Node.js can run TypeScript
This is a fairly quick post, but it's impactful if you use Node.js.
Node.js can now just run TypeScript locally, without needing tsx
or a build step.
How
Node v22 has added an experimental flag, --experimental-transform-types
.
This supercedes a previous strip
flag, because it supports code-based TypeScript features like enum
.
(Maybe there's some features still missing, but it's "good enough" for now.)
To run a TypeScript file, you can now:
$ node --experimental-transform-types file.ts
Just like that. 🤯
Configure Your Shell
Instead of passing the flag around everywhere, you can configure your environment to always do it. Inside your ".bashrc", ".zshrc", or whatever, add:
export NODE_OPTIONS="--experimental-transform-types --disable-warning=ExperimentalWarning"
This means that every invocation of Node will transform TypeScript files, and it'll muffle the egregious warning that was being dumped in your terminal.
Configure Your Projects
This is tricky. If you write a "package.json" file with scripts, you can't assume all users might have these flags configured.
You can add to scripts
:
{
"name": "yourproject",
"scripts": {
"test": "NODE_OPTIONS='--experimental-transform-types --disable-warning=ExperimentalWarning' node --test **/*test.ts",
}
}
This is a bit gross, but means that anyone with a sufficiently high version of Node will get the feature.
Note that the above sample also uses Node.js' built-in test runner, which is also one of the greatest things since sliced bread. 🔪🍞
Promotion
At some point, this flag will probably be enabled by default. Will it be in Node 23, or 24? Who knows. Watch this space.
Module Benefits
While subtle, the other huge benefit of built-in TypeScript support is that code like this now works:
import { Worker } from 'node:worker_threads';
const x = new Worker('./other-module.ts');
const other = await import('./other.ts');
i.e., you can import dependant code even if it's written in TypeScript.
This is one of those things that should never have been hard, and now it's just solved—it was previously difficult to both transpile and for a tool like tsx
to handle.
Fin
Short post! Enjoy. 💞