| name | vercel-doctor |
| description | Run vercel-doctor on a Next.js project to find costly Vercel patterns BEFORE they inflate the bill, then route the fixes to the owning dev-flow skill (`data-fetching` for caching, `design-md-to-app` for images). The cost counterpart to `compliance-audit` (legal gate); dev-flow proposes it before a Vercel deploy. Use when the user says "my Vercel bill is high", "optimize for Vercel", "reduce Vercel cost", "vercel-doctor", "check caching / function duration / image cost". Refuses for non-Vercel / non-Next targets. Not for: legal/privacy audit (use compliance-audit), building features, or actually deploying (use vercel-deploy). |
vercel-doctor — cost & performance pre-deploy gate for Vercel/Next.js
Runs on a project that already exists and targets Vercel. It wraps the third-party vercel-doctor CLI — which scans a Next.js codebase for patterns that cost money on Vercel — and turns its report into applied fixes, routing each finding to the skill that owns it.
Third-party tool. vercel-doctor is not an official Vercel product — it's an independent
open-source project by Aniket-508, published to npm as
vercel-doctor (bin vercel-doctor, MIT). Verified against the npm registry + repo README
(latest at time of writing: 1.2.0 — pin or re-check, the flag set can change). It reads your
codebase and phones home unless --offline; treat its AI-fix prompts as suggestions to verify, not gospel.
Verified invocation + flags
npx -y vercel-doctor@latest .
npx -y vercel-doctor@latest . --output markdown --report docs/vercel/doctor-report.md
npx -y vercel-doctor@latest . --ai-prompts docs/vercel/doctor-fixes.json
| Flag | Effect |
|---|
--output <human|json|markdown> | report format (default human) |
--report <file> | write the report to a file |
--ai-prompts <file> | export fix prompts as JSON (only issues with a known fix strategy) |
--score | print only the health score |
--verbose | list the matching files per rule |
--diff [base] | scan only files changed vs the base branch |
--project <name> / -y, --yes | pick workspace project(s) / scan all without prompting |
--no-lint / --no-dead-code | skip the lint / dead-code analyses |
--offline | skip telemetry |
-v, --version / -h, --help | version / help |
If a flag above is rejected, the CLI has moved — run npx -y vercel-doctor@latest --help and use what
it reports rather than guessing.
⚠️ Two behaviours the --help does not tell you (found by running it)
- With uncommitted changes it silently scans only those. You don't have to pass
--diff — if the
working tree is dirty the run prints "Scanning uncommitted changes" and looks at just those files.
A dirty tree can therefore produce a confident "No issues found!" that means nothing. Run it on a
clean tree (commit or stash first) when you want a real audit, and check the line that says either
"Found N source files" (full scan) or "Scanning N changed source files" (diff mode) before you
trust the result.
--offline also disables the score. Telemetry is what computes it (--help: "anonymous, not
stored, only used to calculate score"). Use --offline for a private codebase and accept there is no
number; drop it only when the user is happy for the scan to phone home.
The six cost areas it scans
| Area | Typical finding | Who fixes it in dev-flow |
|---|
| Caching | fetch/routes that opt out of the CDN; missing "use cache" / revalidate | data-fetching (Next 16 Cache Components — "use cache", cacheLife, revalidateTag) |
| Unused code | dead files, exports, types | safe cleanup (delete + tsc verify) — mechanical, this skill |
| Function duration | long-running serverless work, blocking awaits, oversized bundles | this skill flags; heavy refactors → the owning feature skill |
| Image optimization | unoptimized images, missing sizes, raster where SVG fits | design-md-to-app image patterns / next/image config |
| Function invocations | patterns triggering excessive serverless calls (per-request fan-out) | data-fetching (lift reads to Server Components, batch) |
| Platform / config | next.config / vercel.json / region / runtime misconfig | this skill (config is mechanical) |
Run, then route
-
Preconditions. meta.json#stack.framework ∈ {"next","monorepo"} and the deploy target is Vercel (stack.deploy = "vercel" or the user says so). Refuse otherwise — the checks are Vercel-specific.
-
Run npx -y vercel-doctor@latest . --output markdown --report docs/vercel/doctor-report.md at the project root (or apps/web/, or --project <name> in a monorepo). Add --ai-prompts docs/vercel/doctor-fixes.json when you want the fix prompts. Capture the markdown report + health score (--score alone if you only need the number).
-
Triage each finding by area (table above). Verify it in the code before acting — a scan is a
signal, not a verdict. Trust the categories unequally:
| Category | Trust | Why |
|---|
| Caching / route policy | high | reading a route's headers is a fact |
Deployment + config (file count, --archive=tgz, Fluid Compute) | high | mechanical, verifiable |
| Static-asset size | medium | the threshold is low (~25 KB); judge each asset |
| Link prefetch | read the version first — see below | |
Dead code (Unused file / Unused export / Unused type) | lowest — never act on it alone | see below |
⚠️ The dead-code pass is the one that will hurt you. It runs knip, which resolves imports on its
own and does not know about framework-discovered entry points. On a real run against a Next 16 +
eve project it flagged 67 of 115 files (58%) as unused — and every one we spot-checked was wrong:
agent/agent.ts (the eve agent entry point, discovered by path, imported by nobody — deleting it
destroys the agent), db/index.ts (imported by agent/tools/* via a relative path), hooks/use-mobile.ts
(imported through the alias), and (used by ).
, and treat anything a framework discovers by convention —
, route files, /, , config files — as a guaranteed
false positive. When in doubt, and audit that separately.
meta.json#vercel_doctor block
"vercel_doctor": {
"last_run_at": "<ISO>",
"health_score": 0,
"findings": { "high": 0, "medium": 0, "low": 0 },
"fixed": ["unused-code","image-sizes"],
"routed": { "data-fetching": ["caching","invocations"], "design-md-to-app": ["images"] }
}
dev-flow hook
Horizontal capability — run any time. dev-flow proposes it as a pre-deploy gate at feature_complete (right beside compliance-audit — legal gate + cost gate before shipping), and re-runs it in the deployed maintenance loop (catch cost regressions after changes). It records meta.json#vercel_doctor + history and never bumps phase. It never blocks the deploy on its own — it surfaces the score + findings so the user decides.
Relationship to other skills
compliance-audit — the sibling gate: legal/privacy risk (GDPR/AI-Act) vs vercel-doctor's cost/perf risk. Both are feature_complete pre-deploy gates, both no-phase-bump, both "auto-fix safe + route/flag the rest."
data-fetching — owns the real fix for the two biggest cost areas (caching, invocations). vercel-doctor detects, data-fetching corrects (Next 16 "use cache" / Server-Component reads). Don't duplicate its ladder.
shadscan — the third gate: UI quality + accessibility. Same shape (pre-deploy, no phase bump, auto-fix safe + route the rest), different surface. Worth noting the contrast in precision: shadscan reports what is present in the file it names, while the dead-code pass here resolves imports speculatively and gets it wrong most of the time.
vercel-deploy — the actual Vercel deploy. vercel-doctor runs before it, not instead of it.
Definition of Done
docs/vercel/doctor-report.md written; meta.json#vercel_doctor populated with the score + findings.
- Safe fixes applied as reviewable diffs (dead code removed with
tsc green; config/image tweaks); judgment calls routed to data-fetching / design-md-to-app with a one-line pointer each.
- Every reported finding was verified in code before acting (no raw scan noise).
What this skill does NOT do
- Not a legal/privacy audit — that's
compliance-audit.
- Doesn't deploy — that's
vercel-deploy.
- Doesn't re-implement the caching/read rules — it routes to
data-fetching.
- Doesn't bump
phase, and never blocks deploy by itself.
Reference files
references/contracts.md — the .workflow/ dev-flow contract (vendored).