How to fix 'emitDecoratorMetadata' requires 'experimentalDecorators' to be enabled in TypeScript

TypeScriptBEGINNERMEDIUMUpdated Dec 8, 2025· 139 views

This TypeScript configuration error occurs when you enable emitDecoratorMetadata in tsconfig.json without also enabling experimentalDecorators. Both options must be enabled together because decorator metadata depends on the experimental decorator feature.

Quick fix

Fixes 'emitDecoratorMetadata' requires 'experimentalDecorators' to be enabled

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true
  }
}
  1. Enable experimentalDecorators in tsconfig.json
  2. Verify the configuration is correct
  3. Restart your IDE and TypeScript language server
  4. Check for multiple tsconfig files in monorepos
typescript — error
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true
}
}
'emitDecoratorMetadata' requires 'experimentalDecorators' to be enabled

What this error means

The "'emitDecoratorMetadata' requires 'experimentalDecorators' to be enabled" error appears during TypeScript compilation when your tsconfig.json has "emitDecoratorMetadata": true but lacks "experimentalDecorators": true. These two compiler options are interdependent. The emitDecoratorMetadata option enables TypeScript to emit runtime type metadata for decorated declarations when using the reflect-metadata library. This metadata includes design-time type information like parameter types, return types, and property types. However, this feature only makes sense when decorators are enabled, which is why experimentalDecorators must also be set to true. This error is commonly encountered when working with frameworks like NestJS, TypeORM, Angular, or any library that relies on dependency injection or runtime reflection. These frameworks use decorators extensively and need both the decorator syntax (experimentalDecorators) and type metadata (emitDecoratorMetadata) to function properly.

Typical symptoms

  • Compilation fails with error mentioning 'emitDecoratorMetadata' and 'experimentalDecorators'
  • Error occurs immediately when running tsc or starting the development server
  • NestJS, TypeORM, or Angular projects fail to compile after configuration changes
  • IDE shows configuration errors in tsconfig.json file
  • Build fails in CI/CD pipeline after updating TypeScript configuration
  • Error appears when trying to use @Injectable, @Entity, or other decorator-based features

Common causes

  1. tsconfig.json has emitDecoratorMetadata enabled but experimentalDecorators is missing or false
  2. Configuration file was manually edited and experimentalDecorators was accidentally removed
  3. Copying tsconfig.json from one project to another with incomplete settings
  4. Using a framework starter template that has incomplete TypeScript configuration
  5. Extending a base tsconfig that doesn't include experimentalDecorators
  6. Multiple tsconfig files in a monorepo with inconsistent decorator settings

How to fix "'emitDecoratorMetadata' requires 'experimentalDecorators' to be enabled"

1Enable experimentalDecorators in tsconfig.json

Open your tsconfig.json file and add "experimentalDecorators": true alongside "emitDecoratorMetadata": true:

json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true
  }
}

Both options must be set to true for frameworks that use decorator metadata. Save the file and the error should disappear.

2Verify the configuration is correct

After updating tsconfig.json, verify the changes by running the TypeScript compiler:

bash
# Check for compilation errors
npx tsc --noEmit

# Or run your build command
npm run build

For NestJS projects:

bash
# Start the development server
npm run start:dev

For TypeORM projects:

bash
# Run TypeORM CLI commands
npx typeorm migration:run

If the error persists, ensure there are no syntax errors in your tsconfig.json (missing commas, quotes, etc.).

3Restart your IDE and TypeScript language server

IDEs cache TypeScript configuration, so restart the language server to pick up changes:

VS Code:
1. Press Cmd/Ctrl + Shift + P
2. Type "TypeScript: Restart TS Server"
3. Press Enter

WebStorm/IntelliJ:
1. File → Invalidate Caches → Invalidate and Restart

Command line (if using ts-node):

bash
# Kill any running ts-node processes
killall ts-node

# Restart your application
npx ts-node src/index.ts

After restarting, the IDE should recognize the updated configuration and clear any red underlines.

4Check for multiple tsconfig files in monorepos

If you're working in a monorepo or project with multiple tsconfig files, ensure all relevant configurations include both options:

bash
# Find all tsconfig files
find . -name "tsconfig*.json" -not -path "*/node_modules/*"

Project structure example:

bash
my-monorepo/
├── tsconfig.base.json          # Base config
├── apps/
│   ├── api/
│   │   └── tsconfig.json       # Extends base
│   └── web/
│       └── tsconfig.json
└── packages/
    └── shared/
        └── tsconfig.json

tsconfig.base.json:

json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strict": true
  }
}

apps/api/tsconfig.json:

json
{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src"
  }
}

This ensures all packages inherit the decorator settings.

5Install reflect-metadata if using metadata features

If you're using emitDecoratorMetadata, you'll need the reflect-metadata package for runtime reflection:

bash
npm install reflect-metadata

Then import it at the top of your main entry file (before any decorators are used):

For NestJS (src/main.ts):

typescript
import "reflect-metadata";
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

For TypeORM (src/index.ts):

typescript
import "reflect-metadata";
import { createConnection } from "typeorm";
import { User } from "./entity/User";

createConnection().then(async connection => {
  // Your code here
});

Without reflect-metadata, decorator metadata won't be available at runtime, even though TypeScript will compile successfully.

Advanced notes

### Legacy vs. TC39 Decorators

TypeScript currently supports two decorator proposals:

Legacy Decorators (experimentalDecorators: true):
- The original proposal, widely used in frameworks like NestJS, TypeORM, Angular
- Supports emitDecoratorMetadata for runtime type reflection
- Parameter decorators work as expected
- Will remain supported for backward compatibility

TC39 Decorators (the new standard, default in TypeScript 5.0+):
- Stage 3 ECMAScript proposal, closer to becoming a standard
- Does NOT support emitDecoratorMetadata
- Parameter decorators not supported
- Different syntax and capabilities

Most backend frameworks still require legacy decorators:

json
{
  "compilerOptions": {
    "experimentalDecorators": true,  // Use legacy decorators
    "emitDecoratorMetadata": true     // Emit type metadata
  }
}

If you disable experimentalDecorators, you'll use TC39 decorators, which are incompatible with NestJS/TypeORM's current versions.

### Why Metadata Emission Matters

The emitDecoratorMetadata option makes TypeScript emit three special metadata keys for each decorated declaration:

1. design:type - The type of the property/parameter
2. design:paramtypes - Parameter types of a method/constructor
3. design:returntype - Return type of a method

Example:

typescript
import "reflect-metadata";

class UserService {
  constructor(private db: Database) {}
}

// TypeScript emits this metadata:
Reflect.getMetadata("design:paramtypes", UserService);
// Returns: [Database]

Dependency injection frameworks use this to automatically resolve constructor dependencies without manual wiring.

### Framework-Specific Requirements

NestJS:
- Requires both experimentalDecorators and emitDecoratorMetadata
- Uses metadata for dependency injection, parameter validation, and route handling
- Error will appear immediately if either option is missing

TypeORM:
- Uses metadata to map TypeScript classes to database tables
- Column types are inferred from TypeScript types via metadata
- Without emitDecoratorMetadata, you must specify types manually:

typescript
// Without metadata - manual type specification
@Column({ type: "varchar", length: 255 })
name: string;

// With metadata - automatic inference
@Column()
name: string;  // TypeORM knows this is varchar

Angular:
- Requires experimentalDecorators for dependency injection
- Doesn't strictly require emitDecoratorMetadata but benefits from it
- Uses InjectionToken when metadata isn't available

### Performance Considerations

Enabling emitDecoratorMetadata increases the size of compiled JavaScript output because type information is embedded as metadata. For large applications, this can add 10-20% to bundle size.

If you don't need runtime reflection, consider:
1. Using manual dependency injection without decorators
2. Using type-only imports: import type { User } from "./types"
3. Tree-shaking to remove unused metadata

### Migration Path for New Projects

If starting a new project, consider:

Stick with legacy decorators if:
- Using NestJS, TypeORM, or similar frameworks
- Need runtime type reflection
- Require parameter decorators

Use TC39 decorators if:
- Building a framework-agnostic library
- Want future-proof code aligned with ECMAScript
- Don't need emitDecoratorMetadata

You cannot use both simultaneously - it's an either/or choice per tsconfig.json.

### Debugging Configuration Issues

To verify your exact TypeScript configuration:

bash
# Show effective configuration
npx tsc --showConfig

# Check which files are included
npx tsc --listFiles | head -20

This shows the merged configuration from all extends and helps identify if decorator settings are properly applied.

Frequently asked questions

What does "'emitDecoratorMetadata' requires 'experimentalDecorators' to be enable" mean?
json has "emitDecoratorMetadata": true but lacks "experimentalDecorators": true. These two compiler options are interdependent. The emitDecoratorMetadata option enables TypeScript to emit runtime type metadata for decorated declarations when using the reflect-metadata library.
How do I fix "'emitDecoratorMetadata' requires 'experimentalDecorators' to be enable"?
This TypeScript configuration error occurs when you enable emitDecoratorMetadata in tsconfig.json without also enabling experimentalDecorators. Both options must be enabled together because decorator metadata depends on the experimental decorator feature.
What causes "'emitDecoratorMetadata' requires 'experimentalDecorators' to be enable"?
tsconfig.json has emitDecoratorMetadata enabled but experimentalDecorators is missing or false Configuration file was manually edited and experimentalDecorators was accidentally removed Copying tsconfig.json from one project to another with incomplete settings
Is the "'emitDecoratorMetadata' requires 'experimentalDecorators' to be enable" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading