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

@routegraph/cli

v1.1.0

Published

The routegraph CLI: init, dev, build, validate, generate-client, export-docs.

Downloads

34

Readme

@routegraph/cli

The routegraph command-line tool: scaffold projects, run a dev server with hot reload and docs, validate routes, generate a typed client, and export docs/OpenAPI.

Installation

pnpm add -D @routegraph/cli   # local, recommended — scripts call `routegraph ...` via package.json
npx @routegraph/cli init      # or run one-off without installing

Commands

routegraph init

Interactive project scaffold. Skip prompts with --yes to use defaults (Express, port 3000, all features, pnpm).

routegraph init [--name <name>] [--adapter <name>] [--dir <path>] [--yes]

| Flag | Default | Notes | |---|---|---| | --name | my-api | Also used as the scaffolded package.json name | | --adapter | express | express \| hono \| fastify \| elysia \| koa | | --dir | ./<name> | Target directory | | --yes | off | Skip all prompts, scaffold with defaults immediately |

The interactive wizard (when --yes is not passed) asks: project name → framework (with a one-line hint per option) → port → features (API Docs / Hot Reload / OpenAPI / Typed Client, multi-select) → package manager (pnpm/npm/bun) → a summary box → a final "Create project?" confirmation. In a non-TTY environment (CI, pipes), every prompt falls back to logging its default answer instead of blocking.

Scaffolds: routes/{_shared/db.ts, health/GET.ts, users/GET.ts, users/POST.ts, users/[id]/GET.ts, users/[id]/DELETE.ts}, middleware/logger.ts, an adapter-specific index.ts, package.json, and a tsconfig.json that extends @routegraph/core/tsconfig.json.

routegraph dev

routegraph dev [--dir ./routes] [--adapter express] [--port 3000] [--host localhost] [--docs|--no-docs] [--no-watch]

Loads your routes, dynamically imports the chosen adapter + framework from your project's own node_modules, starts a server, and (by default) starts @routegraph/watcher and mounts the docs UI. Prints a startup banner:

 ◈  RouteGraph Dev Server

 API      →  http://localhost:3000/api
 Docs     →  http://localhost:3000/_routegraph
 Adapter      express
 Routes       9 registered
 Watch        enabled

 Press Ctrl+C to stop

  GET      /
  GET      /health
  ...

followed by a compact list of every registered route. On a hot-reload event, prints a timestamped diff line per changed/added/removed file:

[14:32:07] ↻  routes/users/GET.ts changed — reloaded in 3ms
[14:32:19] +  routes/users/[id]/posts/GET.ts added

Docs UI auto-mounting works out of the box for express, fastify, and koa. For hono and elysia, --docs currently logs a warning and skips mounting — wire createDocsMiddleware manually (see @routegraph/docs's README). The fastify/elysia adapter loading itself is also currently broken via this command — see the init note above; use the manual server-setup pattern from examples/with-express/index.fastify.ts / index.elysia.ts for those two frameworks in the meantime.

Port already in use: exits with code 1 and a friendly Port <n> is already in use. Try --port <n+1> message rather than an unhandled EADDRINUSE stack trace.

routegraph build

routegraph build [--dir ./routes] [--out ./dist] [--docs-out ./dist/docs] [--skip-docs] [--skip-types] [--skip-validate] [--ci]

Pipeline, in order: validate routes → tsc --noEmit (via npx tsc) → generate <out>/routemap.ts (skippable with --skip-types) → export static docs to <docs-out> + <out>/openapi.json (skippable with --skip-docs). Any step failing stops the build and returns exit code 1; a validation or typecheck failure prints the specific issues before exiting.

 ✓  RouteGraph Build Complete

 ✓ Validate             9 routes validated  (12ms)
 ✓ TypeScript           TypeScript — no errors  (1840ms)
 ✓ RouteMap             RouteMap generated → dist/routemap.ts  (8ms)
 ✓ Docs                 Docs exported → dist/docs/index.html (14.2 KB)  (22ms)
 ✓ OpenAPI              OpenAPI spec → dist/openapi.json  (6ms)

 Build time: 1.89s

--ci strips ANSI color codes and disables spinner animation (forces the same plain output every command already falls back to automatically when stdout isn't a TTY).

routegraph routes

routegraph routes [--dir ./routes] [--base <url>] [--json] [--filter <METHOD>] [--tag <tag>] [--sort path|method|tag] [--watch]

Prints a table (Method | Path | Description) plus a method-count bar chart. --json prints Array<{ method, path, description, tags, deprecated }> instead (and disables --watch's re-render loop). --watch re-renders on every route file change until Ctrl+C.

routegraph validate

routegraph validate [--dir ./routes] [--strict] [--fix]

Imports every route file and checks: is there a default export, and is it a function? Is the config export (if present) an object? --strict additionally requires every route to have a config export. Exits 1 if any route has issues; prints a fix hint under each failing route where one applies (e.g. export default async function handler(req, res) { ... }). --fix is currently a stub — it prints "Auto-fix coming soon" and makes no changes.

routegraph generate-client

routegraph generate-client [--dir ./routes] [--out ./routemap.ts] [--watch]

Writes the AppRouteMap type file consumed by @routegraph/client's createClient<AppRouteMap>(). Prints a preview box of the first 10 lines of the generated file, plus the exact import line to use. --watch regenerates on every route change until Ctrl+C.

routegraph export-docs

routegraph export-docs [--dir ./routes] [--out <path>] [--base <url>] [--format ui|openapi]

--format ui (default): static docs site via @routegraph/docs's exportDocs(), written to --out (default ./docs-dist). --format openapi: an OpenAPI 3.1.0 JSON document via graph.toOpenAPISpec(), written to --out (default ./openapi.json). --base (default http://localhost:3000) only affects the ui format's Try It Out panel default base URL.

Non-TTY / CI behavior

Every interactive element (spinners, the init wizard's prompts, box-drawn banners and tables) detects whether stdout/stdin is a TTY and automatically falls back to plain, single-line, colorless output when it isn't — no flag required for CI/pipes to get clean logs. routegraph build --ci forces that same plain mode even in an interactive terminal, for consistent CI log capture regardless of how the job happens to be invoked.

How route files load without a separate build step

The CLI registers a node:module loader hook at startup (register() with a data: URL module) that uses Node's built-in stripTypeScriptTypes() (Node 22.13+/23+) to strip TypeScript syntax from your route files on the fly as they're import()-ed, plus a resolve hook that retries a literal .js specifier as .ts (route files import siblings with a .js extension per NodeNext convention, even though the files on disk are .ts). This means CLI commands that load your routes (dev, validate, routes, build, generate-client, export-docs) work directly against your .ts source with no tsx/ts-node dependency of their own — though the example app's dev:manual-style scripts do use tsx for running an index.ts entry point directly, outside the CLI.