It’s February 2026, and I think I’m finally ready to forgive the TC39 committee.
If you’ve been writing TypeScript as long as I have, you remember the “experimental” phase. It lasted forever. We spent nearly a decade with "experimentalDecorators": true in our tsconfig.json, building entire frameworks (looking at you, NestJS and early Angular) on a feature that was technically a draft. But here we are. The standard decorators have landed. They work in TypeScript 5.x (and the 6.0 beta looks solid). Browsers are catching up. And yet, I still see developers treating them like black magic.

They aren’t magic. They’re just functions. Sometimes very annoying functions, but functions nonetheless.
At its core, a decorator is a design pattern where you wrap a piece of code with another piece of code to extend its behavior. That’s it. You don’t need the @ symbol to do this concept in JavaScript. As described in the TypeScript documentation on decorators, they allow you to add annotations and a meta-programming syntax for class declarations and members.
I mostly use decorators today for “meta” logic—stuff that isn’t the core business logic but needs to happen anyway. Error handling, logging, performance tracking.

In a recent project running on Node 22, I got tired of wrapping every single API handler in a try/catch block. It made the actual logic hard to read. So, I used a standard Stage 3 decorator, as described in the TC39 decorators proposal.
But here’s the rub: Standard decorators operate on the definition of the class elements. Let’s say we want a @Reactive decorator that updates a DOM element whenever a property changes. In TypeScript, it looks clean. However, browsers are strict environments. If you strip away the TypeScript build step (say, you’re just shipping a vanilla JS bundle for a lightweight widget), you can’t use that syntax yet without a polyfill or very recent runtime support.
Another area where standard decorators have matured is dependency injection. In the old “experimental” days, we had to hack the prototype. The new context.addInitializer API allows us to hook into the class setup phase cleanly.
Just because we have standard decorators now doesn’t mean you should sprinkle them everywhere. My rule of thumb today? Use decorators for infrastructure concerns (logging, frameworks, DOM binding). Do NOT use them for business logic. If a junior dev needs to read the decorator source code to understand what the calculateTax() method does, you’ve failed.
The ecosystem is finally stable. TypeScript 5.7 handles this beautifully, and the tooling—ESLint, Prettier, VS Code—finally understands the new syntax without complaining. It took us a long time to get here, but the wait was arguably worth it.
Questions readers ask
Are TypeScript standard decorators finally stable in 2026?
Yes, as of February 2026 standard decorators have landed and work in TypeScript 5.x, with the 6.0 beta looking solid. The decade-long experimental phase is over, and tooling like ESLint, Prettier, and VS Code now understand the new syntax without complaining. Browsers are catching up, though stripping the TypeScript build step for vanilla JS bundles may still require a polyfill or very recent runtime support.
When should you use TypeScript decorators and when should you avoid them?
Use decorators for infrastructure concerns like logging, frameworks, DOM binding, error handling, and performance tracking—meta logic that isn’t core business logic but needs to happen anyway. Do not use them for business logic itself. The rule of thumb: if a junior developer needs to read the decorator source code to understand what a method like calculateTax() does, you’ve failed at applying them appropriately.
What is the difference between experimental and standard TypeScript decorators?
Experimental decorators required “experimentalDecorators”: true in tsconfig.json and powered frameworks like NestJS and early Angular for nearly a decade while technically a draft. Standard Stage 3 decorators, defined by the TC39 proposal, operate on the definition of class elements rather than hacking the prototype. They also introduce the context.addInitializer API, which allows clean hooks into the class setup phase for dependency injection.
How do you handle repetitive try/catch blocks in Node 22 API handlers?
The author got tired of wrapping every API handler in try/catch because it made the actual logic hard to read. In a recent Node 22 project, they replaced that boilerplate with a standard Stage 3 decorator from the TC39 decorators proposal. Decorators are well-suited for this kind of error-handling meta logic because they wrap a piece of code with another piece of code to extend its behavior cleanly.
