Getting Started
Build your own CLI
Section titled “Build your own CLI”Welcome to the start of our journey! If you’ve ever wanted to build a minimal, aesthetically pleasing, and highly functional Command Line Interface (CLI) tool, you are in the right place.
This page provides step-by-step guidance on exactly how we started building the something-cli. We’ll walk you through initialization, installing dependencies, and creating your very first entry file.
-
Initialization: We started by creating a brand new directory for our project. Open your terminal and run:
Terminal window mkdir my-awesome-clicd my-awesome-clinpm init -yYour directory should now look like this:
- package.json
-
Installing Dependencies: To make our CLI powerful and colorful, we installed a few essential tools:
typescript(for type safety),commander(for handling terminal arguments), andchalk(for beautiful colors).Terminal window npm install chalk commandernpm install -D typescript @types/nodeYour directory now includes the
node_modulesfolder and lock file:Directorynode_modules/
- …
- package-lock.json
- package.json
-
Setting up TypeScript: We initialized a
tsconfig.jsonfile to compile our TypeScript code into JavaScript.Terminal window npx tsc --initYour directory tree:
Directorynode_modules/
- …
- package-lock.json
- package.json
- tsconfig.json
-
Creating the Entry File & The Shebang: Next, we created a
srcfolder and anindex.tsfile inside it. At the very top ofsrc/index.ts, we added a “shebang” line:#!/usr/bin/env nodeThis tells your operating system terminal to execute the file using Node.js instead of treating it like a standard bash script.
Your final directory structure for the setup phase:
Directorysrc/
- index.ts
Directorynode_modules/
- …
- package-lock.json
- package.json
- tsconfig.json
-
The Magic
binField: Finally, to tell the operating system that our package contains an executable command, we added thebinfield topackage.json:"bin": {"somethingzz": "./dist/index.js"}What does this do? It maps the command name
somethingzzto the compiled JavaScript file (which will be generated in adistfolder when we build the code). -
Adding Your First Command with Commander: We used the
commanderlibrary to define our very first command:hello. Insidesrc/index.ts, we set up Commander to parse arguments and execute code:import { Command } from 'commander';import chalk from 'chalk';const program = new Command();program.command('hello').description('print hello world').action(() => {// This is where the magic happens!console.log(chalk.hex('#FFC0CB')('hello world!'));});// Don't forget to parse the arguments at the very end of the file!program.parse();How Commander works:
.command('hello')defines the word the user types (e.g.,somethingzz hello)..description(...)adds a helpful description when the user typessomethingzz --help..action(...)defines the function that actually runs when the command is triggered.
-
Linking and Testing: To test the CLI locally without publishing it to npm, we used the
npm linkcommand. This creates a global shortcut on your computer.Terminal window npm run buildnpm linkNow we can test our newly built command! Here is how the output looks in the terminal:
Terminal window somethingzz hello# Output:# hello world! (in beautiful pink color!)
Now that you’ve seen how the foundation was built, check out the Installation & Setup page to see how to run our finished CLI on your own machine!