npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

routemage

v0.1.12

Published

Scan your Next.js, Express, Fastify, or NestJS project and generate an API manifest

Downloads

1,538

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 scan

Commands

| 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.json

Sign 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.com

After 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):

  1. ROUTEMAGE_API_KEY environment variable — for CI/CD pipelines
  2. ~/.routemage/config.json — set by routemage login
  3. .routemage.config.json in 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 levelhigh, 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.ts or route.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-realworld

For 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

  1. Append an entry to repos.json:
    {
      "framework": "express",
      "name": "my-fixture",
      "git": "https://github.com/owner/repo",
      "ref": "<full commit sha>",
      "subdir": "."
    }
    Use git ls-remote <url> HEAD to get a stable ref.
  2. Run pnpm --filter routemage scan:check:bootstrap to clone it.
  3. Hand-write expected/<name>.json (schema below) by reading the repo's route registrations.
  4. Re-run pnpm --filter routemage scan:check my-fixture until 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