NewsJavaScriptDeveloper Tools

Node.js 26 Dropped Transform-Types: Fix Your TypeScript Enums Now

Node.js 26 dropped --experimental-transform-types flag, breaking TypeScript enum support without a build step
Node.js 26 removed transform-types support — enums now require a build step or tsx loader

Node.js 26 shipped on May 5 and quietly removed something a lot of developers were treating as a permanent feature: the --experimental-transform-types flag. If you have TypeScript code with enums, namespaces, or class parameter properties running directly through Node without a build step, that code breaks on Node 26. No warning, no deprecation grace period — the flag is simply gone. Here is what changed, what breaks, and three paths to fix it.

Strip Types vs. Transform Types: The Distinction That Now Matters

Node.js has supported TypeScript type stripping since v22.6.0. The idea is simple: strip the type annotations, run the remaining JavaScript. This works for erasable syntax — type annotations, interfaces, generic parameters. Remove them and you have valid JS.

Enums are different. An enum like enum Status { ACTIVE, PENDING } does not just disappear when you strip types. It compiles into a runtime JavaScript object. That requires transformation, not erasure. The --experimental-transform-types flag handled that work. Node 26 removed it with no replacement, because the Node team concluded that transformation belongs in build tooling, not the runtime.

The result: if your TypeScript code uses enums and you relied on --experimental-transform-types, it stops running on Node 26. The breakage is clean — you will get an unknown flag error immediately — but the blast radius is wide for teams that built scripts and internal tools assuming the flag would stabilize.

Three Ways to Fix It

Option 1: Refactor to as const Objects

This is the recommended path for new projects and small enum counts. Replace your enums with plain object literals using as const, then derive the type from the object. The result is erasable syntax that Node 26 handles natively with zero tooling overhead.

// Before: breaks on Node 26
enum HttpStatus {
  OK = 200,
  NOT_FOUND = 404,
  SERVER_ERROR = 500,
}

// After: works with Node 26 native type stripping
const HttpStatus = {
  OK: 200,
  NOT_FOUND: 404,
  SERVER_ERROR: 500,
} as const;

type HttpStatus = typeof HttpStatus[keyof typeof HttpStatus];

The as const object is pure JavaScript at runtime. Node strips the type annotation; the object literal stays. You get the same developer experience — named constants, type safety, autocomplete — without the transformation dependency.

Option 2: Use the tsx Loader

If you have an existing codebase with heavy enum usage and a full refactor is not realistic right now, tsx is the fastest path to keeping your code running on Node 26 without changing your TypeScript.

npm install -D tsx

# Replace: node --experimental-transform-types file.ts
# With:
tsx file.ts

tsx is powered by esbuild, supports full TypeScript including enums, decorators, and namespaces, and is a drop-in replacement for the node command. It passes all unrecognized CLI arguments through to Node, so existing scripts need minimal changes. This is the right call for internal tooling, CLI scripts, and automation that you cannot afford to refactor immediately.

Option 3: Add a Build Step

For production applications, the right answer was always a build step. If Node 26 is the forcing function that gets your team to configure tsc or swc properly, that is a net positive. Compile your TypeScript, run the output JavaScript. Deterministic, deployable, no runtime flag dependencies.

Lock Down Your tsconfig Now

TypeScript 5.8 added the erasableSyntaxOnly compiler option precisely for this scenario. Set it to true and TypeScript will error at compile time on any syntax that requires transformation — including enums. This turns a potential Node 26 runtime surprise into a build-time error you can catch in CI. Here is the recommended tsconfig for Node 26 compatibility:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "nodenext",
    "erasableSyntaxOnly": true,
    "verbatimModuleSyntax": true,
    "rewriteRelativeImportExtensions": true
  }
}

Add erasableSyntaxOnly: true to your tsconfig today. You will find every enum in your codebase on the next CI run — which is exactly what you want before Node 26 goes LTS in October.

What Else Node 26 Delivers

The --experimental-transform-types removal is a stumbling block, but Node 26 is a genuinely strong release. The headline features beyond the TypeScript changes:

  • Temporal API enabled by default — no flag, no polyfill. The era of reaching for date-fns or dayjs for timezone-safe date math is ending.
  • V8 14.6 — ships Map.prototype.getOrInsert() and getOrInsertComputed(), eliminating a very common defensive initialization pattern.
  • Iterator.concat() — native lazy iterator composition without third-party libraries.
  • Undici 8 — the HTTP client underlying fetch() gets a major update with improved HTTP/2 handling.
  • TypeScript type stripping is now stable — no longer experimental. The foundation for native TypeScript in Node is solid; it just does not include transforms.

Should You Upgrade Now?

Node 26 is the “Current” release, not LTS. It becomes LTS in October 2026. For production services, stay on Node 24 LTS — it is the active long-term support line and the right choice for anything that cannot tolerate unexpected breaking changes. If you are on Node 22, it is in maintenance mode with EOL in April 2027, and Node 24 should be your next stop anyway.

Start testing Node 26 now. The enum removal is the most significant breaking change, and the fix is mechanical — refactor to as const, add tsx to your dev dependencies, or add a build step. Teams that test early will have a clean LTS migration in October. Teams that wait will scramble.

Enums were always an awkward TypeScript feature — a runtime construct dressed up as a type-level abstraction. Node 26 just sent the invoice for that choice. The migration path is clear. Move now.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:News