SlideShare une entreprise Scribd logo
1  sur  25
Télécharger pour lire hors ligne
Making CLIs with Node.js
🏆 Terminals FTW 🏆
Joe Lust mabl engineer @lustcoder
About Me: Joseph Lust
Engineer
■ Building the web for two decades
▲ PHP, Node, Scala, Java, Typescript
■ Currently building mabl testing cloud on GCP
■ Co-organizer GDG Cloud Boston Meetup
@lustcoder
Command
Line
Interface
Why do you need a CLI? Do you?
■ Easily automate processes
▲ Common developer actions
▲ Helpful SDK wrapper
■ Harness client side power
▲ File system access
▲ Complex non-browser use cases
4
CLI tie breakers
■ Very simple UIs
▲ No pixels to polish (e.g. React + Redux)
▲ Allows rapid feature delivery
■ Easily combine with workflows
▲ Chain bash/CLI tools together (stdin → stdout, exit codes)
▲ Users can create novel combinations
■ No Hosting, No Deployments
▲ Runs on customer hardware, no-ops!
5
Your technology options
■ Node.js + NPM
▲ Ubiquitous NPM install base
▲ Pervasive CLI tooling
▲ One line installs
■ Alternatives
▲ Python + PIP
▲ Go binaries
▲ Ruby
6
Let’s get cooking and
Make a CLI !
Let’s get cooking and
Make a CLI !
You only need one file
■ NPM is a CLI, afterall!
■ Just tell NPM what to run
▲ the CLI name (e.g. “boston-node”)
▲ the JS file to launch (e.g. cli.js)
9
# package.json
...
"bin": {
"bode": "./cli.js"
},
...
# package.json
...
"bin": {
"boston-node": "./cli.js"
},
...
Hold on, there’s more
You can alias too
■ Everything in bin winds up on the PATH
■ Add helpful aliases as well
■ Shorter is better (life is short)
▲ boston-node → bode
11
# package.json
...
"bin": {
"bode": "./cli.js",
"boston-node": "./cli.js"
},
...
ProTip™ developers hate typing. Keep it short.
Just link it
■ You can try out your CLI by linking
▲ npm link
■ Don’t forget to cleanup
▲ npm unlink
12
Inspiration: Beg, Barrow, & Attribute
■ Pick your favorite CLI
▲ Investigate it’s NPM listing: dependencies
▲ Read the source code
▲ Look in the package
● How’d they do that? 🤔
13
$ URL=$(npm view jest-cli@latest dist.tarball)
$ wget $URL -O - | tar xvz
Putting the “I” in CLI: the Interface
■ Design your interface
▲ Ergonomic layout
▲ Easily guessed/remember
▲ Plain English flags
14
$ <cli-name> <noun> <verb> <subject> --flag <value>
$ aws s3 ls s3://bucket --recursive
Flag valuePositional ArgNested Commands
Putting the “I” in CLI: the Interface
■ Don’t reinvent the wheel
■ Use argument parser libs
▲ commander (39k)
▲ yargs (17k)
● nested command directories
● autocomplete generator
15
Putting the “I” in CLI: the Interface
■ Don’t reinvent the wheel
■ Use argument parser libs
▲ commander (39k)
▲ yargs (17k)
● nested command directories
● autocomplete generator
16
Hang on to that State
■ Don’t reinvent the wheel
■ There are libs for that!
▲ conf
▲ persist rich configs in user HOME
▲ update your config schema (migrations)
▲ supports secret encryption/keyrings
17
CLIs can be Sexy
■ Spinners - ora
■ Rich forms - inquirer
■ Pretty text - chalk
■ Banners - figlet
■ Tables - cli-table3
■ Progress bar- progress
18
Say NO to Banal CLIs
19
Sorry PDF viewers, these are animated!
Be bashful
■ What would Stephen (Bourne) Do? (WWBD)
▲ Be recombinable
▲ Use Standard In (stdin), Out (stdout), and Error (stderr)
▲ Return error codes when trouble happens
● process.exit(0); // all is well
20
$ curl http://no-such-place.no-way
$ echo “Error code: [$?]”
> Error Code [6]
Log All the Things!
■ Enable a --verbose mode for debugging/power users
■ Logging libs to the rescue
▲ winston, bunyun, pino, morgan (http)
▲ control log.debug() output
■ Save detailed logs to a file for debugging/support
▲ ~/.npm/node_modules/my-cli/logs/aw-snap.log
■ Simplifies testing
▲ Don’t use console.log()
21
Keep Everyone Up to Date
■ Don’t reinvent updates/notifications
■ Use what npm uses
▲ update-notifier
▲ automatically checks NPM registry for updates
▲ just set the nagging interval
22
Don’t forget the tests!
■ Easy to test, just call your yargs parser!
■ Bash script for sanity checks
■ Users will install your CLI on multiple OSes
▲ Use GitHub Workflows to test Win/OSX/Linux
23
Be bashful
24
// Simple Parser Test
describe('application commands', () => {
it('applications describe requires app id', async () => {
const cmd = 'describe';
const parser: Argv<CrudCommand> = yargs.command(myCommand);
const [,out]= await parseArguments<CrudCommand>(parser, cmd);
expect(out).to.contain(
'Not enough arguments: got 0, need at least 1',
);
});
});
Making CLIs with Node.js

Contenu connexe

Tendances

Integrating Node.js with PHP
Integrating Node.js with PHPIntegrating Node.js with PHP
Integrating Node.js with PHP
Lee Boynton
 
NodeJs Intro - JavaScript Zagreb Meetup #1
NodeJs Intro - JavaScript Zagreb Meetup #1NodeJs Intro - JavaScript Zagreb Meetup #1
NodeJs Intro - JavaScript Zagreb Meetup #1
Tomislav Capan
 
Django deployment and rpm+yum
Django deployment and rpm+yumDjango deployment and rpm+yum
Django deployment and rpm+yum
Walter Liu
 
Modern Perl desktop apps - Cluj.pm March 2014
Modern Perl desktop apps - Cluj.pm March 2014Modern Perl desktop apps - Cluj.pm March 2014
Modern Perl desktop apps - Cluj.pm March 2014
Arpad Szasz
 

Tendances (20)

How we do python
How we do pythonHow we do python
How we do python
 
What the HACK is HHVM?
What the HACK is HHVM?What the HACK is HHVM?
What the HACK is HHVM?
 
PHP and node.js Together
PHP and node.js TogetherPHP and node.js Together
PHP and node.js Together
 
KAK Etkinliği OJS de Symfony kullanımı
KAK Etkinliği OJS de Symfony kullanımıKAK Etkinliği OJS de Symfony kullanımı
KAK Etkinliği OJS de Symfony kullanımı
 
Integrating Node.js with PHP
Integrating Node.js with PHPIntegrating Node.js with PHP
Integrating Node.js with PHP
 
Node.js
Node.jsNode.js
Node.js
 
Composer
ComposerComposer
Composer
 
WebAssemlby vs JavaScript
WebAssemlby vs JavaScriptWebAssemlby vs JavaScript
WebAssemlby vs JavaScript
 
CRaSH the shell for the JVM
CRaSH the shell for the JVMCRaSH the shell for the JVM
CRaSH the shell for the JVM
 
Voxxed Days Thessaloniki 2016 - Web assembly : the browser vm we were waiting...
Voxxed Days Thessaloniki 2016 - Web assembly : the browser vm we were waiting...Voxxed Days Thessaloniki 2016 - Web assembly : the browser vm we were waiting...
Voxxed Days Thessaloniki 2016 - Web assembly : the browser vm we were waiting...
 
NodeJs Intro - JavaScript Zagreb Meetup #1
NodeJs Intro - JavaScript Zagreb Meetup #1NodeJs Intro - JavaScript Zagreb Meetup #1
NodeJs Intro - JavaScript Zagreb Meetup #1
 
Full stack java script development
Full stack java script developmentFull stack java script development
Full stack java script development
 
Modern Development Tools
Modern Development ToolsModern Development Tools
Modern Development Tools
 
Symfony ile Gelişmiş API Mimarisi
Symfony ile Gelişmiş API MimarisiSymfony ile Gelişmiş API Mimarisi
Symfony ile Gelişmiş API Mimarisi
 
Nim programming language - DevFest Berlin 2019
Nim programming language -  DevFest Berlin 2019Nim programming language -  DevFest Berlin 2019
Nim programming language - DevFest Berlin 2019
 
Using the Command Line: Bash and WP-CLI
Using the Command Line: Bash and WP-CLIUsing the Command Line: Bash and WP-CLI
Using the Command Line: Bash and WP-CLI
 
Why and what is go
Why and what is goWhy and what is go
Why and what is go
 
Django deployment and rpm+yum
Django deployment and rpm+yumDjango deployment and rpm+yum
Django deployment and rpm+yum
 
Dev/Stage/Prod Parity with Vagrant
Dev/Stage/Prod Parity with VagrantDev/Stage/Prod Parity with Vagrant
Dev/Stage/Prod Parity with Vagrant
 
Modern Perl desktop apps - Cluj.pm March 2014
Modern Perl desktop apps - Cluj.pm March 2014Modern Perl desktop apps - Cluj.pm March 2014
Modern Perl desktop apps - Cluj.pm March 2014
 

Similaire à Making CLIs with Node.js

Exploring Raspberry Pi
Exploring Raspberry PiExploring Raspberry Pi
Exploring Raspberry Pi
Lentin Joseph
 
Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Lightweight Virtualization with Linux Containers and Docker I YaC 2013Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Docker, Inc.
 
TIP1 - Overview of C/C++ Debugging/Tracing/Profiling Tools
TIP1 - Overview of C/C++ Debugging/Tracing/Profiling ToolsTIP1 - Overview of C/C++ Debugging/Tracing/Profiling Tools
TIP1 - Overview of C/C++ Debugging/Tracing/Profiling Tools
Xiaozhe Wang
 
Android Variants, Hacks, Tricks and Resources presented at AnDevConII
Android Variants, Hacks, Tricks and Resources presented at AnDevConIIAndroid Variants, Hacks, Tricks and Resources presented at AnDevConII
Android Variants, Hacks, Tricks and Resources presented at AnDevConII
Opersys inc.
 

Similaire à Making CLIs with Node.js (20)

AOT-compilation of JavaScript with V8
AOT-compilation of JavaScript with V8AOT-compilation of JavaScript with V8
AOT-compilation of JavaScript with V8
 
Fuzzing softwares for bugs - OWASP Seasides
Fuzzing softwares for bugs - OWASP SeasidesFuzzing softwares for bugs - OWASP Seasides
Fuzzing softwares for bugs - OWASP Seasides
 
Serverless Preview Environments @ Boston DevOps
Serverless Preview Environments @ Boston DevOpsServerless Preview Environments @ Boston DevOps
Serverless Preview Environments @ Boston DevOps
 
BKK16-302: Android Optimizing Compiler: New Member Assimilation Guide
BKK16-302: Android Optimizing Compiler: New Member Assimilation GuideBKK16-302: Android Optimizing Compiler: New Member Assimilation Guide
BKK16-302: Android Optimizing Compiler: New Member Assimilation Guide
 
Exploring Raspberry Pi
Exploring Raspberry PiExploring Raspberry Pi
Exploring Raspberry Pi
 
Development tools at Base
Development tools at BaseDevelopment tools at Base
Development tools at Base
 
LCU14 201- Binary Analysis Tools
LCU14 201- Binary Analysis ToolsLCU14 201- Binary Analysis Tools
LCU14 201- Binary Analysis Tools
 
Webinar - Unbox GitLab CI/CD
Webinar - Unbox GitLab CI/CD Webinar - Unbox GitLab CI/CD
Webinar - Unbox GitLab CI/CD
 
BUD17-310: Introducing LLDB for linux on Arm and AArch64
BUD17-310: Introducing LLDB for linux on Arm and AArch64 BUD17-310: Introducing LLDB for linux on Arm and AArch64
BUD17-310: Introducing LLDB for linux on Arm and AArch64
 
Metasepi team meeting #8': Haskell apps on Android NDK
Metasepi team meeting #8': Haskell apps on Android NDKMetasepi team meeting #8': Haskell apps on Android NDK
Metasepi team meeting #8': Haskell apps on Android NDK
 
Lightweight Virtualization with Linux Containers and Docker | YaC 2013
Lightweight Virtualization with Linux Containers and Docker | YaC 2013Lightweight Virtualization with Linux Containers and Docker | YaC 2013
Lightweight Virtualization with Linux Containers and Docker | YaC 2013
 
Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Lightweight Virtualization with Linux Containers and Docker I YaC 2013Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Lightweight Virtualization with Linux Containers and Docker I YaC 2013
 
HTML, CSS & Javascript Architecture (extended version) - Jan Kraus
HTML, CSS & Javascript Architecture (extended version) - Jan KrausHTML, CSS & Javascript Architecture (extended version) - Jan Kraus
HTML, CSS & Javascript Architecture (extended version) - Jan Kraus
 
groovy & grails - lecture 6
groovy & grails - lecture 6groovy & grails - lecture 6
groovy & grails - lecture 6
 
Introduction of unit test on android kernel
Introduction of unit test on android kernelIntroduction of unit test on android kernel
Introduction of unit test on android kernel
 
"Lightweight Virtualization with Linux Containers and Docker". Jerome Petazzo...
"Lightweight Virtualization with Linux Containers and Docker". Jerome Petazzo..."Lightweight Virtualization with Linux Containers and Docker". Jerome Petazzo...
"Lightweight Virtualization with Linux Containers and Docker". Jerome Petazzo...
 
TIP1 - Overview of C/C++ Debugging/Tracing/Profiling Tools
TIP1 - Overview of C/C++ Debugging/Tracing/Profiling ToolsTIP1 - Overview of C/C++ Debugging/Tracing/Profiling Tools
TIP1 - Overview of C/C++ Debugging/Tracing/Profiling Tools
 
Android Variants, Hacks, Tricks and Resources presented at AnDevConII
Android Variants, Hacks, Tricks and Resources presented at AnDevConIIAndroid Variants, Hacks, Tricks and Resources presented at AnDevConII
Android Variants, Hacks, Tricks and Resources presented at AnDevConII
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
Serverless preview environments to the rescue
Serverless preview environments to the rescueServerless preview environments to the rescue
Serverless preview environments to the rescue
 

Plus de Joseph Lust

Plus de Joseph Lust (8)

GitLab Commit 2020: Ubiquitous quality through continuous testing pipelines
GitLab Commit 2020: Ubiquitous quality through continuous testing pipelinesGitLab Commit 2020: Ubiquitous quality through continuous testing pipelines
GitLab Commit 2020: Ubiquitous quality through continuous testing pipelines
 
Serverless Apps on Google Cloud: more dev, less ops
Serverless Apps on Google Cloud:  more dev, less opsServerless Apps on Google Cloud:  more dev, less ops
Serverless Apps on Google Cloud: more dev, less ops
 
mabl's Machine Learning Implementation on Google Cloud Platform
mabl's Machine Learning Implementation on Google Cloud Platformmabl's Machine Learning Implementation on Google Cloud Platform
mabl's Machine Learning Implementation on Google Cloud Platform
 
Going Microserverless on Google Cloud @ mabl
Going Microserverless on Google Cloud @ mablGoing Microserverless on Google Cloud @ mabl
Going Microserverless on Google Cloud @ mabl
 
Going Microserverless on Google Cloud
Going Microserverless on Google CloudGoing Microserverless on Google Cloud
Going Microserverless on Google Cloud
 
Kubernetes & Google Container Engine @ mabl
Kubernetes & Google Container Engine @ mablKubernetes & Google Container Engine @ mabl
Kubernetes & Google Container Engine @ mabl
 
Embracing Serverless with Google
Embracing Serverless with GoogleEmbracing Serverless with Google
Embracing Serverless with Google
 
Firebase Cloud Functions: a quick overview
Firebase Cloud Functions: a quick overviewFirebase Cloud Functions: a quick overview
Firebase Cloud Functions: a quick overview
 

Dernier

Integrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - NeometrixIntegrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - Neometrix
Neometrix_Engineering_Pvt_Ltd
 
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills KuwaitKuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
jaanualu31
 
Verification of thevenin's theorem for BEEE Lab (1).pptx
Verification of thevenin's theorem for BEEE Lab (1).pptxVerification of thevenin's theorem for BEEE Lab (1).pptx
Verification of thevenin's theorem for BEEE Lab (1).pptx
chumtiyababu
 
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments""Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
mphochane1998
 

Dernier (20)

Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS Lambda
 
Wadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptxWadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptx
 
PE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and propertiesPE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and properties
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - V
 
Integrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - NeometrixIntegrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - Neometrix
 
Computer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to ComputersComputer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to Computers
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
 
Unleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leapUnleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leap
 
Online food ordering system project report.pdf
Online food ordering system project report.pdfOnline food ordering system project report.pdf
Online food ordering system project report.pdf
 
Moment Distribution Method For Btech Civil
Moment Distribution Method For Btech CivilMoment Distribution Method For Btech Civil
Moment Distribution Method For Btech Civil
 
DC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationDC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equation
 
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills KuwaitKuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
 
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPT
 
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptxOrlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
 
Verification of thevenin's theorem for BEEE Lab (1).pptx
Verification of thevenin's theorem for BEEE Lab (1).pptxVerification of thevenin's theorem for BEEE Lab (1).pptx
Verification of thevenin's theorem for BEEE Lab (1).pptx
 
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments""Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
 
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
 

Making CLIs with Node.js

  • 1. Making CLIs with Node.js 🏆 Terminals FTW 🏆 Joe Lust mabl engineer @lustcoder
  • 2. About Me: Joseph Lust Engineer ■ Building the web for two decades ▲ PHP, Node, Scala, Java, Typescript ■ Currently building mabl testing cloud on GCP ■ Co-organizer GDG Cloud Boston Meetup @lustcoder
  • 4. Why do you need a CLI? Do you? ■ Easily automate processes ▲ Common developer actions ▲ Helpful SDK wrapper ■ Harness client side power ▲ File system access ▲ Complex non-browser use cases 4
  • 5. CLI tie breakers ■ Very simple UIs ▲ No pixels to polish (e.g. React + Redux) ▲ Allows rapid feature delivery ■ Easily combine with workflows ▲ Chain bash/CLI tools together (stdin → stdout, exit codes) ▲ Users can create novel combinations ■ No Hosting, No Deployments ▲ Runs on customer hardware, no-ops! 5
  • 6. Your technology options ■ Node.js + NPM ▲ Ubiquitous NPM install base ▲ Pervasive CLI tooling ▲ One line installs ■ Alternatives ▲ Python + PIP ▲ Go binaries ▲ Ruby 6
  • 7. Let’s get cooking and Make a CLI !
  • 8. Let’s get cooking and Make a CLI !
  • 9. You only need one file ■ NPM is a CLI, afterall! ■ Just tell NPM what to run ▲ the CLI name (e.g. “boston-node”) ▲ the JS file to launch (e.g. cli.js) 9 # package.json ... "bin": { "bode": "./cli.js" }, ... # package.json ... "bin": { "boston-node": "./cli.js" }, ...
  • 11. You can alias too ■ Everything in bin winds up on the PATH ■ Add helpful aliases as well ■ Shorter is better (life is short) ▲ boston-node → bode 11 # package.json ... "bin": { "bode": "./cli.js", "boston-node": "./cli.js" }, ... ProTip™ developers hate typing. Keep it short.
  • 12. Just link it ■ You can try out your CLI by linking ▲ npm link ■ Don’t forget to cleanup ▲ npm unlink 12
  • 13. Inspiration: Beg, Barrow, & Attribute ■ Pick your favorite CLI ▲ Investigate it’s NPM listing: dependencies ▲ Read the source code ▲ Look in the package ● How’d they do that? 🤔 13 $ URL=$(npm view jest-cli@latest dist.tarball) $ wget $URL -O - | tar xvz
  • 14. Putting the “I” in CLI: the Interface ■ Design your interface ▲ Ergonomic layout ▲ Easily guessed/remember ▲ Plain English flags 14 $ <cli-name> <noun> <verb> <subject> --flag <value> $ aws s3 ls s3://bucket --recursive Flag valuePositional ArgNested Commands
  • 15. Putting the “I” in CLI: the Interface ■ Don’t reinvent the wheel ■ Use argument parser libs ▲ commander (39k) ▲ yargs (17k) ● nested command directories ● autocomplete generator 15
  • 16. Putting the “I” in CLI: the Interface ■ Don’t reinvent the wheel ■ Use argument parser libs ▲ commander (39k) ▲ yargs (17k) ● nested command directories ● autocomplete generator 16
  • 17. Hang on to that State ■ Don’t reinvent the wheel ■ There are libs for that! ▲ conf ▲ persist rich configs in user HOME ▲ update your config schema (migrations) ▲ supports secret encryption/keyrings 17
  • 18. CLIs can be Sexy ■ Spinners - ora ■ Rich forms - inquirer ■ Pretty text - chalk ■ Banners - figlet ■ Tables - cli-table3 ■ Progress bar- progress 18
  • 19. Say NO to Banal CLIs 19 Sorry PDF viewers, these are animated!
  • 20. Be bashful ■ What would Stephen (Bourne) Do? (WWBD) ▲ Be recombinable ▲ Use Standard In (stdin), Out (stdout), and Error (stderr) ▲ Return error codes when trouble happens ● process.exit(0); // all is well 20 $ curl http://no-such-place.no-way $ echo “Error code: [$?]” > Error Code [6]
  • 21. Log All the Things! ■ Enable a --verbose mode for debugging/power users ■ Logging libs to the rescue ▲ winston, bunyun, pino, morgan (http) ▲ control log.debug() output ■ Save detailed logs to a file for debugging/support ▲ ~/.npm/node_modules/my-cli/logs/aw-snap.log ■ Simplifies testing ▲ Don’t use console.log() 21
  • 22. Keep Everyone Up to Date ■ Don’t reinvent updates/notifications ■ Use what npm uses ▲ update-notifier ▲ automatically checks NPM registry for updates ▲ just set the nagging interval 22
  • 23. Don’t forget the tests! ■ Easy to test, just call your yargs parser! ■ Bash script for sanity checks ■ Users will install your CLI on multiple OSes ▲ Use GitHub Workflows to test Win/OSX/Linux 23
  • 24. Be bashful 24 // Simple Parser Test describe('application commands', () => { it('applications describe requires app id', async () => { const cmd = 'describe'; const parser: Argv<CrudCommand> = yargs.command(myCommand); const [,out]= await parseArguments<CrudCommand>(parser, cmd); expect(out).to.contain( 'Not enough arguments: got 0, need at least 1', ); }); });