Creating a CLI with TypeScript
February 17, 2019
Photo by Anders Jildén
Recently, I shared typed-scss-modules, a command-line interface (CLI) for generating type definitions for CSS Modules using SASS. I’ve used many npm packages that provide executable commands, such as tsc
from TypeScript, or apollo
for Apollo GraphQL tooling, but have never created a package with an executable.
Considering typed-scss-modules
is a tool for generating TypeScript type definitions, it seemed fit to also be written in TypeScript. But where to start?
📦 Getting Started
After searching around and also digging through various packages that offered executables the packages below were the most helpful when creating a TypeScript command-line npm package.
Core Tooling
Some of this tooling is specific to TypeScript, but the majority of this is useful for any npm package that includes an executable for doing things like creating the CLI options or printing formatted output.
-
ts-node
: TypeScript Node is used to execute TypeScript. This is useful in development to run the CLI without needing to build anything. Adding a custom script topackage.json
with the same name will enable executing the script the similarily during development and in the published version. For example, adding"my-script": "ts-node ./lib/cli.ts"
to thepackage.json
scripts
property will running it withyarn my-script
ornpm run my-script
. -
yargs
: Yargs helps build interactive command line tools, by parsing arguments and generating a user interface. There are also other packages like commander.js that can be used for this as well. On an unrelated note, the type definitions for yargs (@types/yargs
) are impressive. They allow chaining methods that build up a final object with all of the CLI options with the proper types. -
chalk
: Chalk provides terminal string styling to display messages in different ways depending on the context. The gif below is an example of usingtyped-scss-modules
and the output, which is styled usingchalk
. If looking to create a more complex CLI, consider giving ink a try. It also may be a better fit fortyped-scss-modules
to show the total number of type definitions generated, rather than a full list of every file which could get lengthy in larger projects.