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

apiforge-analyzer

v1.3.2

Published

Universal API documentation generator for Express, Next.js, Vite, React Router, and Node.js

Downloads

317

Readme

apiforge-analyzer

CLI and library for auto-generating API documentation from live Express, NestJS, Next.js, Vite, and React Router apps.

Routes are extracted at runtime by walking the framework's internal route stack — no static analysis, no decorators, no changes to your production code.

CLI usage

npx apiforge

Run this from your project root. The CLI will:

  1. Detect your architecture (monolithic / modular-monolithic / microservices)
  2. Find your server entry file (or ask)
  3. Inject a temporary analysis snippet
  4. Start your server with the command you choose
  5. Collect all registered routes
  6. Upload to your APIForge dashboard for review
  7. Remove the injected code

For microservices, if an apiforge.config.json exists the CLI iterates every service sequentially, collects routes from each, then uploads everything in one batch. If no config file exists, the CLI scans your services/ directory, shows what it found, and writes the config file for you — so the next run is fully automatic.

// apiforge.config.json — auto-created on first run, commit this file
{
  "projectName": "My Backend",
  "architectureType": "microservices",
  "services": [
    { "name": "auth-service",  "dir": "./services/auth-service" },
    { "name": "user-service",  "dir": "./services/user-service" },
    { "name": "order-service", "dir": "./services/order-service" }
  ]
}

Each service entry can also include "startCommand" to override the default (node <entryFile>):

{ "name": "auth-service", "dir": "./services/auth", "startCommand": "npx tsx services/auth/src/index.ts" }

Programmatic API

Install:

npm install apiforge-analyzer

Express

const express = require('express')
const { analyze } = require('apiforge-analyzer')

const app = express()
app.use(express.json())

app.get('/api/users', getUsers)
app.post('/api/users', createUser)
app.get('/api/users/:id', getUserById)

// Call after all routes are registered
analyze(app, {
  projectName: 'My API',
  apiKey: process.env.APIFORGE_API_KEY,
  baseUrl: 'https://api.myapp.com',
  upload: true,
})

app.listen(3000)

NestJS

import { analyze } from 'apiforge-analyzer'

const app = await NestFactory.create(AppModule)
await app.init()

await analyze(app.getHttpServer(), {
  projectName: 'My NestJS API',
  apiKey: process.env.APIFORGE_API_KEY,
  upload: true,
})

await app.listen(3000)

Microservices — per-service

When running each service independently, pass service to tag routes with the service name:

const { analyze } = require('apiforge-analyzer')

analyze(app, {
  projectName: 'My Platform',
  apiKey: process.env.APIFORGE_API_KEY,
  architectureType: 'microservices',
  service: 'auth-service',
  upload: true,
})

Next.js Pages Router

import { analyzeNextPages } from 'apiforge-analyzer'

await analyzeNextPages({
  projectName: 'My Next.js API',
  apiKey: process.env.APIFORGE_API_KEY,
  nextDir: 'pages/api',
  upload: true,
})

Next.js App Router

import { analyzeNextApp } from 'apiforge-analyzer'

await analyzeNextApp({
  projectName: 'My Next.js API',
  apiKey: process.env.APIFORGE_API_KEY,
  nextDir: 'app',
  upload: true,
})

Vite

import { analyzeVite } from 'apiforge-analyzer'

await analyzeVite({
  projectName: 'My App',
  apiKey: process.env.APIFORGE_API_KEY,
  nextDir: 'vite.config.ts',
  upload: true,
})

React Router

import { analyzeReactRouter } from 'apiforge-analyzer'

await analyzeReactRouter({
  projectName: 'My App',
  apiKey: process.env.APIFORGE_API_KEY,
  nextDir: 'src/routes.tsx',
  upload: true,
})

Options

interface AnalyzerOptions {
  projectName: string          // required

  apiKey?: string              // APIForge API key — also read from APIFORGE_API_KEY env var
  baseUrl?: string             // base URL shown in generated docs (e.g. https://api.myapp.com)
  apiForgeUrl?: string         // override backend URL (default: https://apiforgeapi.brainfogagency.com)

  upload?: boolean             // upload to dashboard (default: true when apiKey is set)
  saveJson?: boolean           // write routes to a local JSON file
  jsonPath?: string            // path for the JSON file (default: api-export.json)

  architectureType?: 'monolithic' | 'modular-monolithic' | 'microservices'
  service?: string             // service name for microservices mode — stamped on every route

  framework?: string           // skip auto-detection and force a framework
  nextDir?: string             // directory or config file path for Next.js / Vite / React Router

  skipInProduction?: boolean   // skip when NODE_ENV=production (default: true)
  runOnce?: boolean            // debounce — skip if analyzed within the last 30 s (default: true)
}

Architecture detection

The CLI scores structural signals to pick the right architecture automatically:

| Signal | Architecture | |---|---| | apiforge.config.json with services[] | microservices | | docker-compose.yml with 3+ node services | microservices | | Multiple package.json files in sibling dirs | microservices | | src/modules/ or src/features/ directory | modular-monolithic | | *.module.ts files (NestJS @Module) | modular-monolithic | | None of the above | monolithic |

For modular-monolithic projects, routes are automatically grouped by module using path-prefix matching — /api/users/* gets tagged as the users module.

Output format

Each collected route:

{
  method: 'GET',
  path: '/api/users/:id',
  tag: 'users',
  operationId: 'get-api-users-id',
  summary: 'Get api users',
  middleware: ['authenticate'],
  authRequired: true,
  pathParams: ['id'],
  queryParams: [],
  requestBodyFields: [],
  responseStatuses: [200, 404],
  framework: 'express',
  moduleName?: 'users',        // modular-monolithic only
  serviceName?: 'auth-service' // microservices only
}

ESM and CommonJS

// ESM
import { analyze } from 'apiforge-analyzer'

// CommonJS
const { analyze } = require('apiforge-analyzer')

Environment variables

| Variable | Description | |---|---| | APIFORGE_API_KEY | API key — loaded automatically, no dotenv required | | APIFORGE_URL | Override backend URL | | NODE_ENV | Set to production to disable analysis |

Get an API key

apiforge.brainfogagency.com/dashboard

License

MIT