NestJS documents guards at three levels: controller, method, and application-wide. It does not document a module-scoped guard binding that automatically covers every controller in one module. Registering APP_GUARD from a module does not make the guard local: NestJS says it is global regardless of where it is declared. The distinction matters when you want to protect one module without decorating its controllers or affecting the rest of the application.
What guard scopes does NestJS document?
The NestJS guards documentation describes three binding levels:
As an Amazon Associate I earn from qualifying purchases.
- Method scope: apply a guard to a particular route handler with
@UseGuards(). - Controller scope: apply a guard to the controller so it covers that controller’s handlers, also using
@UseGuards(). - Global scope: register a guard application-wide, including through the
APP_GUARDprovider token.
The documentation explicitly clarifies that when APP_GUARD is registered through a module provider, “regardless of the module where this construction is employed, the guard is, in fact, global.” The module containing the provider is not a boundary for that guard’s execution.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Why doesn’t a module automatically scope its guards?
NestJS modules organize the application graph, including controllers and providers. The module documentation explains module structure and provider visibility; that role should not be confused with the execution scope of an enhancer such as a guard. The reviewed guard documentation does not provide a module-level binding that automatically attaches a guard to every controller declared in that module.
#1 Best Overall
That gap is the subject of a concrete request, NestJS issue #15795. It asks for guards to apply automatically to all controllers declared in a module. The issue page displays the request as closed and lists no branch or pull request in its development section. This establishes that the request exists, but does not explain why it was closed or verify the larger history of similar requests.
What do the “17 issues, 9 years, zero PRs” figures establish?
A Mango Developer article published in 2026 reports 17 requests across nine years and no implementation pull requests. Those are the article’s historical claims, not statistics from NestJS or an independently audited count. The displayed details on issue #15795 cannot verify the aggregate. A DEV Community page republishes the article and is not independent confirmation.
Use those figures as a description of what the article reports, not as a definitive measure of NestJS issue history or proof that a particular team rejected the feature. Issue status and project activity can also change over time.
What can you do in a NestJS application today?
Decorate the controllers or methods you own
When you can edit the target route code, use @UseGuards() at the controller or method level. This is the documented approach for binding a guard locally. Its trade-off is maintenance: each relevant controller or handler must carry the binding, so it may not meet a requirement to protect controllers in a module without modifying them.
Rank #3
Use a global guard and mark public routes
For authentication intended to apply across the application, NestJS’s authentication documentation shows a global APP_GUARD pattern with custom metadata to identify public routes. This can centralize the default policy while allowing selected handlers to opt out. It is application-wide, not module-scoped, and the documented pattern does not establish that it covers every third-party integration or non-HTTP transport scenario.
Choose based on ownership and boundary
- If you own the controllers and want only selected routes protected, controller- or method-level
@UseGuards()is the documented local option. - If your policy is genuinely application-wide and public exceptions can be marked in route code, consider the documented global guard and metadata pattern.
- If the requirement is specifically “apply this guard to all controllers in one module without decorating them,” neither documented binding pattern provides that module-level scope.
How does the article present Holu’s approach?
The Mango Developer article presents Holu as allowing guards to be specified when importing a module, with configuration shaped like { module: ApiModule, path: 'api', guards: [AuthGuard] }. It also says guard providers must be available in the importing module and describes a createGuardHelper() facility for parameterized guards. These are claims made by that article and its republication; they have not been independently verified against current Holu documentation or tested here.
Rank #4
That claimed configuration is conceptually different from NestJS’s documented APP_GUARD: it is presented as import-time configuration associated with an imported module, rather than an application-wide provider. Before relying on it, verify the current API, dependency-injection requirements, supported transports, and compatibility with the integrations you use. The available evidence does not establish production advantages, broad compatibility, or a migration cost.
Quick Recap
Best Value
How should you evaluate the trade-off?
- Scope: NestJS documents application-wide, controller, and method binding; Holu’s module-import behavior is described by the article rather than verified product documentation.
- Code ownership: NestJS’s local decorator approach requires access to the controllers or methods you need to annotate. The Holu article’s example puts guards in module-import configuration.
- Dependency injection: The article says Holu’s guard providers must be available in the importing module. Check that condition against the current implementation before adopting the pattern.
- Integration boundary: Do not assume either pattern covers third-party modules, GraphQL, message transports, subscriptions, or other integrations without checking the specific framework documentation and issue history for that case.
- Migration: No migration estimate is established. Replacing an existing NestJS application with another framework is a separate architectural decision, not merely a guard configuration change.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




