---
title: How to add and manage environment variables on Vercel
description: Add environment variables to Vercel through the dashboard, CLI, or REST API, scope them to each environment, and pull them into local development.
url: /kb/guide/how-to-add-environment-variables-to-vercel
canonical_url: "https://vercel.com/kb/guide/how-to-add-environment-variables-to-vercel"
last_updated: 2026-07-27
authors: Vercel
related:
  - /docs/environment-variables
  - /docs/cli/env
  - /docs/deployments/environments
  - /docs/environment-variables/system-environment-variables
  - /docs/environment-variables/sensitive-environment-variables
  - /kb/bulletin/vercel-april-2026-security-incident
  - /docs/cli/pull
  - /docs/environment-variables/shared-environment-variables
  - /docs/limits
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

You add an [environment variable](https://vercel.com/docs/environment-variables) to a Vercel project in the dashboard, with the Vercel CLI, or through the REST API. Whichever method you use, the change takes effect on your next deployment, not on the deployment that's already live. After adding a variable, you scope it to Production, Preview, Development, or a custom environment, then pull the same values into local development so every environment runs the same configuration.

This guide covers each method, how scoping works, and the handful of behaviors that cause most environment variable bugs.

## How to add environment variables to Vercel

All three methods write to the same underlying store, so you can mix manual edits in the dashboard with automation without changing how deployments read the values. Start with the method that fits where the work belongs.

### Add variables in the dashboard

Open your project in the [Vercel dashboard](https://vercel.com/dashboard) and go to Environment Variables, add a key and value, and select the environments the variable applies to. Vercel encrypts values at rest, and anyone with access to the project can read non-sensitive values.

Integrations like Neon, Supabase, and Upstash add their own variables to your project settings, with the integration name shown next to each one. When you migrate from another platform, add variables in bulk instead of one at a time by pasting the contents of a `.env` file or uploading the file directly.

### Add variables with the Vercel CLI

The Vercel CLI manages variables from your terminal, which fits scripts and repeatable setup. The [\`vercel env\`](https://vercel.com/docs/cli/env) command group covers adding, updating, listing, removing, and pulling:

`vercel env add [name] [environment] [gitbranch] vercel env add [name] [environment] [gitbranch] < [file] vercel env update [name] [environment] vercel env rm [name] [environment] vercel env ls [environment] [gitbranch] vercel env pull [file]` `vercel env add` defaults to sensitive for Production, Preview, and custom environments. Pass `--no-sensitive` to store the value as encrypted instead, unless your team enforces the sensitive policy. Development variables stay encrypted because the API doesn't allow sensitive values there. ### Add variables with the REST API Automation and infrastructure-as-code setups provision variables programmatically through the REST API. Send a `POST` to the project's environment variables endpoint with a bearer token: `curl --request POST \ --url https://api.vercel.com/v10/projects/[idOrName]/env \ --header "Authorization: Bearer $VERCEL_TOKEN" \ --header "Content-Type: application/json" \ --data '[{ "key": "API_KEY", "value": "your_value_here", "type": "sensitive", "target": ["production"] }]'` Add `upsert=true` as a query parameter to update an existing variable instead of returning an error, and `teamId` or `slug` to scope the request to a team. ## Why Vercel environment variable changes need a new deployment Most environment variable bugs on Vercel come from one assumption, that changing a value takes effect right away the way it does on a long-running server that reads its config at startup. On Vercel, the change applies to the next deployment, and that behavior is deliberate. Each deployment is an immutable artifact. Its configuration is fixed at build time and doesn't shift afterward, which is what makes instant rollback safe. Rolling back points traffic at an older deployment whose values are exactly what they were when it shipped. Applying a variable change to existing deployments would break that guarantee, so a change requires a redeploy. `NEXT_PUBLIC_` variables make this concrete. Next.js [inlines them at build time](https://nextjs.org/docs/pages/guides/environment-variables), so a reference like `process.env.NEXT_PUBLIC_ANALYTICS_ID` becomes a hardcoded string in the JavaScript bundle sent to the browser. After the build, the app keeps that bundled value, and no runtime change can update it. Server-only variables differ in one way. Node.js functions read them at runtime through `process.env`, but they still take their values from the deployment that's running.

## How to scope environment variables to each environment

Every variable targets one or more environments, and the target decides which deployments can read it. Scope each variable deliberately so preview builds and production don't read each other's values. The three standard environments map to how a deployment is created:

| Environment | When it applies                                                      |
| ----------- | -------------------------------------------------------------------- |
| Production  | A push to the production branch (usually `main`), or `vercel --prod` |
| Preview     | A push to any non-production branch, or `vercel` without `--prod`    |
| Development | Local development through `vercel dev` or `vercel env pull`          |

A variable can target several environments at once, and you set the targets when you create it.

### Override preview values for a specific branch

A Preview variable can apply to every non-production branch or to one branch. Branch-specific values inherit the general Preview set, so you define only the values you want to override rather than duplicating the whole set for each branch. Managing branch-specific Preview variables from the CLI needs Vercel CLI 21.0.1 or higher.

### Use custom environments for staging or QA

[Custom environments](https://vercel.com/docs/deployments/environments) such as staging or QA are available on Pro and Enterprise plans. Pro allows one custom environment, and Enterprise allows up to 12. A custom environment can import variables from another environment to start, then diverge as its values change. Pull its values locally with `vercel pull --environment=staging`.

Environment-name branching has one trap. `VERCEL_ENV` returns `preview` for every [custom environment](https://vercel.com/docs/environment-variables/system-environment-variables), so it can't tell staging apart from a standard preview. Read `VERCEL_TARGET_ENV` instead, which returns `production`, `preview`, `development`, or the custom environment's actual name.

### Mark production secrets sensitive

All variables are encrypted, but [sensitive variables](https://vercel.com/docs/environment-variables/sensitive-environment-variables) can only be decrypted during builds. Once you create one, its value can no longer be read back from the dashboard or the CLI, and it stays readable only during a build. Sensitive applies to Production and Preview only, and `vercel env add` defaults to it for Production, Preview, and custom environments.

One limit affects short credentials. Build-log redaction replaces a sensitive value with `[REDACTED]` only when the value is 32 characters or longer, so shorter API keys need manual care to keep them out of logs. A team Owner can enforce this across the team. Under Settings then Security & Privacy, enabling the policy makes every new Production and Preview variable sensitive and blocks `--no-sensitive`. Enabling sensitive-by-default keeps secret values from being read back later. After the [April 2026 security incident](https://vercel.com/kb/bulletin/vercel-april-2026-security-incident), Vercel advised customers to rotate any secret values that were not marked sensitive.

## How to pull Vercel environment variables into local development

Local development reads from the same cloud-defined variables, so there's no separate `.env` file to maintain and drift out of sync. A new teammate pulls the current values with three commands:

`npm i -g vercel vercel link vercel env pull`

`vercel env pull` writes the Development variables to `.env.local` and adds `.env.local` to `.gitignore` automatically. To pull a different scope, name the environment:

`vercel env pull # Development to .env.local vercel env pull --environment=preview # Preview variables vercel env pull --environment=preview --git-branch=feature-branch # A specific branch vercel pull --environment=staging # A custom environment`

Use lowercase environment names in CLI commands (`production`, `preview`, `development`). Note that `vercel pull` and `vercel env pull` are [different commands](https://vercel.com/docs/cli/pull). `vercel env pull` writes a file for a framework dev server like `next dev`, while `vercel pull` caches both variables and project settings for `vercel build` or `vercel dev`.

`vercel dev` downloads Development variables into memory automatically, so it needs no file. When you want to avoid writing secrets to disk at all, `vercel env run` injects them straight into a command:

`vercel env run -e preview --git-branch feature-branch -- npm run dev`

The `--` separator passes everything after it to your command, so the variables reach the process without ever touching the file system.

## How to troubleshoot environment variables that aren't working

When a variable seems wrong, the cause is usually one of the five documented behaviors below. Work through the one that matches your symptom.

### A dashboard change hasn't taken effect

Environment variable changes apply to new deployments, so the running deployment keeps its old values. Trigger a new deployment with the Redeploy button (clear Use existing Build Cache), `vercel --force`, or by setting `VERCEL_FORCE_NO_BUILD_CACHE=1` as a project variable.

### A `NEXT_PUBLIC_` variable is undefined in the browser

Only variables prefixed with `NEXT_PUBLIC_` reach the client bundle, and Next.js inlines them at build time. Dynamic lookups like `process.env[name]` are never inlined, and an empty value reads as `undefined`. Prefix the variable, set it before the build runs, and redeploy. For values that must change without a rebuild, serve them from Edge Config or a runtime API instead. ### A preview deployment reads the wrong values Preview deployments only read variables scoped to Preview. Confirm the Preview target is selected under Settings then Environment Variables. For logic that branches on the environment name, switch from `VERCEL_ENV` to `VERCEL_TARGET_ENV` so custom environments resolve correctly. ### A Turborepo cache serves a build with the wrong values If `env` or `globalEnv` keys are missing from `turbo.json`, Turborepo leaves those values out of its task hash, so a cached build can be reused across environments. Declare `env` per task or `globalEnv` globally, and set `TURBO_FORCE=true` when you need to skip the cache. ### System variables are empty under `vercel dev` Deployment-specific system variables like `VERCEL_GIT_REPO_OWNER` are only set at deployment time, so they stay empty locally. Pull production or preview values with `vercel env pull --environment production`, and set any deployment-time values you need directly in `.env.local`. To confirm a fix, open the deployment in the dashboard and check its Environment. For `NEXT_PUBLIC_` values, inspect the browser bundle or log the value from a client component. For server-only variables, log from an API route and read the function logs. ## Next steps With your variables added and scoped, deploy a project to see them applied. [Start a new Vercel project](https://vercel.com/new) and set its variables in project settings, or [browse the templates](https://vercel.com/templates) for a framework-ready starting point.

## Related resources

- [Environment variables](https://vercel.com/docs/environment-variables)
  
- [Sensitive environment variables](https://vercel.com/docs/environment-variables/sensitive-environment-variables)
  
- [Shared environment variables](https://vercel.com/docs/environment-variables/shared-environment-variables)
  
- [System environment variables](https://vercel.com/docs/environment-variables/system-environment-variables)
  
- [vercel env CLI reference](https://vercel.com/docs/cli/env)
  
- [Vercel April 2026 security incident](https://vercel.com/kb/bulletin/vercel-april-2026-security-incident)
  

## Frequently asked questions

### Do I need to redeploy after adding an environment variable?

Yes. A new or changed environment variable takes effect on your next deployment, and existing deployments keep the values they were built with. Trigger a deployment with the Redeploy button, `vercel --force`, or a new push. Keeping deployments fixed this way is what makes rollbacks predictable.

### Can I use sensitive environment variables in local development?

No. Sensitive environment variables apply to Production and Preview only, because the Vercel API doesn't allow sensitive values in Development. When you run `vercel env pull`, sensitive values write a placeholder rather than the real value, so keep any local secrets in your own `.env.local` file.

### What is the maximum number of environment variables per project?

Each environment in a project can hold up to [1,000 environment variables](https://vercel.com/docs/limits). All variables in a deployment share a 64 KB total size limit for Node.js, Python, Ruby, Go, Java, and .NET runtimes, which is also the largest a single variable can be. For the Edge runtime, each variable is limited to 5 KB.

### How do I share one variable across multiple projects?

Create a [shared environment variable](https://vercel.com/docs/environment-variables/shared-environment-variables) in Team Settings and link it to each project, available on Pro and Enterprise plans. Updating the shared value updates every linked project. A project-level variable with the same key and environment overrides the shared one, and shared variables don't support branch-specific scoping.

### What happened to the vercel secrets command?

Vercel converted legacy secrets to sensitive environment variables on May 1, 2024, for Production and Preview environments, and Development secrets were not migrated. Use `vercel env add`, which defaults to sensitive for Production and Preview, or set `"type": "sensitive"` in the REST API to create protected values.