Find where each OpenAPI endpoint is used across your codebase.
Route Scout answers one question fast: "where is this endpoint consumed?" Point it at your OpenAPI specs and your source, and it maps every operation to its call sites — in CI, or right inside VSCode.
It's spec-agnostic and framework-agnostic. You configure three things:
- which specs (globs),
- which sources (globs),
- how a usage looks (matchers) — the part that adapts Route Scout to your client, whether that's a
generated client (
operationIdfunctions), react-query hooks (use{OperationId}), or rawfetch()calls keyed by URL.
| Package | What it is |
|---|---|
@route-scout/core |
The engine: spec parsing + usage matching. No coupling. |
route-scout-cli |
CLI — reports, --unused-only, JSON/Markdown for CI. |
route-scout-vscode |
VSCode extension — CodeLens, tree view, quick search. |
Route Scout is available on every store — install the extension from wherever your editor pulls from:
- VS Code Marketplace → Route Scout (or
code --install-extension MathieuLeTyrant.route-scout-vscode) - Open VSX (VSCodium, Cursor, Gitpod, Windsurf…) → Route Scout
.vsixfrom GitHub Releases → Extensions → Install from VSIX…
Then open a spec file — a ⟶ N usages lens appears above every operation, and Cmd/Ctrl+Click on an
operation jumps to its usages.
Prefer the terminal? The CLI ships on npm as
route-scout-cli (the command it installs is
route-scout):
# zero config (auto-discovers specs + scans common sources)
npx route-scout-cli
# which endpoints are never called?
npx route-scout-cli --unused-only
# or install it once, then use the `route-scout` command:
npm i -g route-scout-cli
route-scout --unused-onlyEach usage matcher has a template expanded per operation, with placeholders:
| Placeholder | getUserById, GET /users/{id} |
|---|---|
{operationId} / {OperationId} |
getUserById / GetUserById |
{operationId:camel|pascal|kebab|snake|constant} |
getUserById / GetUserById / get-user-by-id / get_user_by_id / GET_USER_BY_ID |
{method} / {METHOD} |
get / GET |
{path} / {pathRegex} |
/users/{id} / /users/[^/]+ |
symbolmatchers match a whole identifier (fast; the default).regexmatchers match a regular expression per line (values auto-escaped;{pathRegex}raw).filesrestricts a matcher to the files it makes sense in (e.g."files": "crons.json").
Defaults target the common case:
[
{ "kind": "symbol", "template": "{operationId}" },
{ "kind": "symbol", "template": "use{OperationId}" }
]Imports are masked before matching (multi-line aware, ignoreImports — on by default), so bringing a
symbol into scope never counts as usage.
Route Scout matches by convention, not by type resolution — it's fast, language-agnostic, and honest
about being a heuristic. operationIds are usually distinctive enough that collisions are rare; tune
the matchers to your codebase. When a name still collides with something unrelated (e.g. an Apollo
const [getDevice] = useGetDeviceLazyQuery()), or when the same operationId lives on several
endpoints, declare your generated clients: a hit then counts only if it's linked to one, and it's
attributed to that client's spec. It does not follow re-exports or resolve dynamic URLs. Operations with
no operationId can only be matched by regex/{path} matchers.
A real-world routescout.config.json for a monorepo whose specs live under packages/openapi-specs/
and whose consumers are React apps (react-query hooks) plus server-to-server callers. The key is
excluding the generated client code so the generated definitions aren't counted as usage — the
default {operationId} / use{OperationId} matchers then cover both hooks and .op(...) calls:
{
"$schema": "https://raw.githubusercontent.com/mathieuletyrant/route-scout/refs/heads/main/schema.json",
"specs": ["packages/openapi-specs/*-openapi.json"],
"sources": ["apps/**/src/**/*.{ts,tsx}"],
"exclude": [
"**/node_modules/**",
"**/dist/**",
"**/dist_server/**",
"**/dist_react/**",
"**/out-tsc/**",
"**/.nx/cache/**",
"**/__generated__/**",
"**/*-client/**",
"**/*.schemas.ts",
"**/*.msw.ts",
"**/*.zod.ts"
],
"usage": [
{ "kind": "symbol", "template": "{operationId}" },
{ "kind": "symbol", "template": "use{OperationId}" }
]
}In the VSCode extension, drop this file at the repo root and set "routeScout.configFile": "routescout.config.json" in .vscode/settings.json. The CLI auto-discovers it.
pnpm install
pnpm build # builds core → cli → vscode (topological)
pnpm test # vitest (core)
pnpm typecheck
pnpm lint
pnpm package:vscode # produces packages/vscode/route-scout.vsixSee CONTRIBUTING.md. Licensed MIT.