Analyze Vercel project configurations for correctness, performance, and security. Examines vercel.json, framework settings, build configuration, edge functions, middleware, headers, redirects, environment variables, and deployment patterns. Finds misconfigurations before they cause production incidents.
Use when: "review our Vercel config", "why is our Vercel deployment slow", "check vercel.json", "optimize our edge functions", "fix Vercel build errors", "audit our headers and redirects", or when deploying a new project to Vercel.
Locate and read all Vercel-relevant files:
vercel.json — primary configurationnext.config.js, nuxt.config.ts, svelte.config.js, astro.config.mjs, etc.package.json — build commands and framework detection.env* files — check existence, not contentmiddleware.ts / middleware.js — edge middlewareapi/ / pages/api/ / app/api/ — serverless and edge functions (search for export const runtime)Check each section of vercel.json for correctness:
Build Configuration:
json
{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"installCommand": "npm ci",
"framework": "nextjs"
}
Common issues:
buildCommand not matching package.json scriptsoutputDirectory wrong for the framework (Next.js: .next, Vite: dist, CRA: build)framework field causing incorrect auto-detectionnpm install instead of npm ci (non-deterministic builds)Framework detection matrix:
FrameworkExpected Output DirAuto-DetectedBuild CommandNext.js.nextYesnext buildVitedistYesvite buildCreate React AppbuildYesreact-scripts buildNuxt.outputYesnuxt buildSvelteKit.svelte-kitYesvite buildAstrodistYesastro buildRemixbuildYesremix buildPlain HTMLpublic or .NoNone
json
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "X-XSS-Protection", "value": "1; mode=block" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
Security headers checklist:
HeaderRequiredPurposeRecommended ValueStrict-Transport-SecurityCriticalForce HTTPSmax-age=63072000; includeSubDomains; preload``X-Content-Type-OptionsCriticalPrevent MIME sniffingnosniff``X-Frame-OptionsHighPrevent clickjackingDENY or SAMEORIGIN``Content-Security-PolicyHighPrevent XSS/injectionApplication-specificReferrer-PolicyMediumControl referrer infostrict-origin-when-cross-origin``Permissions-PolicyMediumRestrict browser featuresDeny unused featuresX-XSS-ProtectionLowLegacy XSS filter0 (or omit; CSP replaces this)
Cache strategy recommendations:
Resource TypeCache-ControlWhyHashed assets (JS/CSS)public, max-age=31536000, immutableContent-addressed, never changesImages/fontspublic, max-age=86400, stale-while-revalidate=604800Changes rarelyHTML pagespublic, max-age=0, must-revalidateShould always check for updatesAPI responsesno-store or private, max-age=60Depends on data freshness needsUser-specific dataprivate, no-storeMust never be cached in shared caches
Redirect issues to check:
permanent: true (301) for temporary moves — browsers cache 301s aggressively, very hard to undo/about vs /about/)Rewrite issues to check:
has conditions — creates an open proxy/:path* -> /index.html) not placed LAST — overrides API routesFunctions can be configured in vercel.json (per-file memory, maxDuration, runtime) or inline with export const runtime = 'edge' and export const maxDuration = 30.
Function optimization checklist:
maxDuration for long operations (default: 10s Hobby / 60s Pro)Edge vs Serverless decision matrix:
Use CaseRecommended RuntimeWhyAuthentication/authorizationEdgeLow latency, runs before page loadsGeolocation-based routingEdgeAccess to request.geoA/B testingEdgeModify response before it reaches clientFeature flagsEdgeFast, runs at the edgeDatabase queriesServerless (Node.js)Most DB drivers need Node.js APIsFile processingServerless (Node.js)Needs Node.js fs/stream APIsHeavy computationServerless (Node.js)Edge has CPU time limitsExternal API proxyEitherEdge if latency-sensitive
Search code for process.env.* and client-exposed prefixes. Key audit checks:
VERCEL_URL usage — use for dynamic base URL on preview deploymentsFramework-specific variable exposure:
FrameworkClient-Exposed PrefixServer-OnlyNext.jsNEXT_PUBLIC_*Everything elseViteVITE_*Everything elseCreate React AppREACT_APP_*Everything elseNuxtNUXT_PUBLIC_*``NUXT_* (server)SvelteKitPUBLIC_*Everything elseAstroPUBLIC_*Everything else
Common build time culprits and fixes:
CulpritTime CostFixnpm install30-120sUse npm ci, enable Vercel dependency cacheTypeScript compilation15-60sUse SWC (Next.js default), check tsconfig strictnessStatic page generationVariesReduce build-time pages, use ISR for long-tailImage optimization10-60sUse external image CDNLinting/testing in build30-120sMove to CI (GitHub Actions), don't block deploy
Check build output size with du -sh .next/ dist/ build/ and analyze build-manifest.json for oversized pages.
Middleware audit checklist:
_next/static, _next/image, and favicon.icoSameSite, Secure, and HttpOnly flagscname.vercel-dns.com)markdown
# Vercel Configuration Analysis
## Project Overview
- **Framework:** {detected framework}
- **Runtime:** {Edge / Serverless / Static}
- **Build Command:** {command}
- **Output Directory:** {path}
## Findings
### Critical
- {Security or correctness issue that will cause production problems}
### Warnings
- {Performance or best-practice issue}
### Recommendations
- {Optimization opportunities}
## Security Headers
- {Present: list}
- {Missing: list with recommended values}
## Environment Variables
- {Count of server-only vars}
- {Count of client-exposed vars}
- {Any sensitive vars exposed to client}
## Performance
- {Build time analysis}
- {Bundle size concerns}
- {Caching recommendations}
## Suggested vercel.json
{Optimized configuration}
vercel.json settings conflict with framework config (e.g., next.config.js headers override vercel.json headers in Next.js)preview environment — verify env vars are set for preview, not just productionvercel env pull locally to sync environment variables for local developmentRoot Directory in project settings and use ignoreCommand to skip unchanged projectsrevalidate — the stale page is served while regenerating (stale-while-revalidate pattern)vercel build locally to test the exact build process Vercel will runvercel logs) for runtime errors that don't appear in build outputX-Robots-Tag: noindex header on non-production deployments