Creating a TypeScript CLI for Your Monorepo
// 9 comments
I like to create local CLIs for my Monorepo to automate tasks like build
and deploy
. These tasks often require more than just chaining a few commands in an npm script (like rimraf dist && tsc
).
Using commander.js and tsx, we can create executable programs written in TypeScript that run from the command line like any other CLI tool.
#!/usr/bin/env -S pnpm tsx import { Command } from 'commander'; const program = new Command() .name('monorepo') .description('CLI for Monorepo') .version('1.0.0'); program .command('build') .description('Build the monorepo') .action(async () => { console.log('Building...'); // run your build steps ... }); program .command('deploy') .description('Deploy the monorepo') .action(async () => { console.log('Deploying...'); // run your deploy steps ... }); await program.parseAsync(process.argv);
Save this script as cli
(or any name you prefer) in your project root and make it executable with chmod +x cli
. You can then run it directly using ./cli
:
$ ./cli Usage: monorepo [options] [command] CLI for Monorepo Options: -V, --version output the version number -h, --help display help for command Commands: build Build the monorepo deploy Deploy the monorepo help [command] display help for command
The magic that allows you to run this without node
, npx
, or even a .ts
extension is in the first line - the shebang:
#!/usr/bin/env -S pnpm tsx
This shebang tells your shell which program should execute this file. Behind the scenes, it translates your ./cli
command into pnpm tsx cli
. This works with other package managers too - you can use npm
or yarn
instead of pnpm
.