Skip to content

Instantly share code, notes, and snippets.

@paulirish
Last active November 23, 2025 15:48
Show Gist options
  • Select an option

  • Save paulirish/18f417604b5d875b88ad303b104742b7 to your computer and use it in GitHub Desktop.

Select an option

Save paulirish/18f417604b5d875b88ad303b104742b7 to your computer and use it in GitHub Desktop.
Quick guide to native TS in Node.js

To do TS in node natively (no compiling needed) there are a few considerations:

  1. tsconfig.json
  2. package.json
  3. import statements
  4. node version

tsconfig.json

Copy the file down below. But here's an annotated version of the compilerOptions

    "target": "esnext",
    "module": "nodenext",
    "erasableSyntaxOnly": true, /* Prevents using unsupported TypeScript features. */
    "verbatimModuleSyntax": true, /* Enforces explicit type imports: https://nodejs.org/api/typescript.html#importing-types-without-type-keyword */
    "allowImportingTsExtensions": true, /* Allows 'import x from "./file.ts"' */
    "rewriteRelativeImportExtensions": true, /* Handle the import adjustment if compiling to JS */

    "noEmit": true, /* In most cases, no emit. But set to `false` if still distributing the JS. */

package.json

In the package.json you almost certainly want:

   "type": "module",

Without that you'll likely need filenames as .mts or .cts

import statements

Explicit .ts extensions are now required in import statements:

import { dopeFn } from './hotness.ts';

and explicit type imports are required:

import type { BucketList, Occupation } from './person.ts';

Okay now run it 🟢

Use node v24.11.0+ for the best experience.

node script.ts

You can manaully typecheck with:

tsc

Node versions

  • v24.11.0: No more ExperimentalWarning: Type Stripping is an experimental feature and might change at any time warning.
  • v22.18.0: the default is strip-types.
  • v22.7.0+: --experimental-transform-types available. (also enables --experimental-strip-types implicitly)
  • v22.6.0+: --experimental-strip-types available.

So, the --experimental-strip-types is only needed if v22.6.0 < your node version < v22.18.0

And --experimental-transform-type is a thing but.. excluded from this lil guide.

Warning text

image

This'll happen up through node v24.2.0. Easiest solution is upgrade to latest v24+ (as its gone there). If you can't upgrade, set export NODE_OPTIONS="--disable-warning=ExperimentalWarning", or alternatively, you can use a flag: node --disable-warning=ExperimentalWarning.

See also

All of this had been documented before, but I wanted a clearer one-stop shop for it. :)

Shout out to Marco Ippolito who made this feature happen in Node. And the TS folks who added erasableSyntaxOnly etc!

{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true,
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": true,
"noEmit": true,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment