decorator-transforms

raw JSON →
2.3.1 verified Sat Apr 25 auth: no javascript

A Babel plugin that transforms JavaScript decorators (legacy TC39 stage 1) into simpler, smaller code using modern features like class static blocks, private fields, and WeakMap. Current stable version is 2.3.1, released December 2025, with minor/patch releases every few months. Key differentiators vs @babel/plugin-proposal-decorators: significantly smaller output, avoids transpiling other class features, built-in browser compatibility options. Supports both legacy and loose mode decorators, aims for bug-for-bug compatibility with Babel's legacy decorator transform. Includes a runtime helper for decorator initialization.

error Module not found: Can't resolve 'decorator-transforms/globals'
cause Missing runtime import or incorrect import path.
fix
Ensure you have added import 'decorator-transforms/globals' at the very beginning of your entry file.
error Plugin 'decorator-transforms' not found
cause Babel cannot resolve the plugin because the name convention expects 'babel-plugin-*' prefix.
fix
Use 'module:decorator-transforms' or require.resolve('decorator-transforms') in babel config.
error Transform error: Decorator transform is not supported in this environment
cause Using decorator-transforms with incompatible Babel version or missing Babel peer dependencies.
fix
Ensure Babel 7.4+ is installed and that @babel/core is a peer dependency.
gotcha Do not use 'decorator-transforms' directly as plugin name; prefix with 'module:' or use absolute path (require.resolve).
fix Use 'module:decorator-transforms' or require.resolve('decorator-transforms') in plugins array.
breaking v2.0.0 changed default runtime from 'import' to 'globals'; runEarly option introduced for broader browser compat.
fix Add import 'decorator-transforms/globals' at app entry or set runtime: { import: ... } in config.
gotcha Incompatible with @babel/plugin-proposal-decorators; do not use both simultaneously.
fix Remove @babel/plugin-proposal-decorators from plugins when using decorator-transforms.
gotcha runEarly: true requires extra babel traversal; only use if targeting browsers without native private fields/static blocks.
fix Set runEarly: false (default) unless you need transpilation of private fields or static blocks.
gotcha Ember classic builds: only 'globals' runtime option works because ember-auto-import cannot see transform output.
fix Use runtime: 'globals' (default) and import 'decorator-transforms/globals' in app.js.
npm install decorator-transforms
yarn add decorator-transforms
pnpm add decorator-transforms

Shows minimal Babel config with runEarly and runtime import, global runtime import at app entry, and a simple decorated class.

// babel.config.js
module.exports = {
  plugins: [['module:decorator-transforms', { 
    runtime: { import: require.resolve('decorator-transforms/runtime') },
    runEarly: true 
  }]]
};

// app.js (entry point)
import 'decorator-transforms/globals';

// example decorated class
function log(target, key, descriptor) {
  const original = descriptor.value;
  descriptor.value = function(...args) {
    console.log(`Calling ${key} with`, args);
    return original.apply(this, args);
  };
  return descriptor;
}

class MyClass {
  @log
  greet(name) {
    return `Hello, ${name}!`;
  }
}

const obj = new MyClass();
obj.greet('World'); // logs: Calling greet with ['World']