Hiprup

What is metadata in Angular?

Metadata in Angular is the configuration attached to a class via a decorator (@Component, @NgModule, @Injectable, @Directive). Tells Angular how to use the class.

  • Component metadataselector, template, styles, changeDetection, standalone, imports.

  • Module metadatadeclarations, imports, providers, exports, bootstrap.

  • Service metadataprovidedIn on @Injectable; controls where the service lives in the DI tree.

  • Read at compile time — the Angular compiler uses metadata to wire up DI, change detection, and template references.

  • Reflect-metadata — the underlying library that lets decorators carry runtime info.

  • Without metadata — the class is just a plain TypeScript class; Angular doesn't know what to do with it.

// Metadata = the configuration object passed to a decorator
import { Component, Injectable, Directive, NgModule, ChangeDetectionStrategy } from '@angular/core';

// @Component metadata
@Component({
  selector: 'app-greeting',                    // CSS selector for the host element
  standalone: true,                            // standalone component (modern default)
  imports: [CommonModule],                     // standalone imports
  templateUrl: './greeting.component.html',
  styleUrls: ['./greeting.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class GreetingComponent {}

// @Injectable metadata
@Injectable({ providedIn: 'root' })           // tree-shakeable singleton at root injector
export class UserService {}

// @Directive metadata
@Directive({
  selector: '[appHighlight]',
  standalone: true
})
export class HighlightDirective {}

// @NgModule metadata (legacy module-based)
@NgModule({
  declarations: [/* ... */],
  imports: [/* ... */],
  providers: [/* ... */],
  exports: [/* ... */]
})
export class FeatureModule {}

Each decorator receives a metadata object that Angular's compiler reads at build time. @Component configures the view (selector, template, styles, changeDetection, standalone, imports). @Injectable({ providedIn: 'root' }) tells DI to create a tree-shakeable singleton at the root injector. @Directive follows the same model as @Component but without a template. @NgModule groups declarations/imports/providers/exports. Because the compiler reads metadata statically, values must be statically analyzable — function calls and arrow expressions in metadata historically failed AOT (modern Ivy is lenient but the rule still helps with library compatibility).

Metadata = the config object passed to a decorator. Compiler reads it statically at build time — function calls in metadata historically failed AOT. Naming reflect-metadata signals depth.

What is metadata in Angular? | Hiprup