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.