TypeScript developers have been debating this for months, and the dust is finally settling — but the landscape it reveals is more fractured than anyone expected. Node.js v25.2.0 stabilized type stripping, which means you can now run node app.ts directly. No compilation step. No tsconfig.json. No build pipeline for simple scripts. It sounds like the developer experience TypeScript always deserved, and in many ways it is. But there’s a catch that fundamentally changes how we think about the TypeScript language itself.
Node.js strips types at the textual level without understanding TypeScript’s semantics. It literally removes type annotations from the source code and runs what’s left as JavaScript. This means “erasable” syntax — type annotations, interfaces, type aliases, generics — works perfectly. The runtime just deletes them and the remaining JavaScript is valid. But “runtime” syntax — enums, namespaces, parameter properties, const enum — is banned. These features don’t just annotate JavaScript; they generate JavaScript code. An enum like enum Direction { Up, Down } compiles to an actual JavaScript object with reverse mappings. You can’t just erase it; you have to transform it. Node.js refuses to do that transformation, so it throws an error.
TypeScript 5.8 responded by adding the --erasableSyntaxOnly compiler flag. When enabled, tsc will error if your code uses any non-erasable features. This flag essentially formalizes the bifurcation: there is now “erasable TypeScript” (the subset that runs everywhere) and “full TypeScript” (the complete language that requires compilation).
Why This Matters More Than You Think
TypeScript enums have been controversial for years. They generate runtime JavaScript objects, add bundle size, and behave differently from every other TypeScript construct. Many style guides — including several from large tech companies — already recommend as const objects over enums. The TypeScript team itself has hinted that enums were a design decision they might not repeat.
But enums are deeply embedded in millions of codebases. Angular uses them extensively throughout its framework and documentation. NestJS patterns rely on them for decorators and guards. Countless enterprise applications have enums woven through their domain models, API contracts, and database mappings. You can’t just flip a compiler flag and call it a day.
The bifurcation creates a real practical problem: code that compiles and runs with tsc might fail with node --experimental-strip-types (which is graduating to stable). If you’re writing a library, do you target erasable-only TypeScript to maximize compatibility, or do you use the full language? If you’re starting a new project, do you adopt the simpler node app.ts workflow and give up enums, or do you keep your build pipeline for the full feature set?
The Developer Experience Tradeoff
For new projects, the simplification is genuinely fantastic. node app.ts is zero-config, instant execution. No tsc --watch, no ts-node, no tsx — just Node.js running your TypeScript directly. For scripts, CLIs, and small services, this is a massive quality-of-life improvement.
For existing projects with enums and namespaces, there’s a migration cost. I spent a weekend migrating a side project: 45 enums converted to as const objects with derived types. The resulting code was actually cleaner in many ways — TypeScript’s type inference with as const is remarkably powerful, and the patterns are more composable than enum types. But the migration wasn’t trivial. Enum comparison semantics differ from string literal comparisons in subtle ways. Several switch statements needed updating because exhaustiveness checking works differently. A few runtime checks that relied on Object.values(MyEnum) had to be rewritten.
Ecosystem Convergence
Here’s what makes this feel inevitable rather than optional: Deno has always stripped types without supporting runtime features. Bun currently supports enums but is signaling alignment with Node.js’s approach. The three major JavaScript runtimes are converging on erasable-only TypeScript as the standard.
This convergence is creating a de facto standard. The question is whether it fractures the community into “modern TypeScript” (erasable only, runs everywhere without compilation) and “full TypeScript” (with enums and namespaces, requires a build step). We’ve seen similar bifurcations before — CommonJS vs ESM took years to resolve and arguably still isn’t fully resolved in practice.
My prediction: within two years, new TypeScript projects will overwhelmingly use erasable-only syntax. Existing projects will migrate gradually, probably tied to major version bumps or framework upgrades. Enums won’t disappear from the language spec, but they’ll become a legacy feature — supported but not recommended.
Has your team adopted Node.js type stripping yet? Are you planning to remove enums from your codebase, or is the migration cost too high to justify?