Fix Vite 8 Oxc Not Lowering Native Decorators

Vite's own migration guide text stating the Oxc transformer does not support lowering native decorators, next to a tsconfig.json experimentalDecorators setting
On this page

Why Oxc can’t lower this syntax

Vite 8’s migration guide states the limitation directly, under the section on replacing esbuild with Oxc for JavaScript transformation: “The Oxc transformer does not support lowering native decorators.”

“Lowering” means downlevel-compiling newer syntax into older, broadly-supported JavaScript for a build target that doesn’t understand it natively, the same job esbuild used to do for decorators alongside everything else it transformed. Oxc, Vite 8’s replacement for that transform step, doesn’t implement this specific lowering pass.

This is easy to conflate with a different, much older feature: TypeScript’s experimentalDecorators, the decorator implementation most real-world projects (Angular-style DI containers, some ORMs, class-based state management) have used for years. That’s a separate TypeScript-level transform, unaffected by this Oxc gap. It keeps working the same as it always has. The limitation is specifically about TC39’s newer native decorator proposal, a related but distinct syntax that TypeScript can also emit when experimentalDecorators is off.

Fix it: use the transform that already works

Before: native decorators targeting an older environment

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020"
    // no experimentalDecorators — TypeScript emits native
    // decorator syntax, which Oxc can't lower for ES2020 (BROKEN)
  }
}

After: TypeScript’s legacy decorator transform

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "experimentalDecorators": true, // FIXED: TypeScript itself lowers
    "emitDecoratorMetadata": true // this transform, not Oxc
  }
}

experimentalDecorators changes which decorator semantics your code actually gets, not just how it’s compiled. This is a real behavior difference, not a drop-in syntax swap, so check the library or framework you’re using decorators for to confirm which mode it expects before flipping this setting.

If you specifically need native decorator semantics

Switching to experimentalDecorators isn’t an option if a dependency requires the real TC39 native decorator behavior. In that case, either target a JavaScript environment new enough to run native decorators without lowering at all, or pre-transform those files with a separate tool (Babel or SWC both support native decorator lowering) before Vite processes them.

Confirmed version range

Documented in Vite’s own current migration guide as a known limitation of Oxc’s transformer in Vite 8, with no committed fix timeline. This site’s own TypeScript config doesn’t use class decorators in any form, so this limitation wasn’t independently reproducible against this repo’s own build. The distinction between native and experimentalDecorators syntax is the same regardless of which project hits it. Browse more posts like this in the Guides & Fixes archive.

Frequently asked

Does this affect TypeScript's older experimentalDecorators feature too?

No, and that distinction matters. TypeScript's legacy experimentalDecorators (the widely-used, older decorator implementation) transforms fine under Oxc, same as it did under esbuild. This limitation is specifically about the newer TC39 native decorator proposal syntax, a different language feature that happens to look similar.

Will Oxc add native decorator lowering in a future release?

Possibly, but there's no committed timeline as of this research. If your build target already supports native decorators without lowering (a sufficiently new JS runtime), you don't need to wait on it at all; the limitation only matters when you need older-target compatibility.

Emitted as FAQPage JSON-LD from the same frontmatter — one source, no duplicated prose.

Recent posts

Full-text search via Pagefind · ↑↓ to navigate · ↵ to open