NestJS, with its modular and expressive syntax, is built around decorators. While Nest provides a wide variety of built-in decorators—like @Controller(), @Injectable(), and @Get()—you’re not limited to just those. In fact, one of the most powerful features of NestJS is the ability to create your own custom decorator to encapsulate logic, improve readability, and promote code reuse.
In this guide, we’ll explore how to build and use custom decorators in NestJS, explain when to use them, and show practical examples.
What Are Decorators in NestJS?
Decorators are special functions prefixed with @
that attach metadata to classes, methods, properties, or parameters. NestJS uses decorators heavily for things like routing, dependency injection, and more.
Custom decorators let you extend this concept by defining your own annotations for frequently-used logic or patterns.
Why Create Custom Decorators?
Here’s why custom decorators can improve your codebase:
- Code Reusability: Extract repeating logic into reusable decorators.
- Cleaner Controllers: Keep controllers lean and readable by offloading responsibilities.
- Separation of Concerns: Abstract away logic like authentication, permissions, or metadata extraction.
Creating a Simple Parameter Decorator
Let’s start with a basic example: a decorator that retrieves the current user from the request object.
@CurrentUser()
Decorator

Usage in a controller:

This avoids repeating request.user
logic inside every controller.
Creating a Custom Method Decorator
Method decorators are ideal for cross-cutting concerns like logging or authorization. Let’s create a custom role-checking decorator.
@Roles()
Decorator

This decorator doesn’t contain logic itself—it simply sets metadata. You’d use it alongside a guard:

Then a RolesGuard
would read the metadata and decide access.
Custom Class Decorator Example
You can even apply decorators to classes—for example, to automatically apply global middleware or metadata:

This isn’t as common as method or parameter decorators, but it’s useful in advanced use cases.
NestJS Decorators + Reflect Metadata
Most custom decorators work using Reflect Metadata. It allows you to attach and retrieve metadata at runtime:

This is how NestJS passes data between decorators and guards, interceptors, or middleware.
Best Practices for Custom Decorators
- Keep them single-responsibility: One decorator should do one thing.
- Avoid excessive logic inside the decorator itself.
- Pair with guards/interceptors when decorators need enforcement logic.
- Use naming conventions (
@CurrentUser
,@Public
,@Roles
, etc.) for clarity.
Real-World Use Cases
- Authentication:
@Public()
for routes that bypass auth. - Authorization:
@Roles('admin')
for RBAC. - Validation: Custom decorators for DTO transformation.
- Logging/Tracking: Tag routes or services for monitoring tools.
- Feature Flags: Enable/disable features conditionally.
Final Thoughts

Creating custom decorators in NestJS empowers you to write more expressive, clean, and reusable code. Whether you’re extracting metadata, wrapping logic, or extending existing patterns, decorators help keep your project organised and modular.
By mastering custom decorators in NestJS, you’re adding a powerful tool to your backend development toolkit.
Explore how seasoned backend teams apply advanced NestJS patterns at Dev Centre House Ireland.nestjs-decorators.jpg