Decorators — Nest's Building Block

How Nest Knows What Your Code Means

Decorators — Nest's Building Block

Decorators attach metadata to classes, methods, and parameters. Nest reads that metadata at runtime to wire everything together.

4 min read Level 2/5 #nestjs#decorators#metadata
What you'll learn
  • Recognize the three categories — class, method, and parameter decorators
  • Use the built-in decorators fluently
  • Know that decorators rely on reflect-metadata

Most of what looks like “magic” in Nest is just decorators — functions that attach metadata to your code. Nest reads that metadata at startup to build the request pipeline.

Three Categories

import {
  Controller, Module, Injectable,           // class decorators
  Get, Post, Put, Delete,                   // method decorators
  Body, Param, Query, Headers,              // parameter decorators
} from '@nestjs/common';

@Injectable()                       // class
export class UsersService {}

@Controller('users')                // class
export class UsersController {
  @Get(':id')                       // method
  findOne(@Param('id') id: string)  // parameter
  {
    return { id };
  }
}

The pattern is consistent: class decorators say “this is a Nest thing,” method decorators map a method to an HTTP verb, parameter decorators pull a value out of the request.

They’re Just Metadata

A decorator does not change what your method does on its own. It writes information into a side table (via reflect-metadata) that the framework reads later. You can confirm this:

import 'reflect-metadata';

@Controller('users')
class Users {}

Reflect.getMetadata('path', Users);  // → 'users'

That’s exactly how Nest discovers routes — by reading the same metadata.

The tsconfig Settings That Make It Work

For decorators (and DI’s parameter-type lookup) to work, two flags must be on:

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

emitDecoratorMetadata is the important one for Nest — it tells the compiler to embed parameter types in the output so DI can read them at runtime.

You Can Write Your Own

Custom decorators are a one-liner with createParamDecorator or SetMetadata. We’ll build a @CurrentUser() decorator near the end of this section. For now, just know that anywhere built-ins fall short, you can extend the surface yourself.

HTTP Platform — Express vs Fastify →