Next.js

Use Dotenvx with Next.js.

Install

In your Next.js project, install Dotenvx and @dotenvx/next-env.

$ npm install @dotenvx/dotenvx
$ npm install @dotenvx/next-env

Add this override to your package.json:

{
  "overrides": {
    "@next/env": "npm:@dotenvx/next-env"
  }
}

Apply it:

$ npm install

Next.js now loads encrypted secrets automatically through @dotenvx/next-env.

Encrypt

Start with a secret value in the .env file at your project root, like:

# .env
HELLO="Secret"

Encrypt it with a single command.

$ npx dotenvx encrypt
◈ encrypted (.env)

The values become ciphertext and only your private key can unlock them.

# .env
DOTENV_PUBLIC_KEY="0220d830351410598be484f43a7b07097e09851f50426832876e8b5815a1752990"

HELLO="encrypted:BHLTACNJMr00nTG6yXpkCyWFKF/MY0ajN855tg3uVtKopTe2AGzSkQlcPd21pTOT3Ci8IKrdIg2TMZFoq1mDR6yb06QCRvqHXtpkZkAHYCEHfeWqqC8tMFovcYq5JS2uZSrC/qUGDA=="

Commit

Commit your encrypted .env files with your code. It's safe. Now you can securely share secrets through git. Keep .env.keys out of git. The -f flag adds the encrypted file even if your Next.js project ignores .env files.

$ git add -f .env
$ git commit -m "encrypt .env"

Ship

Read your secrets through process.env. Create src/app/api/hello/route.js (or app/api/hello/route.js if your project does not use src/):

// src/app/api/hello/route.js
export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'

export async function GET() {
  return new Response(`Hello ${process.env.HELLO}`)
}

Run your app:

$ npx next dev
⟐ injected env (2) from .env

Visit /api/hello to see Hello Secret.

Next.js loads and decrypts .env before your server code reads process.env.

Seeing encrypted text instead of Hello Secret?

Next.js may still be using the original @next/env package, even after adding the override. Check which package is installed:

$ npm ls @next/env

The output should show @next/env as an alias of @dotenvx/next-env. An original Next.js version followed by “overridden” does not mean the replacement was installed.

If the original package is still installed, stop the dev server with Ctrl+C. From your project directory, rebuild the dependency installation:

$ rm -rf node_modules package-lock.json
$ npm install
$ npm ls @next/env

Confirm the alias now points to @dotenvx/next-env, then restart:

$ npx next dev

Refresh /api/hello. Review the regenerated package-lock.json before committing, since reinstalling can update dependency versions.

Deploy

Find your private key with the keypair command.

$ npx dotenvx keypair
{"DOTENV_PUBLIC_KEY":"0220d830351410598be484f43a7b07097e09851f50426832876e8b5815a1752990","DOTENV_PRIVATE_KEY":"b37dbad0e00206f31486c4f44f8cc7abf2f1be96d5ba352eb791122b5e131bbf"}

Deploy your code and encrypted .env file, install your npm dependencies, and set DOTENV_PRIVATE_KEY in your hosting platform's environment variables. Make it available during both build and runtime. On Vercel, select the environments you deploy to. Keep .env.keys on your local machine.

Build and run your app:

$ npx next build
$ npx next start

Your app reads the same secrets, but this time with the private key stored in your hosting environment.

Production

Give production its own secrets by creating a .env.production file:

# .env.production
HELLO="Production"

Encrypt it:

$ npx dotenvx encrypt -f .env.production
◈ encrypted (.env.production)

Commit it:

$ git add -f .env.production
$ git commit -m "encrypt .env.production"

Find the matching private key with npx dotenvx keypair -f .env.production. Set it as DOTENV_PRIVATE_KEY and set DOTENV_FILE to .env.production in your hosting platform's environment variables for both build and runtime.

Build and run it:

$ npx next build
$ npx next start

Next.js automatically loads .env.production for next build and next start. Visit /api/hello to see Hello Production. Same code, production secrets.

Next.js also loads .env as a fallback. If it uses a different encryption key, supply that key as DOTENV_PRIVATE_KEY_2.

Conclusion

You've encrypted a .env file, committed it to git, and loaded its secrets through Next.js with @dotenvx/next-env. You've also learned how to set a private key on your server and load different secrets for production without changing your code.

Your encrypted secrets now travel with your code. Set the matching keys in your hosting environment, and Next.js handles loading them.