This site runs best with JavaScript enabled.

Notes from Build Custom CLI Tooling with oclif and TypeScript course

Tomasz Łakomy

August 24, 2020

Build Custom CLI Tooling with oclif and TypeScript

You can check out the course here: Build Custom CLI Tooling with oclif and TypeScript

Oclif can be used to easily create CLI tools

Two types of commands:

  • single command
  • multi command

In order to test CLIs locally you can quickly create a yarn workspace to call e.g. yarn mycli init

You can use a VSCode debugger with node --inspect-brk ./bin/run init. You can also use watch expressions in VSCode.

Oclif supports debugging by default: e.g. DEBUG=* mycommand / DEBUG=mycli yarn mycli. Add debug module in order to get a better debugging experience (it's basically a better console.log)

Enquirer package allows us to ask all kinds of questions to our users via CLI prompts (even surveys!)

Cosmiconfig is an easy way to enable package.json/mycli.rc and other ways of providing configuration to your cli:

By default, Cosmiconfig will start where you tell it to start and search up the directory tree for the following:

  • a package.json property
  • a JSON or YAML, extensionless "rc file"
  • an "rc file" with the extensions .json, .yaml, .yml, .js, or .cjs
  • a .config.js or .config.cjs CommonJS module

copy-template-dir can be used to scaffold projects from templates. Just create a template directory and copy it over like this:

const vars = { projectName: name };
const inDir = path.resolve(__dirname, '../templates/template-jquery');
const outDir = path.join(process.cwd(), name);
copy(inDir, outDir, vars, (err: Error, createdFiles: String[]) => {
if (err) throw err;
createdFiles.forEach(filePath => console.log(`Created ${filePath}`));

"name": "{{projectName}}", - we can also use {{}} in order to inject strings into the templates

execa can be used to execute child processes:

This package improves `child_process` methods with:
Promise interface.
Strips the final newline from the output so you don't have to do stdout.trim().
Supports shebang binaries cross-platform.
Improved Windows support.
Higher max buffer. 100 MB instead of 200 KB.
Executes locally installed binaries by name.
Cleans up spawned processes when the parent process dies.
Get interleaved output from stdout and stderr similar to what is printed on the terminal. (Async only)
Can specify file and arguments as a single string without a shell
More descriptive errors.
Share articleBuy Me A Beer

Join the Newsletter

Tomasz Łakomy © 2020