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 , 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.
SOCIAL SHARE CARD GENERATOR