Reduce your Vercel bill with one command.
Scans your Next.js codebase for patterns that increase your Vercel bill — long function durations, uncached routes, unoptimized images, expensive cron jobs, and more — then outputs actionable diagnostics.
Main.mp4
Vercel Doctor detects your framework and project setup, then runs two analysis passes in parallel:
- Billing lint — detects patterns that inflate your Vercel invoice:
- Function duration: sequential
awaits, blockingafter()calls, side effects in GET handlers - Caching: missing cache policies,
force-dynamic/no-storeoverrides, SSR where SSG would work - Image optimization: global image optimization disabled, next/image with SVG without
unoptimized, overly broad remote patterns, missingsizesprop - Invocations: Link prefetch default (use
prefetch={false}or disable globally, then addprefetch={true}only to critical links) - Edge functions: heavy imports, sequential awaits that burn CPU time
- Version-aware handling: Next.js 15/16+ caching guidance tailored to your detected Next.js major version
- Static assets: large files that should be served from an external CDN
- Build optimization: Turbopack build cache (Next.js 16+),
getStaticPropswithoutrevalidate(consider ISR), large projects →vercel deploy --archive=tgz - Platform usage: Vercel Cron vs. GitHub Actions / Cloudflare Workers, Fluid Compute, Bun runtime
- Function duration: sequential
- Dead code — detects unused files, exports, types, and duplicates that slow cold starts.
Diagnostics are filtered through your config to produce actionable results.
Run this at your project root:
npx -y vercel-doctor@latest .Use --verbose to see affected files and line numbers:
npx -y vercel-doctor@latest . --verboseTeach your coding agent Vercel cost optimization rules:
curl -fsSL https://vercel-doctor.com/install-skill.sh | bashSupports Cursor, Claude Code, Amp Code, Codex, Gemini CLI, OpenCode, Windsurf, and Antigravity.
Usage: vercel-doctor [directory] [options]
Options:
-v, --version display the version number
--no-lint skip linting
--no-dead-code skip dead code detection
--verbose show file details per rule
--score output only the score
-y, --yes skip prompts, scan all workspace projects
--project <name> select workspace project (comma-separated for multiple)
--diff [base] scan only files changed vs base branch
--offline skip telemetry (anonymous, not stored, only used to calculate score)
--output <format> output format: "human" (default), "json", or "markdown"
--report <file> write human-readable report to file
--ai-prompts <file> write AI fix prompts to JSON file for use with Cursor/Claude/Windsurf
-h, --help display help for command
Create a vercel-doctor.config.json in your project root to customize behavior:
{
"ignore": {
"rules": ["vercel-doctor/nextjs-image-missing-sizes", "knip/exports"],
"files": ["src/generated/**"]
}
}You can also use the "vercelDoctor" key in your package.json instead:
{
"vercelDoctor": {
"ignore": {
"rules": ["vercel-doctor/nextjs-image-missing-sizes"]
}
}
}If both exist, vercel-doctor.config.json takes precedence.
| Key | Type | Default | Description |
|---|---|---|---|
ignore.rules |
string[] |
[] |
Rules to suppress, using the plugin/rule format shown in diagnostic output (e.g. vercel-doctor/async-parallel, knip/exports) |
ignore.files |
string[] |
[] |
File paths to exclude, supports glob patterns (src/generated/**, **/*.test.tsx) |
lint |
boolean |
true |
Enable/disable lint checks (same as --no-lint) |
deadCode |
boolean |
true |
Enable/disable dead code detection (same as --no-dead-code) |
verbose |
boolean |
false |
Show file details per rule (same as --verbose) |
diff |
boolean | string |
— | Force diff mode (true) or pin a base branch ("main"). Set to false to disable auto-detection. |
CLI flags always override config values.
Generate detailed reports and AI-compatible fix prompts:
# Generate a markdown report
npx vercel-doctor . --output markdown --report report.md
# Export AI prompts for fixing issues (use with Cursor, Claude, Windsurf)
npx vercel-doctor . --ai-prompts fixes.jsonThe --ai-prompts flag generates ready-to-use prompts for AI coding tools. It only exports issues that have a known fix strategy. The format is auto-detected from the file extension:
.json- Structured format for programmatic use and automation.mdor.markdown- Human-readable format, easy to copy-paste into AI chats
# Export as JSON (for scripts, automation)
npx vercel-doctor . --ai-prompts fixes.json
# Export as Markdown (for manual copy-paste into Cursor/Claude/Windsurf)
npx vercel-doctor . --ai-prompts fixes.mdEach prompt includes:
- The specific rule violation
- File location, line, and column number
- Before/after code examples
- Step-by-step fix instructions
Example AI prompt output:
{
"vercel-doctor/vercel-no-force-dynamic::src/app/page.tsx:15:1": "Fix this Vercel optimization issue..."
}You can also use Vercel Doctor programmatically:
import { diagnose } from "vercel-doctor/api";
const result = await diagnose("./path/to/your/nextjs-project");
console.log(result.score); // { score: 82, label: "Good" } or null
console.log(result.diagnostics); // Array of Diagnostic objects
console.log(result.project); // Detected framework, React version, etc.The diagnose function accepts an optional second argument:
const result = await diagnose(".", {
lint: true, // run lint checks (default: true)
deadCode: true, // run dead code detection (default: true)
});Each diagnostic has the following shape:
interface Diagnostic {
filePath: string;
plugin: string;
rule: string;
severity: "error" | "warning";
message: string;
help: string;
line: number;
column: number;
category: string;
}Vercel Doctor is not affiliated with, endorsed by, or sponsored by Vercel Inc., Vercel and the Vercel logo are trademarks of Vercel Inc. This is an independent, open-source project that review Next.js project code to help optimize Vercel costs.
Want to contribute? Check out the codebase and submit a PR.
git clone https://github.com/Aniket-508/vercel-doctor
cd vercel-doctor
pnpm install
pnpm -r run buildRun locally:
node packages/vercel-doctor/dist/cli.js /path/to/your/nextjs-project