-
Notifications
You must be signed in to change notification settings - Fork 441
[discussion]: nest analyze --unused-routes β detect backend routes not consumed by the frontendΒ #3294
Description
Is there an existing issue that is already proposing this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe it
As NestJS backends grow, it's common to accumulate HTTP routes that were once needed but are no longer called by the frontend. There is currently no automated, static way to detect these "dead routes". Teams rely on manual API doc reviews or runtime traffic analysis, neither of which works in local or CI environments.
Describe the solution you'd like
A new nest analyze --unused-routes command that statically detects backend routes not consumed by a given frontend codebase.
How it works (working PoC already exists):
- Uses
ts-morphto walk the backend AST and extract all route definitions:@Controller()prefixes combined with@Get(),@Post(),@Put(),@Patch(),@Delete(),@All()method decorators, accounting for@Version()and the global prefix innest-cli.json - Uses the same
ts-morphpipeline on the frontend source to find HTTP client call sites (string/template literals matching route patterns, calls tofetch,axios,HttpClient,useSWR,useQuery, etc.) - Diffs both sets and reports routes present in the backend but never referenced in the frontend
Proposed CLI interface:
# Frontend in same monorepo
nest analyze --unused-routes --frontend ./apps/web
# Private remote frontend repo (GitHub PAT for auth)
nest analyze --unused-routes \
--frontend https://github.com/org/frontend-repo \
--frontend-token
# Machine-readable output for CI
nest analyze --unused-routes --format jsonExample output:
β Unused routes detected (3):
DELETE /api/v1/reports/:id β ReportsController#remove
GET /api/v1/exports/csv β ExportsController#getCsv
POST /api/legacy/notifications β NotificationsController
β 47 routes verified as consumed by frontend.
Considered drawbacks:
- Frontend call-site detection via string matching can produce false positives if routes are constructed dynamically at runtime (e.g. computed URL strings). This is a known limitation and can be documented.
- Cloning a remote frontend repo adds I/O overhead; the PAT is never persisted or logged.
- Scope of frontend framework support needs community input (plain fetch/axios vs framework-specific wrappers for v1).
Teachability, documentation, adoption, migration strategy
Usage would follow the same pattern as other nest CLI commands β no app bootstrap required, purely static analysis.
Docs entry (draft):
Analyzing unused routes
nest analyze --unused-routes --frontend [--frontend-token ] [--format json]| Flag | Description |
|---|---|
--frontend |
Path to the frontend source (local) or GitHub repo URL (remote) |
--frontend-token |
GitHub PAT for private frontend repos (never stored) |
--format |
Output format: text (default) or json for CI consumption |
Adoption: Zero config for monorepos β reads existing nest-cli.json for entry file, source root, and global prefix. No additional setup needed.
Video of the PoC output (delayed on purpose):
What is the motivation / use case for changing the behavior?
Concrete use cases:
- A team refactors a large feature and removes the frontend calls, but forgets to clean up the backend controllers. The dead routes accumulate silently.
- A monorepo using Nx or Turborepo wants to enforce "no orphaned routes" as a CI check β today there is no
nest-native way to do this. - A developer inherits a legacy NestJS backend and wants to understand which routes are actually in use before attempting a cleanup.
Why nest-cli specifically? It already reads nest-cli.json (entry file, source root, global prefix), so it has the project context needed to resolve routes correctly. No need to re-configure paths or bootstrap the NestJS app.
Alternatives considered and why they fall short:
- Runtime traffic analysis β requires production traffic; not suitable for local or CI environments
- OpenAPI diffing β tells you what's documented vs deployed, not what the frontend actually calls; also requires Swagger to be set up
- ESLint plugin β harder to correlate across repos; separate config burden
- Standalone ts-morph script β exists as community gists but not integrated into the CLI toolchain and requires per-project setup
I have a working PoC and am ready to submit a PR once there is alignment on the command interface, naming, and whether this belongs in nest-cli core or a separate @nestjs/analyze package.
