Prisma Next is in early access.Read the docs

Environment variables

Project configuration that gets injected into your deployments, scoped to production, preview, or a single branch.

Environment variables are project configuration that gets injected into your deployments. You scope each one to production, to preview, or to a single preview branch. This is also how you connect your app to a database: set its connection string as a variable like DATABASE_URL.

How it works

There are three layers:

  1. Production variables: used by production deploys.
  2. Preview variables: used by every preview deploy.
  3. Branch overrides: replace a preview value for one specific branch.
How a deploy composes its environment variablesStep 1 of 3
What you set, by scopeWhat each branch resolves toProduction--role productionDATABASE_URL…/prodPreview--role previewDATABASE_URL…/previewSTRIPE_KEYsk_test_…Branch override--branch feature/searchDATABASE_URL…/branch-dbFEATURE_FLAGonmainproduction deployDATABASE_URL…/prodfeature/searchpreview deployDATABASE_URL…/branch-dbSTRIPE_KEYsk_test_…FEATURE_FLAGonbug/fix-issuepreview deployDATABASE_URL…/previewSTRIPE_KEYsk_test_…from productionfrom previewfrom branch override
Your default branch deploys as production, and resolves to the production variables only. Nothing else is mixed in.

A preview deploy gets the preview variables, with any branch overrides layered on top. Overrides help when one branch needs a different API key, database URL, or feature flag than the rest.

Values are resolved at deploy time and baked into the deployment. Changing a variable doesn't touch deployments that already exist and doesn't trigger a redeploy; the new value applies the next time you deploy.

Set a variable

Pass KEY=value and a role or branch:

bunx @prisma/cli@latest project env add DATABASE_URL=postgresql://example --role production
bunx @prisma/cli@latest project env add DATABASE_URL=postgresql://preview --role preview
bunx @prisma/cli@latest project env add FEATURE_FLAG=enabled --branch feature/search

To keep a secret out of your shell history, pass just the key and let the CLI read it from your environment:

DATABASE_URL=postgresql://example npx @prisma/cli@latest project env add DATABASE_URL --role production

To import many variables at once, pass a dotenv file with --file instead of a KEY=value argument (one or the other, not both). It works for add and update:

bunx @prisma/cli@latest project env add --file .env.production --role production

Connect a database

To give your app a database, set its connection string per scope, then redeploy. Use a different database per scope if you want preview deployments isolated from production data.

List, update, remove

bunx @prisma/cli@latest project env list --role production
bunx @prisma/cli@latest project env list --branch feature/search
bunx @prisma/cli@latest project env update DATABASE_URL=postgresql://new --role production
bunx @prisma/cli@latest project env remove DATABASE_URL --role preview

list --role shows names and metadata, never values. list --branch shows the resolved view for one branch. rm works as an alias for remove.

add never overwrites: it fails if the key already exists in that scope, so use update to change a value. Every project env subcommand also accepts --project <id-or-name> to target a project other than the linked one.

Values are write-only

Once you save a variable, the platform never gives it back. Values are encrypted at rest and never returned: not by the CLI, the API, or the Console. In practice:

  • project env list shows keys and metadata, not values.
  • There's no command to pull values into a local .env.
  • To rotate a secret, project env update it and redeploy.
  • To confirm an app sees a value, redeploy and check its behavior or logs.

Keep your own copy of every value in a secret manager. Treat Prisma as the place values are injected, not a store you read back from.

Rules

  • Keys must match [A-Z_][A-Z0-9_]*, up to 256 characters.
  • Values must be non-empty, up to 8 KB.
  • Production variables can't be branch-scoped: use --role production for production, and --branch <name> only for preview overrides.

In CI and agents

Add --json so the output is machine-readable, and --no-interactive so the CLI fails with an error code instead of waiting on a prompt nothing will answer:

bunx @prisma/cli@latest project env list --role preview --json --no-interactive

Don't build anything that depends on reading a value back. Pass the source value in from your own secret store, and let Prisma handle injection at deploy time.

Next steps

On this page