cheat sheet
vercel
Package-level reference for the vercel CLI on npm — install, Node support, command surface, project linking model, and where it fits next to wrangler / netlify-cli.
vercel
What it is
vercel is the official command-line tool for Vercel's frontend cloud — the platform that hosts Next.js and many other framework deployments (SvelteKit, Astro, Nuxt, Remix, Vue, Vite, plain static). It wraps the Vercel REST API and handles project linking, deploys (preview + production), environment variables, log tailing, alias management, custom domains, certificates, and the Vercel Functions / Edge runtimes. A single vercel invocation in a project directory uploads the source, runs the same build that runs in the cloud, and returns a URL.
Reach for vercel whenever you target Vercel directly without a Git integration — local one-shot deploys, CI promotions, env-var sync, log streaming after an incident. If you only ever use the GitHub-connected auto-deploy, you may not need it day-to-day; most teams still install it for vercel env pull, vercel link, and rollback.
Install
The CLI is published as the vercel npm package. The team recommends global install because it isn't tied to a single project's lockfile and is most often used outside node_modules (e.g. clean clones, CI runners).
npm install -g vercel
Output: added 1 package; vercel on PATH
pnpm add -g vercel
Output: added vercel globally
yarn global add vercel
Output: added vercel globally
bun add -g vercel
Output: installed vercel as a global tool
Per-project install (pins the version alongside your code, especially useful in CI):
npm install -D vercel
Output: added vercel to devDependencies
One-off without install:
npx vercel --version
Output: prints installed vercel version
Verify:
vercel --version
Output: prints CLI version (currently the 47.x line, hedge against minor drift)
Versioning & Node support
Current line is vercel@47.x (mid-2026). Vercel ships a new minor roughly every 1–2 weeks, tracking platform features and runtime changes.
- Node 20+ required on the
47.xline. Earlier majors supported Node 16/18; check the changelog before upgrading old projects. - The CLI is a Node application — distributed as platform-neutral JS plus optional native deps for build acceleration.
- TypeScript types are NOT published for programmatic use — the CLI is the interface. For programmatic integrations use the Vercel REST API directly or the
@vercel/sdkpackage. - Semver is followed but the API surface (subcommand flags, output formats) shifts more often than the npm package's major number suggests. Pin in CI.
Package metadata
- Maintainer: Vercel (
vercel/vercelmono-repo on GitHub) - Project home: github.com/vercel/vercel
- Docs: vercel.com/docs/cli
- npm: npmjs.com/package/vercel
- License: Apache-2.0
- First released: 2017 (as
now, renamed tovercelin 2020 alongside the company rename) - Downloads: ~2 million weekly — one of the most-installed deploy CLIs on npm.
Peer dependencies & extras
vercel declares no peer dependencies — it is a self-contained CLI. The package ships a large bundle (~50–80 MB after install) because it embeds the Vercel build runtime for local-parity builds (vercel build), the Next.js compatibility shim, and helpers for many framework adapters.
Companion packages from the same monorepo (use directly only in advanced workflows):
@vercel/node— Node Function runtime@vercel/edge— Edge Function runtime@vercel/static-build— static-build framework adapter@vercel/next— Next.js builder@vercel/blob,@vercel/kv,@vercel/postgres,@vercel/redis— storage SDKs paired with Vercel Marketplace integrations@vercel/sdk— JavaScript SDK for the REST API (programmatic alternative to shelling out to the CLI)@vercel/og— Open Graph image generation for Vercel runtimes@vercel/analytics,@vercel/speed-insights— drop-in client SDKs
Most apps never install these directly — Vercel-aware frameworks (Next.js, SvelteKit, Astro, Nuxt) handle the integration through their own adapter packages.
Alternatives
vercel is the deploy CLI for Vercel. There is no second-party alternative. For other platforms:
| Tool | Platform |
|---|---|
wrangler | Cloudflare Workers / Pages |
netlify-cli | Netlify — Functions, Edge Functions, Forms |
flyctl | Fly.io — full VMs + edge regions |
aws-cdk / sst / sam | AWS Lambda + edge via CloudFront |
firebase | Firebase Hosting + Functions |
gcloud run deploy | Google Cloud Run |
azure functions core tools | Azure Functions |
deno deploy | Deno Deploy — Deno-native edge runtime |
render (web UI + Git integration) | Render — full apps + static |
For multi-cloud setups, frameworks like Astro, SvelteKit, and Next.js (via OpenNext / open-next.js.org) publish adapters that retarget the same source onto a competitor's CLI.
Common gotchas
- Project linking is per-directory, not per-repo.
.vercel/project.jsonis written into the current working directory. A monorepo with multiple deployable apps needsvercel linkrun once per app folder; otherwise deploys go to whichever project the root was linked to last. vercel deployandvercel --prodare NOT the same. Without--prodyou get a preview deploy with a unique URL; with--prod, the active deployment alias updates. Many teams have leaked staging features to prod by passing--prodreflexively in CI.vercel env pulloverwrites your.env.local. It writes the file without confirmation. Back up local-only overrides before pulling, or use--environment=development/--environment=preview/--environment=productionexplicitly to scope.- Git-integrated auto-deploys race with manual
vercel deploy --prod. A push and a manual deploy can complete in either order. Either disable the Git integration's production branch deploy, or stop usingvercel --prodfrom local machines. vercel.jsonprecedence vs framework config. Settings invercel.jsonoverride framework defaults silently. Customheaders,redirects,rewritesin framework config (next.config.js,astro.config.mjs) plusvercel.jsonproduce a merged result that's hard to predict — keep them in one place.vercel devis NOT the same asnext dev.vercel devruns the full Vercel build pipeline locally including Functions routing and rewrites — slower but production-faithful. Frameworks' own dev servers are faster but skip routing rules fromvercel.json.- Function concurrency is unbounded by default. Serverless / Edge functions scale per request; a misbehaving function can run up surprise bills. Use the
maxDurationandconcurrencyconfig invercel.jsonand watch the dashboard's spend caps. - Aliases vs domains. A deployment URL (
my-app-abc123.vercel.app) is permanent. The "production" URL is an alias pointed at the latest production deployment. Rollback works by re-aliasing, not by re-deploying.
Real-world recipes
These recipes target deploy-time setup — environments, aliases, env-var sync, and rollback — rather than framework-internal patterns.
One-shot deploy from a clean clone
The shortest path to production from a fresh checkout:
vercel login # opens browser for OAuth
vercel link # pick or create a project
vercel deploy # preview deploy (unique URL)
vercel deploy --prod # production deploy
Output: each command prints the deployed URL. The preview URL is permanent and shareable.
Preview vs production deploys
vercel deploy defaults to a preview environment with a deploy-specific subdomain. Use --prod to promote.
vercel deploy # preview: alice-api-abc123.vercel.app
vercel deploy --prod # production: alice-api.vercel.app
vercel deploy --prebuilt --prod # use a pre-built output (faster, see "vercel build")
Output: deployment URL printed to stdout (single line — pipe to awk to capture).
Env-var management
Env vars live in the Vercel dashboard, scoped per environment. The CLI mirrors them.
vercel env ls # list all vars across envs
vercel env add DATABASE_URL production # prompts for the value
vercel env add STRIPE_KEY preview development # multiple envs at once
vercel env rm DEBUG production
Output: each command prints the affected variable; add requires the value via stdin or interactive prompt.
For pulling secrets to a local .env.local for next dev / astro dev:
vercel env pull .env.local # development env by default
vercel env pull .env.production --environment=production
Output: writes the file; lists how many vars were pulled.
Link a directory to an existing project
When you clone a repo on a new machine:
vercel link # interactive — pick from your projects
vercel link --project my-project --yes # non-interactive (good for CI)
Output: writes .vercel/project.json (gitignored) with org + project IDs.
For monorepos with multiple apps, run vercel link once per app folder. Keep .vercel/ in .gitignore.
Custom build settings
vercel.json at the project root controls build, routing, and runtime config:
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"buildCommand": "pnpm run build",
"outputDirectory": ".vercel/output",
"installCommand": "pnpm install --frozen-lockfile",
"framework": "astro",
"regions": ["iad1", "fra1"],
"headers": [
{
"source": "/static/(.*)",
"headers": [{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }]
}
],
"rewrites": [
{ "source": "/api/(.*)", "destination": "https://upstream.example.com/api/$1" }
]
}
Settings in the dashboard win over vercel.json for inputs (build command, install command). Settings in vercel.json win for routing (rewrites, headers, redirects).
Rollback to a previous deployment
Vercel doesn't expose vercel rollback (as of mid-2026) — rollback is re-aliasing.
vercel ls # see recent deploys
vercel alias set <previous-deployment-url> <production-domain>
Output: the alias is repointed instantly; the previous code is live within seconds.
You can also promote any preview to production via the dashboard's three-dot menu — useful when the CLI session is on a different machine.
Promote a preview to production
vercel promote <preview-deployment-url>
Output: alias of the production domain updates to point at the chosen deployment.
This is the safe way to ship — deploy a preview, exercise it, then promote without rebuilding.
Production deployment
Vercel is the production target itself; "production deployment" here means the deploy hygiene around the platform.
CI deploy with tokens
In CI, authenticate with a token (Vercel dashboard → Account Settings → Tokens) instead of vercel login:
- run: npm install --global vercel@latest
- run: vercel pull --yes --environment=production --token=$VERCEL_TOKEN
- run: vercel build --prod --token=$VERCEL_TOKEN
- run: vercel deploy --prebuilt --prod --token=$VERCEL_TOKEN
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
The pull → build → deploy --prebuilt flow avoids running the build twice (once locally for verification, once on Vercel). The token + org-ID + project-ID triple replaces interactive linking.
Preview deploys per PR
The official GitHub integration handles this automatically. To do it manually (other Git hosts, custom CI):
- run: vercel deploy --token=$VERCEL_TOKEN --meta git-branch=$BRANCH > url.txt
- run: gh pr comment $PR --body "Preview: $(cat url.txt)"
Regions and edge
regions: ["iad1"] in vercel.json pins serverless Function execution to a single region. The Vercel Edge runtime always runs at the nearest PoP regardless. For data residency, scope regions carefully — they affect where logs and request bodies are processed.
Custom domains and certificates
vercel domains add example.com
vercel domains inspect example.com # see DNS instructions
vercel certs ls # certificates
Output: Vercel prints the DNS records you must add at your registrar. After DNS propagates, Vercel issues a Let's Encrypt cert automatically.
Performance tuning
vercel build+vercel deploy --prebuiltlets CI build once and upload the output, instead of asking Vercel to build remotely. Cuts deploys to 5–15 seconds.- Region selection. Pin Functions to the region closest to your database. The default (
iad1) is fine if your data lives in AWS us-east-1; otherwise expect 50–200 ms of round-trip on every cold start. - Edge over Node for stateless work. Edge Functions start in single-digit milliseconds; Node Functions start in 100–500 ms cold. Latency-sensitive endpoints prefer Edge unless they need Node-specific APIs.
maxDurationper route. Set invercel.jsonor per-Function. Long requests block other invocations on the same container.- Build caching. Vercel caches
node_modules, framework caches (.next/cache,.svelte-kit/cache), and CDN assets between builds. Don't accidentally invalidate them — frequentpackage.jsonchurn busts the cache. - ISR / on-demand revalidation. For Next.js, prefer
revalidateover re-deploying for content changes.
Version migration guide
The CLI ships rapidly and rarely has hard breaking changes — but a few major versions tightened defaults. Check the official changelog at vercel.com/changelog for your specific versions before upgrading.
| From | To | Likely changes (verify against the changelog) |
|---|---|---|
vercel@32 | vercel@33 | Node 18+ floor; legacy now.json removed in favour of vercel.json (deprecated for years but finally rejected). |
vercel@39 | vercel@40 | vercel build output path stabilised; --prebuilt recommended for CI. |
vercel@43 | vercel@44+ | Node 20+ floor; tightened token scopes for deploys. |
Recommended upgrade flow:
- Bump CLI in a branch (locally and in CI):
npm install -g vercel@latest. - Run
vercel deploy --dry-run(if available for your version) or a preview deploy on a throwaway project. - Verify
vercel.jsonparses — schema is occasionally tightened between majors. - Refresh tokens at the same time; old tokens may lack permissions a new CLI expects.
ESM/CJS interop & bundling
vercel is a CLI; the interop concerns are about the Functions it deploys, not the CLI binary.
| Concern | Pattern |
|---|---|
| Function module format | Node Functions on the nodejs20.x / nodejs22.x runtime support both ESM and CJS. package.json "type" controls the default. |
| Edge Function format | ESM only, with a runtime: "edge" export. No Node built-ins; restricted Web-API surface. |
| Next.js App Router | Server Components are ESM. Route Handlers detect ESM/CJS automatically. |
| Native modules | Functions cannot ship native bindings beyond what's on the AWS Lambda base image. Audit any node-gyp deps before deploying. |
| Bundle size limit | 50 MB unzipped per Function (and 250 MB unzipped including layers). Vercel reports size at deploy; over-limit fails the upload. |
| Tree-shaking | Vercel's builder uses nft (node-file-trace) to ship only the files a Function actually reads. ESM imports tree-shake automatically; dynamic require() is conservative. |
Plugin & ecosystem coverage
Vercel's "ecosystem" is the Marketplace (storage, auth, CMS, monitoring) plus framework adapters.
| Service | Purpose |
|---|---|
| Vercel Blob | S3-style object storage with edge CDN. Pairs with @vercel/blob. |
| Vercel KV | Redis-compatible KV (powered by Upstash). @vercel/kv. |
| Vercel Postgres | Neon-backed serverless Postgres. @vercel/postgres. |
| Vercel Edge Config | Read-only config replicated globally with sub-ms reads. |
| Marketplace integrations | Supabase, Neon, Upstash, MongoDB, Clerk, Auth0, Sentry, Resend, Stripe (provisioned via the Marketplace; env vars injected automatically). |
| Vercel Analytics | First-party RUM (@vercel/analytics). |
| Speed Insights | Core Web Vitals tracking (@vercel/speed-insights). |
| AI SDK / AI Gateway | ai package + Vercel AI Gateway for model routing. |
| Cron Jobs | Scheduled Function invocations. Declared in vercel.json. |
| Workflows (WDK) | Durable, pause/resume workflows on the Vercel platform. |
| Framework adapter | Notes |
|---|---|
next | First-class — Next.js is Vercel's framework. |
@astrojs/vercel | Astro SSR / static / edge adapter. |
@sveltejs/adapter-vercel | SvelteKit adapter. |
nuxt (nitro-vercel) | Built into Nitro. |
@remix-run/vercel | Remix adapter. |
vike (formerly vite-plugin-ssr) | Generic Vite SSR adapter. |
Testing & CI integration
The CLI doesn't run tests itself; teams pair it with their framework's test runner (Vitest, Jest, Playwright) and use the CLI only for the deploy step.
Pattern: test, then deploy, then smoke-test
jobs:
ship:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22 }
- run: npm ci
- run: npm test
- run: npm install --global vercel@latest
- run: vercel pull --yes --environment=production --token=$VERCEL_TOKEN
- run: vercel build --prod --token=$VERCEL_TOKEN
- id: deploy
run: echo "url=$(vercel deploy --prebuilt --prod --token=$VERCEL_TOKEN)" >> $GITHUB_OUTPUT
- run: curl -fsSL "${{ steps.deploy.outputs.url }}/api/health"
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
Programmatic deploys via the SDK
For workflows that don't fit a CLI (e.g. bulk preview from a queue), use @vercel/sdk:
import { Vercel } from "@vercel/sdk";
const client = new Vercel({ bearerToken: process.env.VERCEL_TOKEN });
const deployment = await client.deployments.createDeployment({
requestBody: {
name: "alice-api",
target: "production",
project: process.env.VERCEL_PROJECT_ID,
},
});
console.log(deployment.url);
Output: prints the deployment URL.
Security considerations
- Tokens scope to the whole account by default. When generating an API token in the Vercel dashboard, scope it to a specific team and rotate every 90 days. Revoke immediately after CI provider migrations.
- Environment variables ≠ secrets. Vercel encrypts env vars at rest, but they're visible in plaintext to anyone with project access. For high-value secrets, prefer integrations (HashiCorp Vault, AWS Secrets Manager via Marketplace) over plain env vars.
vercel env pullwrites plaintext locally. The resulting.env.localis unencrypted. Add.env*to.gitignoreand to your OS keychain integration if available.vercel.jsonis committed. Don't put secret values there. Use env vars and reference them:"env": { "DATABASE_URL": "@database-url" }(the@references a vercel secret, not the literal value).vercel logsshows live request data. In some setups this includes auth headers or PII in URLs. Restrict access toteam:readfor production logs.- Public deployments are public. Every preview URL is reachable on the open internet unless you enable Deployment Protection (Vercel Pro+).
- Function input validation. Vercel Functions receive the raw request — there's no platform-level WAF on the free tier. Use Vercel Firewall (paid) or framework-level middleware for rate limiting, auth, and input sanitisation.
- Domain verification. When adding a custom domain, the DNS proof is required before issuance. Don't paste the verification record into a public ticket — it allows certificate hijacking until the domain DNS is fully cut over.
Troubleshooting common errors
Error! Authentication token has expired — run vercel logout and vercel login again, or rotate VERCEL_TOKEN in CI.
Error! No existing credentials found — vercel login not run, or ~/.local/share/com.vercel.cli missing. Re-login.
Error! Could not find any framework configuration — wrong directory (e.g. you ran from the monorepo root instead of an app folder). cd into the app, re-link, redeploy.
Cannot find a project linked to the current directory — vercel link not run. Link and try again.
Deployment exceeds the maximum size limit — Function bundle too large. Inspect vercel build output for offenders (often full puppeteer or prismjs with all languages).
Error! Domain example.com is not assigned to your team — domain belongs to a different org. Move it via the dashboard or transfer ownership.
vercel dev shows different output than production — framework-level routing files (next.config.js middleware) vs vercel.json mismatch. Decide which owns routing and remove the other.
Function exceeded the maximum duration — bumped against maxDuration (default 10s on Hobby, 60s on Pro). Increase in vercel.json or refactor to a shorter Function.
vercel env pull fails silently / overwrites custom vars — it writes the whole file. Move local-only overrides to .env.local.user (not read by frameworks) before pulling.
When NOT to use this
Skip vercel when:
- You aren't deploying to Vercel. Single-vendor CLI; for Cloudflare use
wrangler, for Netlify usenetlify-cli, for AWS use CDK/SAM/SST. - You only use the GitHub-connected auto-deploy and never touch env vars or logs from CLI. Most teams still install it for
vercel env pulland rollback, but you can drive the platform entirely from the dashboard. - You're on a corporate network that blocks Vercel egress. The CLI talks to
api.vercel.com; if outbound HTTPS to Vercel is blocked, every command fails. - You want full IaC. Pulumi and Terraform have community Vercel providers — useful if you want declarative project + env-var + domain management. You'd still use the CLI for
vercel devandvercel logs, but deploys live in IaC. - You self-host Next.js.
next starton your own VM doesn't need Vercel at all. Some Vercel-specific features (ISR with on-demand revalidation, Edge Functions, Edge Config) only run on Vercel infrastructure.
See also
- JavaScript: vercel — full command reference, deploy recipes, env management
- JavaScript: wrangler — peer CLI for Cloudflare's edge platform
- JavaScript: npm — installing the CLI globally vs per-project
- Concept: api — REST API contracts underlying the CLI