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

bash
npm install -g vercel

Output: added 1 package; vercel on PATH

bash
pnpm add -g vercel

Output: added vercel globally

bash
yarn global add vercel

Output: added vercel globally

bash
bun add -g vercel

Output: installed vercel as a global tool

Per-project install (pins the version alongside your code, especially useful in CI):

bash
npm install -D vercel

Output: added vercel to devDependencies

One-off without install:

bash
npx vercel --version

Output: prints installed vercel version

Verify:

bash
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.x line. 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/sdk package.
  • 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/vercel mono-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 to vercel in 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:

ToolPlatform
wranglerCloudflare Workers / Pages
netlify-cliNetlify — Functions, Edge Functions, Forms
flyctlFly.io — full VMs + edge regions
aws-cdk / sst / samAWS Lambda + edge via CloudFront
firebaseFirebase Hosting + Functions
gcloud run deployGoogle Cloud Run
azure functions core toolsAzure Functions
deno deployDeno 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

  1. Project linking is per-directory, not per-repo. .vercel/project.json is written into the current working directory. A monorepo with multiple deployable apps needs vercel link run once per app folder; otherwise deploys go to whichever project the root was linked to last.
  2. vercel deploy and vercel --prod are NOT the same. Without --prod you 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 --prod reflexively in CI.
  3. vercel env pull overwrites your .env.local. It writes the file without confirmation. Back up local-only overrides before pulling, or use --environment=development / --environment=preview / --environment=production explicitly to scope.
  4. 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 using vercel --prod from local machines.
  5. vercel.json precedence vs framework config. Settings in vercel.json override framework defaults silently. Custom headers, redirects, rewrites in framework config (next.config.js, astro.config.mjs) plus vercel.json produce a merged result that's hard to predict — keep them in one place.
  6. vercel dev is NOT the same as next dev. vercel dev runs 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 from vercel.json.
  7. Function concurrency is unbounded by default. Serverless / Edge functions scale per request; a misbehaving function can run up surprise bills. Use the maxDuration and concurrency config in vercel.json and watch the dashboard's spend caps.
  8. 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:

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

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

bash
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:

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

When you clone a repo on a new machine:

bash
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:

json
{
  "$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.

bash
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

bash
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:

yaml
- 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 pullbuilddeploy --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):

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

bash
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 --prebuilt lets 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.
  • maxDuration per route. Set in vercel.json or 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 — frequent package.json churn busts the cache.
  • ISR / on-demand revalidation. For Next.js, prefer revalidate over 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.

FromToLikely changes (verify against the changelog)
vercel@32vercel@33Node 18+ floor; legacy now.json removed in favour of vercel.json (deprecated for years but finally rejected).
vercel@39vercel@40vercel build output path stabilised; --prebuilt recommended for CI.
vercel@43vercel@44+Node 20+ floor; tightened token scopes for deploys.

Recommended upgrade flow:

  1. Bump CLI in a branch (locally and in CI): npm install -g vercel@latest.
  2. Run vercel deploy --dry-run (if available for your version) or a preview deploy on a throwaway project.
  3. Verify vercel.json parses — schema is occasionally tightened between majors.
  4. 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.

ConcernPattern
Function module formatNode Functions on the nodejs20.x / nodejs22.x runtime support both ESM and CJS. package.json "type" controls the default.
Edge Function formatESM only, with a runtime: "edge" export. No Node built-ins; restricted Web-API surface.
Next.js App RouterServer Components are ESM. Route Handlers detect ESM/CJS automatically.
Native modulesFunctions cannot ship native bindings beyond what's on the AWS Lambda base image. Audit any node-gyp deps before deploying.
Bundle size limit50 MB unzipped per Function (and 250 MB unzipped including layers). Vercel reports size at deploy; over-limit fails the upload.
Tree-shakingVercel'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.

ServicePurpose
Vercel BlobS3-style object storage with edge CDN. Pairs with @vercel/blob.
Vercel KVRedis-compatible KV (powered by Upstash). @vercel/kv.
Vercel PostgresNeon-backed serverless Postgres. @vercel/postgres.
Vercel Edge ConfigRead-only config replicated globally with sub-ms reads.
Marketplace integrationsSupabase, Neon, Upstash, MongoDB, Clerk, Auth0, Sentry, Resend, Stripe (provisioned via the Marketplace; env vars injected automatically).
Vercel AnalyticsFirst-party RUM (@vercel/analytics).
Speed InsightsCore Web Vitals tracking (@vercel/speed-insights).
AI SDK / AI Gatewayai package + Vercel AI Gateway for model routing.
Cron JobsScheduled Function invocations. Declared in vercel.json.
Workflows (WDK)Durable, pause/resume workflows on the Vercel platform.
Framework adapterNotes
nextFirst-class — Next.js is Vercel's framework.
@astrojs/vercelAstro SSR / static / edge adapter.
@sveltejs/adapter-vercelSvelteKit adapter.
nuxt (nitro-vercel)Built into Nitro.
@remix-run/vercelRemix 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

yaml
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:

ts
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 pull writes plaintext locally. The resulting .env.local is unencrypted. Add .env* to .gitignore and to your OS keychain integration if available.
  • vercel.json is 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 logs shows live request data. In some setups this includes auth headers or PII in URLs. Restrict access to team:read for 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 foundvercel 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 directoryvercel 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 use netlify-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 pull and 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 dev and vercel logs, but deploys live in IaC.
  • You self-host Next.js. next start on 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