Skip to content
Back to skills

Vercel Doctor

ASecurity

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

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 19, 2026
developmentpythonrustgoshellbashnextjsgitperformance

Works with

  • cli

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 19, 2026

npx -y skills add lukedj78/dev-flow --skill vercel-doctor --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Vercel Doctor?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Vercel Doctor
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lukedj78-vercel-doctor/badge)](https://www.skillsdirectory.com/skills/lukedj78-vercel-doctor)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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), UI quality (shadscan), launch readiness (launch-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](https://www.vercel-doctor.com/) 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](https://github.com/Aniket-508/vercel-doctor), 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

```bash
npx -y vercel-doctor@latest .                       # scan the project at <path>
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)

1. **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.
2. **`--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

1. **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.
2. **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).
3. **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 `buttonVariants` (used by `components/ui/calendar.tsx`).
   **Open every file before deleting it**, and treat anything a framework discovers by convention —
   `agent/**`, route files, `middleware`/`proxy`, `instrumentation.ts`, config files — as a guaranteed
   false positive. When in doubt, `--no-dead-code` and audit that separately.

   ⚠️ **The Link-prefetch advice predates Next 16.3.** It says "add `prefetch={false}`… add `prefetch={true}`
   only to critical links", which was right when every link cost a prefetch request. Under **Partial
   Prefetching** (16.3) Next prefetches one reusable **App Shell per route**, so rendering a `<Link>` is
   effectively free and `prefetch={true}` means something different (deeper per-link prefetch + runtime
   prefetching). On ≤16.2 the advice stands; on 16.3+ with `partialPrefetching` on, **ignore it** and follow
   `data-fetching` §Instant Navigation instead.
4. **Apply the safe, mechanical fixes** here (dead-code deletion with `tsc --noEmit` green, config corrections, `next/image` `sizes`/format tweaks).
5. **Route the judgment calls** to the owning skill rather than hand-fixing: caching + invocation findings → `data-fetching` (it owns the Next 16 read/caching ladder); image-pattern findings → `design-md-to-app`. Don't re-implement their rules here.
6. **Persist**: write the report to `docs/vercel/doctor-report.md`, update `meta.json#vercel_doctor`, append `history`. **No phase bump.**

## Regions against the residency decision

When `meta.json#stack.data_residency` is `"eu"` or `"eu-sovereign"`, a function region outside the EU is not only a latency question. `python3 <dev-flow>/scripts/data_residency.py check <root>` reports every `regions` in `vercel.json` (project-level and per function) and region-bearing hosts in `.env*.example` that are not EU; surface those in the report as **flagged** and route the decision to `module-add deploy` / `dev-flow/references/eu-data-sovereignty.md` — never move a region on your own (a Blob store's region cannot be changed after creation).

## `meta.json#vercel_doctor` block

```jsonc
"vercel_doctor": {
  "last_run_at": "<ISO>",
  "health_score": 0,            // as reported
  "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`** — another of the five gates: 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).

Files in this skill

  • SKILL.md10.8 KB
  • references/contracts.md80.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.