From TypeScript to Terminal: How to Run Your Code Directly
I love TypeScript as a language for building web applications. But a few days ago I wondered if it was possible to run
the code as if it was a shell script. Usually, I just run the code through a build step or a tool like ts-node
. But it
is actually possible to just run your project from the terminal, as if it was a shell script!
In this article, I’m going to show how you can achieve this, using the commit-ai
project (link to the project) as a case study.
Goal: A Seamless CLI Experience
The goal is to be able to run a command like commit-ai
(in my case) from anywhere in your system, and have it execute
your
TypeScript code. This is a common requirement for CLI tools, and it’s actually surprisingly easy to set up!
The Build Step: Compiling to JavaScript
Yes, we need a build step. The first thing to understand is that Node.js doesn’t run TypeScript directly. It runs
JavaScript. So, we need to
compile our TypeScript code to JavaScript before we can run it. I just use the TypeScript compiler tsc
:
In our package.json
, you’ll need a build
script that runs tsc
:
"scripts": {
"build": "tsc"
}
This command will look at our tsconfig.json
file to figure out how to compile the code. A typical setup is to compile
the code in /src
into dist/
tsconfig.json
:
{
"compilerOptions": {
// ...
"outDir": "./dist"
},
"include": [
"src"
],
"exclude": [
"dist",
"node_modules"
]
}
The bin
Field: Creating a Command-Line Alias in package.json
Now that we have our compiled JavaScript, we need to tell Node.js how to run it as a command-line tool. This is where
the bin
field in package.json
comes in handy.
"bin": {
"commit-ai": "dist/index.js"
},
This field tells npm
(or pnpm
, or yarn
) to create a symbolic link from the command commit-ai
to our
compiled dist/index.js
file. When you install this package globally, you’ll be able to run commit-ai
from anywhere
in your terminal.
The Shebang: Making the Script Executable
At the very top of your index.ts
file, you’ll want to add the following line:
#!/usr/bin/env node
This is called a “shebang”. It’s a special line that tells the operating system what interpreter to use to run the
script. In this case, we’re telling it to use the node
interpreter.
When you run the commit-ai
command, the operating system will see the shebang and know to execute the script with
Node.js.
Linking the Package: Making it Global
Now that we have everything set up, the last step is to make our command available system-wide. We can do this with
the pnpm link --global
command (or npm link
if you’re using npm).
This command will create a symbolic link from the global node_modules
directory to our project directory. This means
that you can now run commit-ai
from any directory on your system.
Putting It All Together
So, to recap, here’s the entire process:
- Write your TypeScript code, making sure to include the shebang at the top of your main file.
- Add a
build
script to yourpackage.json
that runstsc
. - Add a
bin
field to yourpackage.json
that points to your compiled JavaScript file. - Run
pnpm install
to install your dependencies. - Run
pnpm build
to compile your TypeScript code to JavaScript. - Run
pnpm link --global
to make your command available system-wide.
And that’s it! You can now run your TypeScript code directly from the terminal. This is a powerful technique that can help you build professional-grade CLI tools with TypeScript.