DEV Community

Chris Cook
Chris Cook

Posted on

Creating a TypeScript CLI for Your Monorepo

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);
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (4)

Collapse
 
svijaykoushik profile image
Vijay Koushik, S. πŸ‘¨πŸ½β€πŸ’»

I can see myself doing this when build gets complicated. Thanks for the informative post. keep writing

Collapse
 
zirkelc profile image
Chris Cook

I have a built a CLI for building and deploying my Shopify app. It executes multiple CLI commands (vite build, serverless deploy, etc.) via execa.

Maybe I'll make a short follow up post on this :-)

Collapse
 
devmercy profile image
Mercy

This is great @zirkelc, we need more of these.

Collapse
 
zirkelc profile image
Chris Cook

Thanks! :-)