routemage
v0.1.12
Published
Scan your Next.js, Express, Fastify, or NestJS project and generate an API manifest
Downloads
1,538
Maintainers
Readme
routemage
Scan your Next.js, Express, Fastify, or NestJS project and auto-upload every endpoint to your Routemage workspace — all params, request bodies, descriptions, response shapes, and auth patterns extracted from source code with zero config.
Supported frameworks
| Framework | Discovery | Body extraction | Description |
|---|---|---|---|
| Next.js (App Router) | app/**/route.ts | Zod schemas, type annotations, req.json() destructure, formData() | JSDoc on the handler |
| Next.js (Pages Router) | pages/api/**/*.ts | req.body accesses, Request<P,R,B> generics, Zod schemas | JSDoc on the default export |
| Express | app.METHOD(), Router() mounting via app.use(prefix, router) | req.body accesses, Request<P,R,B> generics, Zod schemas | JSDoc on the route call |
| Fastify | fastify.METHOD(), fastify.route(), fastify.register({ prefix }) | JSON Schema in opts.schema.body (gold standard), Zod fallback | schema.description / schema.summary |
| NestJS | @Controller + @Get/@Post/etc. decorators | @Body() dto: SomeDto resolved via class-validator decorators | @ApiOperation({ summary, description }) |
Multi-framework monorepos are auto-detected — every framework with matching files contributes to a single manifest.
npm install -g routemage
routemage login
routemage scanCommands
| Command | Description |
|---|---|
| routemage login | Prompt for API key, validate it, save to ~/.routemage/config.json |
| routemage logout | Clear saved API key |
| routemage scan | Scan project + auto-upload to your workspace |
| routemage scan --output file.json | Write manifest locally, skip upload |
| routemage scan --no-upload | Same as --output, writes to routemage/manifest.json |
| routemage scan --generate-docs | After upload, trigger AI doc generation for all routes |
| routemage --version | Print version |
Quick start
1 — Install
npm install -g routemage
# or: npx routemage <command>2 — Log in (once)
routemage login
# Paste your API key: rm_live_xxxxxxxxxxxxxxxxxxxx
# ✓ Logged in as [email protected]
# Key saved to ~/.routemage/config.jsonSign in at app.routemage.com to grab one.
3 — Scan your project
cd /path/to/your-nextjs-app
routemage scan
# Detecting frameworks...
# Scanning nextjs-app 138/318 app/api/users/route.ts
# GET /api/users [high]
# GET /api/users/:id [high]
# POST /api/users [high]
# DELETE /api/users/:id [medium]
# POST /api/auth/login [high]
# ✓ 5 endpoints synced → app.routemage.comAfter upload, open app.routemage.com — every route is in the sidebar, ready to test and document.
API key priority
The CLI looks for your API key in this order (first match wins):
ROUTEMAGE_API_KEYenvironment variable — for CI/CD pipelines~/.routemage/config.json— set byroutemage login.routemage.config.jsonin the project root — team-shared key
CI usage
Set ROUTEMAGE_API_KEY as a secret — no routemage login needed:
- name: Scan and upload
run: npx routemage scan
env:
ROUTEMAGE_API_KEY: ${{ secrets.ROUTEMAGE_API_KEY }}What gets extracted
Routemage uses TypeScript AST parsing (ts-morph) to extract from every route.ts / route.js under app/:
| What | How it's detected |
|---|---|
| HTTP methods | export const GET, POST, PUT, DELETE, PATCH, ... |
| Route paths | File path → /api/users/:id |
| Path & query params | Route segments + searchParams.get("name") calls |
| Request body shape | Destructured req.json(), type annotations, property access |
| Auth type | Bearer, authorization, getServerSession, auth() patterns |
Each field includes a confidence level — high, medium, or low.
Manifest format
Saved to routemage/manifest.json when using --output or --no-upload:
{
"version": "1",
"generatedAt": "2025-01-01T00:00:00.000Z",
"source": "cli",
"project": {
"name": "my-app",
"framework": "nextjs-app"
},
"endpoints": [
{
"id": "a1b2c3d4e5f6a7b8",
"path": "/api/users/:id",
"method": "GET",
"confidence": "high",
"parameters": {
"path": [{ "name": "id", "required": true }],
"query": [],
"headers": []
},
"requestBody": null,
"auth": { "required": true, "type": "bearer" }
}
]
}Requirements
- Node.js 18+
- A Next.js project using the App Router (
app/directory) - Route handlers named
route.tsorroute.js
Scanner fidelity harness (dev only)
The CLI ships with a dev-only harness for testing scanner output against
real open-source codebases. It is not part of the published binary —
it lives under packages/cli/scripts/scan-check/ and is run via pnpm.
# One-time: clone the test repos at pinned commit shas into ./test-repos/
pnpm --filter routemage scan:check:bootstrap
# Run scan + diff against curated ground truth for every repo
pnpm --filter routemage scan:check
# Or filter to a single repo
pnpm --filter routemage scan:check node-express-realworldFor each cloned repo, the harness picks the adapter declared in
scripts/scan-check/repos.json,
runs it, and diffs the output against
scripts/scan-check/expected/<name>.json. Mismatches are grouped into
missing, extra, and mismatched with field-level detail. Exit
status is non-zero on unannotated diffs.
Adding a new test repo
- Append an entry to
repos.json:
Use{ "framework": "express", "name": "my-fixture", "git": "https://github.com/owner/repo", "ref": "<full commit sha>", "subdir": "." }git ls-remote <url> HEADto get a stable ref. - Run
pnpm --filter routemage scan:check:bootstrapto clone it. - Hand-write
expected/<name>.json(schema below) by reading the repo's route registrations. - Re-run
pnpm --filter routemage scan:check my-fixtureuntil it's PASS.
expected.json shape
{
"name": "my-fixture",
"endpoints": [
{
"method": "POST",
"path": "/api/users",
"auth": { "type": "none" },
"parameters": { "path": [], "query": [] },
"requestBody": { "present": true },
"responses": ["201", "400"]
}
],
"knownIssues": [
{ "endpoint": "GET /api/foo", "note": "scanner-bug: tracking-id" }
]
}Comparator v1 checks auth.type, sorted path/query param names,
requestBody presence (boolean — not schema), and response
status keys (set equality). Schema deep-equals and descriptions are
deferred. knownIssues suppresses an endpoint key from causing a FAIL
but still counts in the summary so outstanding bugs stay visible.
Links
- Platform — app.routemage.com
- Documentation — docs.routemage.com
- Website — routemage.com
