Need help with cli-cheatsheet?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.
sw-yx

Description

helpful libraries for *building* CLIs. Not a list of CLIs.

495 Stars 19 Forks MIT License 108 Commits 5 Opened issues

Services available

Need anything else?

cli-cheatsheet

helpful libraries and resources for building Node.js CLIs. Not a list of CLIs.

I put together a 90 minute Egghead.io Course and Workshop on how to put these tools together, if you like video learning. I also make some money if you watch those videos if you want to help :)

CLI Design Thinking

Frameworks

  • Commander: Built by TJ, used in
    create-react-app
    ,
    vue-cli
    , and many others. Key feature: pluggability. Vorpal is another framework inspired by Commander and is seeking maintainers
  • Oclif: Built by Heroku, used in Heroku and Salesforce CLI's. Key feature: pluggability.
  • Sade: Built by lukeed, used in tsdx. Key feature: lightweight?
  • Gluegun: Built by Infinite Red, used in Ignite and AWS Amplify. Key feature: templating/filesystem
  • Ink: Built by Vadim & Sindre. Key Feature: React Components and Yoga Layout. See also import-jsx
  • Scritch: Built by Jamie, used at Eventbrite. Key Feature: compose multiple scripts regardless of language into one CLI.
  • Yargs: Built by bcoe, used by
    webpack-cli
    ,
    mocha
    ,
    react-native
    ,
    nyc
    , and 14,343 other modules.
  • arg: Built by Vercel, used by
    vercel
    ,
    ncc
    ,
    micro
    ,
    serve
    , and many others. Key Feature: tiny
  • cac: Built by Egoist, used by
    create-nuxt-app
    and many others.
  • Pastel for React-ink - used in Twilio https://www.twilio.com/blog/building-conference-cli-in-react

New: see CLUI https://blog.repl.it/clui

Inspiration from other languages - the http://charm.sh/ universe.

Utility Libraries

Performance Optimization

For performance logging, you can try

process.htime()
instead of
console.time()
(altho the latter uses the former under the hood)

Update Management/Nagging

  • https://github.com/yeoman/update-notifier#readme

Context/Config

Context from Git/CI

  • https://www.npmjs.com/package/env-ci
  • https://www.npmjs.com/package/git-repo-info
  • http://npm.im/parse-git-config - Parse .git/config into a JavaScript object. sync or async.
  • https://www.npmjs.com/package/parse-gitignore
  • https://www.npmjs.com/package/git-remote-origin-url
  • https://www.npmjs.com/package/parse-github-url
  • https://www.npmjs.com/package/ci-info
  • https://www.npmjs.com/package/is-docker

Context from filesystem/PATH

  • https://github.com/npm/node-which Like running
    which
    : Find the first instance of an executable in the PATH.
  • https://github.com/szwacz/fs-jetpack filesystem access
  • https://github.com/sindresorhus/find-up search up the parents path for where files are located
  • https://www.npmjs.com/package/resolve to simulate Node
    require.resolve
    • https://www.npmjs.com/package/relative generate relative filepaths e.g.
      relative('a/b/c', 'a/d') // ../../d
  • if dealing with yarn workspaces: https://www.npmjs.com/package/find-yarn-workspace-root
  • File watching
    • https://www.npmjs.com/package/cpx (copying with watch functionality)
    • https://www.npmjs.com/package/chokidar (recommended)
    • https://www.npmjs.com/package/sane
    • Sapper Watcher
    • https://www.npmjs.com/package/cheap-watch
    • VSCode's per-platform watchers
  • File finding
    • https://www.npmjs.com/package/glob (dominant)
    • https://www.npmjs.com/package/glob-fs
    • https://www.npmjs.com/package/file-regex
    • https://github.com/pillarjs/path-to-regexp Turn a path string such as /user/:name into a regular expression.
  • Dependency resolution
    • https://www.npmjs.com/package/precinct

Config validation

  • https://github.com/hapijs/joi used by React Native CLI for validation
  • https://www.npmjs.com/package/jest-validate from Jest but not Jest specific

Loading config from json, rc file, etc*

  • https://github.com/DavidWells/configorama
  • https://github.com/davidtheclark/cosmiconfig Find and load configuration from a package.json property, rc file, or CommonJS module. Check
    searchPaths
    to implement XDG spec compliance.
    • replaces https://github.com/dominictarr/rc, an old rc-file finder with some different design choices

don't need but nice to know: https://www.npmjs.com/package/read-package-json

Beware the race condition when you check if file exists and then open it. the file could be deleted in betwee. instead, just open the file and handle the error if it doesnt exist.

Loading/Storing config from a persistent store

⚠️ Be aware of the XDG spec. Sindre's libraries use

env-paths
to get paths compliant with this.

  • https://github.com/sindresorhus/conf simple config storing (maybe try conf-cli to manipulate if needed) the successor to configstore
  • https://github.com/jonschlinkert/data-store conf like datastore but in the shclinkerverse

🌟Input

  • https://npm.im/enquirer (recommended)
    • combine with https://www.npmjs.com/package/fuzzy for fuzzy matching
  • https://npm.im/inquirer
  • https://npm.im/prompts
  • https://npm.im/email-prompt

Stdin Parsing

  • https://npm.im/get-stdin (eg when you want to receive pipe results
    cat mydata.json | mycli
    )

Argument Parsing

  • https://npm.im/meow
  • https://npm.im/arg
  • https://npm.im/minimist (hasn't been updated in a while though)
    • https://www.npmjs.com/package/cliclopts

⚠️ Your framework may come with parsing built in

Input/Stdin/Argument Processing

make sure to also normalize inputted stuff before you compare

  • path.resolve(str1) === path.resolve(str2)
  • https://npm.im/normalize-url
  • https://github.com/sindresorhus/compare-urls

🌟Processing

Command execution

  • https://npm.im/shelljs - xplatform shell command execution
  • https://npm.im/cross-spawn (also a cross platform solution to node's spawn and spawnSync)
  • https://npm.im/execa (recommended)

Remember Windows users for cross-platform nodejs (Guide). e.g. dont execute pkg.json or shell commands with single quotes instead of escaped double quotes

Sometimes processes can spawn processes. This is troublesome for watch/reload features. Kill them all with

tree-kill
.

You'll probably also use these in conjunction with port monitors (e.g. the process you're working with opens a port, like CRA for Netlify Dev):

  • https://github.com/Rich-Harris/port-authority#readme
  • https://github.com/mikeal/getport#readme
  • https://github.com/sindresorhus/get-port#readme

If child_processes are going to be a key part of your CLI, be sure to read the docs and this guide to be aware of the API.

You may also want to poll for conditions to be true to execute async processes:

  • https://www.npmjs.com/package/p-wait-for

Spinners/Loaders

  • https://npm.im/ora (recommended)
  • https://www.npmjs.com/package/cli-ux#cliaction
  • http://npm.im/log-update Log by overwriting the previous output in the terminal. Useful for rendering progress bars, animations, etc.
  • https://www.npmjs.com/package/cli-spinners
  • https://npm.im/listr for progress lists
  • https://www.npmjs.com/package/progress-estimator remembers previous execution times, estimates them next time

Templating

  • https://www.npmjs.com/package/copy-template-dir
  • https://www.npmjs.com/package/consolidate
  • https://www.npmjs.com/package/ejs (Gluegun has this built in)
  • https://www.npmjs.com/package/pupa (sindresorhus' templating)
  • https://www.npmjs.com/package/replace-string (string replace with multiple matches)
  • https://www.npmjs.com/package/cpy (copy files using streams)
  • Mustache and handlebars https://www.npmjs.com/package/handlebars
  • Liquid templating (from Shopify) https://github.com/Shopify/liquid
  • https://github.com/amwmedia/plop: "basically glue code between inquirer prompts and handlebar templates"
  • Angular Schematics https://angular.io/guide/schematics
  • Yeoman generator https://yeoman.io/
    • specifically you can just use the filesystem commands https://yeoman.io/authoring/file-system.html

Temp folders

  • https://www.npmjs.com/package/tempy (create unique temp directories)
  • https://www.npmjs.com/package/tmp (very popular. can remove on exit)

🌟Output

Files

  • ensure directory exists: https://stackoverflow.com/questions/13542667/create-directory-when-writing-to-file-in-node-js
    • simple replacement for
      fs.existsSync(path.resolve/path.join)
      http://npm.im/path-exists
    • also https://www.npmjs.com/package/make-dir
  • encrypt files: https://medium.com/@brandonstilson/lets-encrypt-files-with-node-85037bea8c0e
  • writing large files: https://www.npmjs.com/package/write-file-atomic
  • navigating node_modules using the same package npm uses: https://github.com/npm/arborist/

Icons & Coloring

  • https://npm.im/chalk (recommended - also see Related Packages)
  • https://npm.im/kleur
  • https://npm.im/cfonts
  • https://npm.im/tinycolor2 (some interesting APIs, handy with React Ink)
  • https://npm.im/log-symbols (colored xplatform unicode symbols for success/info/warning/error)
  • https://npm.im/figures (Unicode symbols with Windows CMD fallbacks)
  • https://npm.im/gradient-string VERY nice color gradient text

Note that you may want to offer the option to FORCE_COLOR in CI logging.

PrettyPrinting

  • https://npm.im/pretty-bytes
  • https://www.npmjs.com/package/prettyjson
  • https://www.npmjs.com/package/concordance

there are also react based renderers

  • react ink
  • https://github.com/Yomguithereal/react-blessed

Boxing

  • https://www.npmjs.com/package/term-size Get Terminal Size
  • https://npm.im/boxen
  • https://www.npmjs.com/package/sign-bunny

Tables

  • https://www.npmjs.com/package/cli-table
  • https://www.npmjs.com/package/cli-ux#clitable
  • https://www.npmjs.com/package/ascii-table

Banners

  • https://github.com/patorjk/figlet.js

Debug Logging

  • https://www.npmjs.com/package/debug (note that you might not need this, Node's inbuilt
    util.debuglog
    does a lot of the same h/t @stefanjudis)
  • https://github.com/winstonjs/winston
  • https://github.com/pinojs/pino
  • https://github.com/klaussinani/signale
  • https://github.com/pimterry/loglevel
  • https://github.com/log4js-node/log4js-node
  • https://github.com/nuxt/consola
  • https://github.com/baryon/tracer
  • https://github.com/trentm/node-bunyan
  • React Native CLI has very simple logging with verbose mode you can still with just chalk dependency
  • In Github Issue Templates, tell your users to report versions: https://www.npmjs.com/package/envinfo

You often also find specialized logger tools for each domain, like @dazn/lambda-powertools-logger for AWS Lambda, but at their core they all support the core pattern of Log Levels

DEBUG
,
INFO
,
WARN
and
ERROR
.

Plugin/Release Management

  • https://www.npmjs.com/package/live-plugin-manager
  • https://www.npmjs.com/package/pacote (used in npm cli)
  • https://www.npmjs.com/package/gh-release-fetch (very low level pull from github)
  • https://www.npmjs.com/package/require-package-name (get package names as if local files were modules)
  • https://www.npmjs.com/package/semantic-release

⚠️ None of these are offline-first. Keen on finding one that respects offline first.

Dependency installs and Upgrading Scaffolds

import { spawn, hasYarn } from 'yarn-or-npm'
// optionalDir for installing?
const prefixFlag = hasYarn() ? '--cwd' : '--prefix'
spawn.sync(['install', prefixFlag, optionalDir], { stdio: 'inherit' })

Error Stacks/Error Handling

  • https://github.com/sindresorhus/clean-stack Removes the mostly unhelpful internal Node.js entries.
  • https://github.com/tapjs/stack-utils Captures and cleans stack traces
  • node-cleanup - add a callback for when Node is terminated

Serving Files

  • https://github.com/lukejacksonn/servor zero dependency fileserver focused on SPA usecase
  • https://www.npmjs.com/package/serve general local fileserver utility
  • https://github.com/lukeed/sirv/tree/master/packages/sirv-cli lukeed's alternative to
    serve

Misc

  • https://npm.im/stmux for
    tmux
    like UI
  • https://www.npmjs.com/package/cli-ux general Heroku CLI utils including OS notification
  • https://github.com/jeroenouw/cgx Generate all the recommended files (pre-filled) for the Github community standards. (Issue templates, code of conduct, etc)
  • https://github.com/vercel/pkg packaging as executable (so no requirement for node or npm)
  • https://github.com/kefranabg/readme-md-generator generate READMEs
  • https://github.com/netlify/netlify-dev-plugin/pull/227/files disable clearing of screen like with React-Scripts
  • https://github.com/DanWebb/jdown for parsing a directory of markdown files into json, just wonderful
    • Other Markdown tools
    • gray-matter
    • remark
  • https://www.npmjs.com/package/random-item for randomized selection from a list
  • https://www.npmjs.com/package/uuid UUID for tagging a machine for analytics. see also https://github.com/lukeed/uuid
  • https://www.npmjs.com/package/redact-env redact env var secrets
  • https://github.com/marionebl/svg-term-cli record terminal session as animated svg for docs
  • https://github.com/sinclairzx81/zero for 3d animated scenes in the terminal (idk dont ask)
  • node-cleanup - add a callback for when Node is terminated

New: see CLUI https://blog.repl.it/clui

Other useful lists

  • https://github.com/bcoe/awesome-cross-platform-nodejs

Beginner Tutorials

  • https://www.twilio.com/blog/how-to-build-a-cli-with-node-js

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.