Using tsm as a shebang interpreter in TypeScript
TypeScript has taken the web development world by storm, becoming increasingly popular for enterprise projects and solo developers alike.
What is tsm?
Should you use tsm?
The primary and most obvious advantage to using tsm is that developers don’t need to worry about TypeScript transpilation. This means that development feedback loops are shorter, build tooling is simpler, and deployment is more straightforward. This is particularly convenient for small projects like one-off scripts.
Because tsm runs on top of Node.js, developers familiar with Node will find using tsm natural and easy to incorporate TypeScript into their projects with a simple step.
For example, esbuild has built-in source map support, which means that TypeScript programs that run under tsm can be debugged with the standard V8 debugging protocol (included with Node.js) and popular debugging tools like VS Code.
Additionally, the vast ecosystem of npm packages and Node built-in APIs are available to TypeScript running with tsm.
The disadvantages to tsm
One relatively small trade-off of using tsm is that it must be installed, in addition to Node.js itself, on the system that needs to run the TypeScript code.
This can be an inconvenience if distributing scripts meant to be run directly from the shell (like when using tsm as the interpreter for a script via shebang interpreter directive), but not a problem for fully packaged Node.js modules.
Other than that, there aren’t too many downsides to giving tsm a try, assuming there’s an appetite for new and emerging (and therefore, potentially changing) tech.
There are a few different ways to hook tsm into a Node.js project.
1. As a replacement for the
Assuming you have tsm installed globally (via
npm --global install tsm or
yarn global add tsm), you can run TypeScript files using the
tsm executable, like so:
For local installations, the
tsm executable can be found at
Note that any command-line flags will be passed through to
node, which is convenient for experimental features, debugging configuration, and the like.
2. With a shebang interpreter directive
Because tsm includes an executable, it can be used in a shebang directive like any other script interpreter. Shebang directives are formatted as such:
They appear at the first line of the file and tell the operating system which program to use to parse and execute the rest of the file.
3. Using the
If you still need to use
node directly rather than the
tsm executable, you can use the
--loader hooks to instruct
node to use
tsm to load TypeScript files. tsm needs to be installed as a local dependency (rather than globally) for this to work.
Deno: An alternative to tsm
tsm isn’t the only way to achieve transpilation-less executable TypeScript. Ryan Dahl, the creator of Node.js, has released a project called Deno that ships with TypeScript support out of the box.
Like Node.js and tsm, Deno can be used directly as an executable:
It can also be used in a shebang directive:
However, code written for Node.js in TypeScript may not be portable to Deno, as Deno provides its own standard library as a replacement for the Node.js APIs. It also has its own paradigm for distributing modules rather than utilizing npm. Check out Deno’s standard library and API docs for more details.
tsm is a great way to integrate TypeScript into a Node.js project quickly and seamlessly. Because it’s built upon Node.js, tsm users can leverage the vast ecosystem of packages in npm and the powerful Node.js APIs, all from within TypeScript without needing to set up a complicated build process.
- create-figma-plugin: a comprehensive toolkit for developing plugins and widgets for Figma and FigJam. It is written in TypeScript and uses tsm for its development process
- tinyhttp: a modern web framework written in TypeScript. It uses tsm in its documentation examples as a simple way to get users up and running quickly
In short, use tsm when you want to leverage Node.js’ vast ecosystem from within TypeScript or integrate TypeScript into an existing Node codebase. If you don’t have many npm-only dependencies and want to enjoy the benefits of Deno’s security model, consider using Deno for your next server-side TypeScript project.