Back to Tsx

Native TypeScript type stripping

notes/node/type-stripping.md

4.23.96.2 KB
Original Source

Native TypeScript type stripping

Node's built-in TypeScript execution pipeline and its runtime limits.

Timeline

ChangePR or issueVerified releases
--experimental-strip-typesnodejs/node#53725v22.6.0, v23.0.0
--experimental-transform-typesnodejs/node#54283v22.7.0, v23.0.0
module.stripTypeScriptTypes()#55282, nodejs/node#54300v22.13.0, v23.2.0
TypeScript in --eval and STDIN#56359v22.14.0, v23.6.0, v24.0.0
Default strip-only execution#56350, nodejs/typescript#17v22.18.0, v23.6.0, v24.0.0
Stable status#60600v24.12.0, v25.2.0
Remove transform mode#61803v26.0.0

Runtime pipeline

Public API and loader path

node:module exposes stripTypeScriptTypes(), but it differs from the loader path.

AspectPublic APIInternal loader
node_modulesNo path restriction (v24.15.0 typescript.js#L102-L127)Throws ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING (v24.15.0 typescript.js#L180-L183)
Compile cacheNot used (public path)Keyed by filename (v24.15.0 typescript.js#L198)
Transform modePublic mode: "transform" available through v25 (v25 API); removed in v26 (v26 API)Loader mode followed the runtime flag through v25 (v25 loader); transform mode was removed in v26 (release)

Position preservation

Strip mode replaces erasable syntax with whitespace, preserving source length and line/column offsets; sourceUrl appends a sourceURL comment, while sourceMap: true is invalid in strip mode (v24 tests, v26 tests). Direct loader execution therefore reports original locations without generated source maps (stack test).

The public helper permits caught fallback and accepts an arbitrary sourceUrl; the internal loader strips only after format selection and cannot return to an earlier user hook when syntax is unsupported (ESM translator, CJS loader).

Runtime limits

  • Node ignores tsconfig.json; paths and downleveling are unsupported (v26.0.0 typescript.md#L80-L88).
  • Relative TypeScript imports require explicit extensions (v26.0.0 typescript.md#L128-L136).
  • .tsx, non-erasable syntax, and TypeScript in node_modules remain unsupported (v26.0.0 typescript.md#L128-L217).
  • Import aliases such as import Alias = Namespace.Member require JavaScript generation and fail strip-only execution with ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX (v26.5.1 typescript.md#L140-L162).
  • TypeScript data URLs remain unsupported because the data-protocol handler maps its MIME type through a table that recognizes JavaScript, JSON, and WebAssembly but not TypeScript (v26.0.0 handler, MIME table).
  • As of v26.5.1, the CJS extension hook selects TypeScript formats only for .mts, .cts, and .ts; extensionless entrypoints receive JavaScript package formats instead (loader).