How to Run TypeScript Directly in Node.js Without Transpilation
Problem
I was tired of waiting for TypeScript to compile every time I made a small change. For quick scripts and prototypes, the compile step felt unnecessary. I just wanted to write TypeScript and run it directly like I would with JavaScript.
I tried running a TypeScript file with Node.js:
node app.tsAnd it worked. No errors, no transpilation needed. That’s when I realized Node.js 23+ can run TypeScript natively.
How It Works
Starting from Node.js 23.6.0, the --experimental-strip-types flag is enabled by default. This means Node.js can execute TypeScript files directly by stripping type annotations at runtime.
Quick Start
Create a simple TypeScript file:
interface User { name: string; age: number;}
function greet(user: User): string { return `Hello, ${user.name}! You are ${user.age} years old.`;}
const user: User = { name: "Alice", age: 30 };console.log(greet(user));Run it directly:
node app.tsThat’s it. No tsc, no build step.
Configuration Requirements
For this to work reliably, you need a proper tsconfig.json. The key settings are:
{ "compilerOptions": { "target": "ESNext", "module": "NodeNext", "moduleResolution": "NodeNext", "noEmit": true, "erasableSyntaxOnly": true, "verbatimModuleSyntax": true }}Let me break down what each option does:
noEmit: Tells TypeScript not to output compiled JavaScript files (Node.js handles this)target: ESNext: Uses the latest JavaScript featuresmodule: NodeNext: Uses ES modules (required for native TypeScript support)moduleResolution: NodeNext: Matches the module settingerasableSyntaxOnly: Ensures you only use TypeScript syntax that can be stripped (no enums, namespaces, etc.)verbatimModuleSyntax: Requires explicit imports/exports, enabling cleaner type stripping
Enhanced TypeScript Support with TSX
For even better development experience, you can use tsx - it provides hot reloading and faster execution:
npm install -D tsxnode --import=tsx app.tsOr use the tsx binary directly:
npx tsx app.tsThe --import=tsx approach lets you keep using the node command while getting tsx’s enhanced features.
Limitations
This feature is experimental and has constraints:
Erasable Syntax Only (By Default)
Node.js strips type annotations by replacing them with whitespace. Some TypeScript features require actual code transformation, not just stripping:
// This works (erasable syntax)type Status = "pending" | "active" | "done";const status: Status = "active";
// This requires transformation (not erasable)enum Color { Red = "red", Blue = "blue",}To enable transformation for non-erasable syntax, use:
node --experimental-transform-types app.tsNo Type Checking
Node.js does NOT perform type checking when running TypeScript directly. It simply strips types and runs the code. Your types could be completely wrong and Node.js won’t care.
For type checking, you still need:
npx tsc --noEmitProduction Warning
This feature is experimental. Do NOT use it in production:
- Performance is not optimized
- Behavior may change between Node.js versions
- Some edge cases may fail silently
For production, always compile with tsc and deploy the JavaScript output.
When to Use This
Run TypeScript directly in Node.js for:
- Quick prototypes and experiments
- Small scripts and automation
- Learning TypeScript without build tools
- Development workflows with hot reloading
Still use traditional compilation for:
- Production applications
- Complex projects with build pipelines
- When you need type checking during development
- When you need maximum performance
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments