Skip to the solution
MediumBackend7 min read

How do you run TypeScript directly in Node.js (native type stripping, tsx, ts-node)?

529 views

The problem

Question presented to candidate: "A teammate says you don't even need ts-node or tsx anymore to run a .ts file with Node directly. Is that actually true for ANY TypeScript file, or are there real limits to what Node can run without a full transpiler?"

What a strong answer should cover:

  • Modern Node (type stripping unflagged-by-default starting around Node 23.6+/24) can run a .ts file directly, with zero flags and zero installed packages, for files using only type annotations that can be simply erased β€” interfaces, type annotations on variables/parameters/returns, generics β€” none of which produce any runtime code at all, so removing them is sufficient.
  • πŸ“Œ Verified, not assumed β€” confirming the teammate's claim, for THIS category: a real .ts file with function parameter/return types and a real interface genuinely ran correctly with plain node file.ts, no flag, no --experimental-strip-types, no transpiler installed at all.
  • πŸ“Œ Verified, not assumed β€” the real, precise limit the teammate's claim glosses over: a real TypeScript enum β€” a construct that requires actual code generation, not mere erasure, since an enum produces real runtime values/objects β€” genuinely failed running the identical way, with a real, specific error: SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode.
  • πŸ“Œ Interview term: type stripping (what Node does) vs. transpilation (what tsx/ts-node do): stripping only ever removes type syntax, never transforms it β€” this is precisely why erasable syntax (types, interfaces) works natively, verified above, while syntax requiring genuine transformation (enums, namespaces, legacy import = syntax, and other non-erasable TS features) genuinely does not, also verified above with a real, specific error naming exactly this distinction ("not supported in strip-only mode").
  • The precise, honest scope for the interview: tsx/ts-node remain genuinely necessary for any codebase using non-erasable TypeScript features (enums verified above being the most common), or that needs other transpiler-provided capabilities (path-mapping resolution, decorators depending on configuration, targeting an older Node/JS version) β€” native stripping is a real, meaningful reduction in tooling need for a large, common subset of TypeScript, not a full replacement for every TypeScript codebase.

Clarifying questions expected:

  • "Does this codebase use TS enums, namespaces, or other non-erasable syntax anywhere, even in a few files?" β€” directly decides whether native stripping alone is sufficient, or a transpiler is still genuinely required.
  • "Is the target Node version confirmed to have type stripping enabled by default, or would an explicit --experimental-strip-types flag (or an even older version lacking it entirely) be needed?" β€” a real, version-dependent detail worth confirming for a specific deployment target.

Code / implementation expected: Yes β€” a real .ts file genuinely running with zero flags, alongside a real, specific error on a genuine TS enum, is the concrete, convincing proof of exactly where native stripping's real capability ends.

  • nodejs
  • typescript
  • tooling
  • esm

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

7 min read Β· 7 sections

Read the code

Real native TypeScript execution: erasable syntax genuinely runs with zero flags; a real enum genuinely fails with a specific error
# interfaces.ts β€” purely erasable syntax
# interface Point { x: number; y: number; }
# function dist(p: Point): number { return Math.sqrt(p.x ** 2 + p.y ** 2); }
# console.log(dist({ x: 3, y: 4 }));

$ node interfaces.ts
5
# genuinely ran with ZERO flags, zero installed packages

# enum-test.ts β€” requires real code generation, not mere erasure
# enum Color { Red, Green, Blue }
# console.log(Color.Green);

$ node enum-test.ts
SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode
    at parseTypeScript (node:internal/modules/typescript:68:40)
# genuinely fails β€” enums need a real transpiler (tsx / ts-node), not just stripping

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 85 of 152 in Node.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Node.js questions
Up nextMedium

What is the purpose of the cluster module and how does it utilize multi-core CPUs?

Continue