@dotenvx/dotenvx v1.44.2
a better dotenv–from the creator of dotenv.
- run anywhere (cross-platform)
- multi-environment
- encrypted envs
Quickstart

Install and use it in code just like dotenv.
npm install @dotenvx/dotenvx --save// index.js
require('@dotenvx/dotenvx').config()
// or import '@dotenvx/dotenvx/config' // for esm
console.log(`Hello ${process.env.HELLO}`)
or install globally - unlocks dotenv for any language, framework, or platform!
curl -sfS https://dotenvx.sh | sh
dotenvx help
brew install dotenvx/brew/dotenvx
dotenvx help
docker run -it --rm -v $(pwd):/app dotenv/dotenvx help
curl -L -o dotenvx.tar.gz "https://github.com/dotenvx/dotenvx/releases/latest/download/dotenvx-$(uname -s)-$(uname -m).tar.gz"
tar -xzf dotenvx.tar.gz
./dotenvx help
winget install dotenvx
dotenvx help
Run Anywhere
$ echo "HELLO=World" > .env
$ echo "console.log('Hello ' + process.env.HELLO)" > index.js
$ node index.js
Hello undefined # without dotenvx
$ dotenvx run -- node index.js
Hello World # with dotenvx
> :-DMore examples
// package.json { "type": "module", "dependencies": { "chalk": "^5.3.0" } }// index.ts import chalk from 'chalk' console.log(chalk.blue(`Hello ${process.env.HELLO}`))$ npm install $ echo "HELLO=World" > .env $ dotenvx run -- npx tsx index.ts Hello World$ echo "HELLO=World" > .env $ echo "console.log('Hello ' + Deno.env.get('HELLO'))" > index.ts $ deno run --allow-env index.ts Hello undefined $ dotenvx run -- deno run --allow-env index.ts Hello World!WARNING Some of you are attempting to use the npm module directly with
deno run. Don't, because deno currently has incomplete support for these encryption ciphers.$ deno run -A npm:@dotenvx/dotenvx encrypt Unknown cipherInstead, use
dotenvxas designed, by installing the cli as a binary - via curl, brew, etc.$ echo "HELLO=Test" > .env.test $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ bun index.js Hello undefined $ dotenvx run -f .env.test -- bun index.js Hello Test$ echo "HELLO=World" > .env $ echo 'import os;print("Hello " + os.getenv("HELLO", ""))' > index.py $ dotenvx run -- python3 index.py Hello World$ echo "HELLO=World" > .env $ echo '<?php echo "Hello {$_SERVER["HELLO"]}\n";' > index.php $ dotenvx run -- php index.php Hello World$ echo "HELLO=World" > .env $ echo 'puts "Hello #{ENV["HELLO"]}"' > index.rb $ dotenvx run -- ruby index.rb Hello World$ echo "HELLO=World" > .env $ echo 'package main; import ("fmt"; "os"); func main() { fmt.Printf("Hello %s\n", os.Getenv("HELLO")) }' > main.go $ dotenvx run -- go run main.go Hello World$ echo "HELLO=World" > .env $ echo 'fn main() {let hello = std::env::var("HELLO").unwrap_or("".to_string());println!("Hello {hello}");}' > src/main.rs $ dotenvx run -- cargo run Hello World$ echo "HELLO=World" > .env $ echo 'public class Index { public static void main(String[] args) { System.out.println("Hello " + System.getenv("HELLO")); } }' > index.java $ dotenvx run -- java index.java Hello World$ echo "HELLO=World" > .env $ echo '(println "Hello" (System/getenv "HELLO"))' > index.clj $ dotenvx run -- clojure -M index.clj Hello World$ echo "HELLO=World" > .env $ echo 'fun main() { val hello = System.getenv("HELLO") ?: ""; println("Hello $hello") }' > index.kt $ kotlinc index.kt -include-runtime -d index.jar $ dotenvx run -- java -jar index.jar Hello World$ dotnet new console -n HelloWorld -o HelloWorld $ cd HelloWorld $ echo "HELLO=World" | Out-File -FilePath .env -Encoding utf8 $ echo 'Console.WriteLine($"Hello {Environment.GetEnvironmentVariable("HELLO")}");' > Program.cs $ dotenvx run -- dotnet run Hello World$ echo "HELLO=World" > .env $ dotenvx run --quiet -- sh -c 'echo Hello $HELLO' Hello World$ echo "HELLO=World" > .env $ dotenvx run --quiet -- sh -c 'echo Hello $HELLO' Hello World# run every day at 8am 0 8 * * * dotenvx run -- /path/to/myscript.sh$ dotenvx run -- next dev $ dotenvx run -- npm start $ dotenvx run -- bin/rails s $ dotenvx run -- php artisan servesee framework guides
$ docker run -it --rm -v $(pwd):/app dotenv/dotenvx run -- node index.jsOr in any image:
FROM node:latest RUN echo "HELLO=World" > .env && echo "console.log('Hello ' + process.env.HELLO)" > index.js RUN curl -fsS https://dotenvx.sh/install.sh | sh CMD ["dotenvx", "run", "--", "echo", "Hello $HELLO"]see docker guide
name: build on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: curl -fsS https://dotenvx.sh/install.sh | sh - run: dotenvx run -- node build.js env: DOTENV_KEY: ${{ secrets.DOTENV_KEY }}# heroku heroku buildpacks:add https://github.com/dotenvx/heroku-buildpack-dotenvx # docker RUN curl -fsS https://dotenvx.sh/install.sh | sh # vercel npm install @dotenvx/dotenvx --savesee platform guides
// pm2 "scripts": { "start": "dotenvx run -- pm2-runtime start ecosystem.config.js --env production" },# alternatively use npx $ npx @dotenvx/dotenvx run -- node index.js $ npx @dotenvx/dotenvx run -- next dev $ npx @dotenvx/dotenvx run -- npm start$ npm install @dotenvx/dotenvx --save{ "scripts": { "start": "./node_modules/.bin/dotenvx run -- node index.js" }, "dependencies": { "@dotenvx/dotenvx": "^0.5.0" } }$ npm run start > start > ./node_modules/.bin/dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (1) from .env.production Hello World# use dotenvx with asdf $ asdf plugin add dotenvx $ asdf install dotenvx latestthank you @jgburet of Paris 🇫🇷
# use as a git submodule $ git dotenvx run -- node index.js $ git dotenvx run -- next dev $ git dotenvx run -- npm startReference and expand variables already on your machine for use in your .env file.
# .env USERNAME="username" DATABASE_URL="postgres://${USERNAME}@localhost/my_database"// index.js console.log('DATABASE_URL', process.env.DATABASE_URL)$ dotenvx run --debug -- node index.js [dotenvx@0.14.1] injecting env (2) from .env DATABASE_URL postgres://username@localhost/my_databaseAdd the output of a command to one of your variables in your .env file.
# .env DATABASE_URL="postgres://$(whoami)@localhost/my_database"// index.js console.log('DATABASE_URL', process.env.DATABASE_URL)$ dotenvx run --debug -- node index.js [dotenvx@0.14.1] injecting env (1) from .env DATABASE_URL postgres://yourusername@localhost/my_database
Multiple Environments
Create a
.env.productionfile and use-fto load it. It's straightforward, yet flexible.$ echo "HELLO=production" > .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
$ dotenvx run -f .env.production -- node index.js dotenvx@1.X.X injecting env (1) from .env.production Hello production
^^
More examples
$ echo "HELLO=local" > .env.local $ echo "HELLO=World" > .env $ dotenvx run -f .env.local -f .env -- node index.js [dotenvx@1.X.X] injecting env (1) from .env.local,.env Hello localNote subsequent files do NOT override pre-existing variables defined in previous files or env. This follows historic principle. For example, above
localwins – from the first file.$ echo "HELLO=local" > .env.local $ echo "HELLO=World" > .env $ dotenvx run -f .env.local -f .env --overload -- node index.js [dotenvx@1.X.X] injecting env (1) from .env.local,.env Hello WorldNote that with
--overloadsubsequent files DO override pre-existing variables defined in previous files.$ echo "HELLO=production" > .env.production $ dotenvx run -f .env.production --verbose -- node index.js [dotenvx][verbose] injecting env from /path/to/.env.production [dotenvx][verbose] HELLO set [dotenvx@1.X.X] injecting env (1) from .env.production Hello production$ echo "HELLO=production" > .env.production $ dotenvx run -f .env.production --debug -- node index.js [dotenvx][debug] configuring options [dotenvx][debug] {"envFile":[".env.production"]} [dotenvx][verbose] injecting env from /path/to/.env.production [dotenvx][debug] reading env from /path/to/.env.production [dotenvx][debug] parsing env from /path/to/.env.production [dotenvx][debug] {"HELLO":"production"} [dotenvx][debug] writing env from /path/to/.env.production [dotenvx][verbose] HELLO set [dotenvx][debug] HELLO set to production [dotenvx@1.X.X] injecting env (1) from .env.production Hello productionUse
--quietto suppress all output (except errors).$ echo "HELLO=production" > .env.production $ dotenvx run -f .env.production --quiet -- node index.js Hello productionSet
--log-levelto whatever you wish. For example, to suppress warnings (risky), set log level toerror:$ echo "HELLO=production" > .env.production $ dotenvx run -f .env.production --log-level=error -- node index.js Hello productionAvailable log levels are
error, warn, info, verbose, debug, sillyLoad envs using Next.js' convention or dotenv-flow convention. Set
--conventiontonextjsorflow:$ echo "HELLO=development local" > .env.development.local $ echo "HELLO=local" > .env.local $ echo "HELLO=development" > .env.development $ echo "HELLO=env" > .env $ dotenvx run --convention=nextjs -- node index.js Hello development local $ dotenvx run --convention=flow -- node index.js Hello development local(more conventions available upon request)
Encryption
Add encryption to your
.envfiles with a single command. Usedotenvx encrypt.
$ dotenvx encrypt
✔ encrypted (.env)A
DOTENV_PUBLIC_KEY(encryption key) and aDOTENV_PRIVATE_KEY(decryption key) are generated using the same public-key cryptography as Bitcoin.
More examples
$ echo "HELLO=World" > .env $ dotenvx encrypt $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (2) from .env Hello World$ echo "HELLO=Production" > .env.production $ dotenvx encrypt -f .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (2) from .env.production Hello ProductionNote the
DOTENV_PRIVATE_KEY_PRODUCTIONends with_PRODUCTION. This instructsdotenvx runto load the.env.productionfile.$ echo "HELLO=Ci" > .env.ci $ dotenvx encrypt -f .env.ci $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ DOTENV_PRIVATE_KEY_CI="<.env.ci private key>" dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (2) from .env.ci Hello CiNote the
DOTENV_PRIVATE_KEY_CIends with_CI. This instructsdotenvx runto load the.env.cifile. See the pattern?$ dotenvx set HELLO World -f .env $ dotenvx set HELLO Production -f .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ DOTENV_PRIVATE_KEY="<.env private key>" DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (3) from .env, .env.production Hello WorldNote the
DOTENV_PRIVATE_KEYinstructsdotenvx runto load the.envfile and theDOTENV_PRIVATE_KEY_PRODUCTIONinstructs it to load the.env.productionfile. See the pattern?$ mkdir app1 $ mkdir app2 $ dotenvx set HELLO app1 -f app1/.env.ci $ dotenvx set HELLO app2 -f app2/.env.ci $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ DOTENV_PRIVATE_KEY_CI="<app1/privat ci key>,<app2/private ci key>" dotenvx run -f app1/.env.ci -f app2/.env.ci -- node index.js [dotenvx@1.X.X] injecting env (2) from app1/.env.ci,app2/.env.ci Hello app1 $ DOTENV_PRIVATE_KEY_CI="<app1/privat ci key>,<app2/private ci key>" dotenvx run -f app1/.env.ci -f app2/.env.ci --overload -- node index.js [dotenvx@1.X.X] injecting env (2) from app1/.env.ci,app2/.env.ci Hello app2Note the
DOTENV_PRIVATE_KEY_CI(and anyDOTENV_PRIVATE_KEY*) can take multiple private keys by simply comma separating them.$ echo "HELLO=World" > .env $ dotenvx encrypt --stdout $ dotenvx encrypt --stdout > .env.encryptedsecp256k1is a well-known and battle tested curve, in use with Bitcoin and other cryptocurrencies, but we are open to adding support for more curves.If your organization's compliance department requires NIST approved curves or other curves like
curve25519, please reach out at security@dotenvx.com.
Advanced
Become a
dotenvxpower user.
CLI 📟
Advanced CLI commands.
Reference and expand variables already on your machine for use in your .env file.
# .env USERNAME="username" DATABASE_URL="postgres://${USERNAME}@localhost/my_database"// index.js console.log('DATABASE_URL', process.env.DATABASE_URL)$ dotenvx run --debug -- node index.js [dotenvx@1.X.X] injecting env (2) from .env DATABASE_URL postgres://username@localhost/my_databaseAdd the output of a command to one of your variables in your .env file.
# .env DATABASE_URL="postgres://$(whoami)@localhost/my_database"// index.js console.log('DATABASE_URL', process.env.DATABASE_URL)$ dotenvx run --debug -- node index.js [dotenvx@1.X.X] injecting env (1) from .env DATABASE_URL postgres://yourusername@localhost/my_databasePrevent your shell from expanding inline
$VARIABLESbefore dotenvx has a chance to inject it. Use a subshell.$ dotenvx run --env="HELLO=World" -- sh -c 'echo Hello $HELLO' Hello WorldDotenvx supports multiline values. This is particularly useful in conjunction with Docker - which does not support multiline values.
# .env MULTILINE_PEM="-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/ bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/ kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V u4QuUoobAgMBAAE= -----END PUBLIC KEY-----"// index.js console.log('MULTILINE_PEM', process.env.MULTILINE_PEM)$ dotenvx run -- node index.js MULTILINE_PEM -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/ bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/ kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V u4QuUoobAgMBAAE= -----END PUBLIC KEY-----Unlike other dotenv libraries, dotenvx attempts to unblock you with contextual help.
For example, when missing a custom .env file:
$ dotenvx run -f .env.missing -- echo $HELLO [MISSING_ENV_FILE] missing .env.missing file (/Users/scottmotte/Code/dotenvx/playground/apr-16/.env.missing) [MISSING_ENV_FILE] https://github.com/dotenvx/dotenvx/issues/484 and re-run [dotenvx run -- echo]or when missing a KEY:
$ echo "HELLO=World" > .env $ dotenvx get GOODBYE [MISSING_KEY] missing GOODBYE keyCompose multiple
.envfiles for environment variables loading, as you need.$ echo "HELLO=local" > .env.local $ echo "HELLO=World" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -f .env.local -f .env -- node index.js [dotenvx@1.X.X] injecting env (1) from .env.local, .env Hello localNote subsequent files do NOT override pre-existing variables defined in previous files or env. This follows historic principle. For example, above
localwins – from the first file.Set environment variables as a simple
KEY=valuestring pair.$ echo "HELLO=World" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run --env HELLO=String -f .env -- node index.js [dotenvx@1.X.X] injecting env (1) from .env, and --env flag Hello StringOverride existing env variables. These can be variables already on your machine or variables loaded as files consecutively. The last variable seen will 'win'.
$ echo "HELLO=local" > .env.local $ echo "HELLO=World" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -f .env.local -f .env --overload -- node index.js [dotenvx@1.X.X] injecting env (1) from .env.local, .env Hello WorldNote that with
--overloadsubsequent files DO override pre-existing variables defined in previous files.Decrypt your encrypted
.envby settingDOTENV_PRIVATE_KEYbeforedotenvx run.$ touch .env $ dotenvx set HELLO encrypted $ echo "console.log('Hello ' + process.env.HELLO)" > index.js # check your .env.keys files for your privateKey $ DOTENV_PRIVATE_KEY="122...0b8" dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (2) from .env Hello encryptedDecrypt your encrypted
.env.productionby settingDOTENV_PRIVATE_KEY_PRODUCTIONbeforedotenvx run. Alternatively, this can be already set on your server or cloud provider.$ touch .env.production $ dotenvx set HELLO "production encrypted" -f .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js # check .env.keys for your privateKey $ DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (2) from .env.production Hello production encryptedNote the
DOTENV_PRIVATE_KEY_PRODUCTIONends with_PRODUCTION. This instructs dotenvx run to load the.env.productionfile.Decrypt your encrypted
.env.ciby settingDOTENV_PRIVATE_KEY_CIbeforedotenvx run. Alternatively, this can be already set on your server or cloud provider.$ touch .env.ci $ dotenvx set HELLO "ci encrypted" -f .env.ci $ echo "console.log('Hello ' + process.env.HELLO)" > index.js # check .env.keys for your privateKey $ DOTENV_PRIVATE_KEY_CI="122...0b8" dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (2) from .env.ci Hello ci encryptedNote the
DOTENV_PRIVATE_KEY_CIends with_CI. This instructs dotenvx run to load the.env.cifile. See the pattern?Decrypt your encrypted
.envand.env.productionfiles by settingDOTENV_PRIVATE_KEYandDOTENV_PRIVATE_KEY_PRODUCTIONbeforedotenvx run.$ touch .env $ touch .env.production $ dotenvx set HELLO encrypted $ dotenvx set HELLO "production encrypted" -f .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js # check .env.keys for your privateKeys $ DOTENV_PRIVATE_KEY="122...0b8" DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (3) from .env, .env.production Hello encrypted $ DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" DOTENV_PRIVATE_KEY="122...0b8" dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (3) from .env.production, .env Hello production encryptedCompose any encrypted files you want this way. As long as a
DOTENV_PRIVATE_KEY_${environment}is set, the values from.env.${environment}will be decrypted at runtime.Set log level to
verbose. (log levels)$ echo "HELLO=production" > .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -f .env.production --verbose -- node index.js loading env from .env.production (/path/to/.env.production) HELLO set [dotenvx@1.X.X] injecting env (1) from .env.production Hello productionSet log level to
debug. (log levels)$ echo "HELLO=production" > .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -f .env.production --debug -- node index.js process command [node index.js] options: {"env":[],"envFile":[".env.production"]} loading env from .env.production (/path/to/.env.production) {"HELLO":"production"} HELLO set HELLO set to production [dotenvx@1.X.X] injecting env (1) from .env.production executing process command [node index.js] expanding process command to [/opt/homebrew/bin/node index.js] Hello productionUse
--quietto suppress all output (except errors). (log levels)$ echo "HELLO=production" > .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -f .env.production --quiet -- node index.js Hello productionSet
--log-levelto whatever you wish. For example, to suppress warnings (risky), set log level toerror:$ echo "HELLO=production" > .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -f .env.production --log-level=error -- node index.js Hello productionAvailable log levels are
error, warn, info, verbose, debug, silly(source)Exit with code
1if any errors are encountered - like a missing .env file or decryption failure.$ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -f .env.missing --strict -- node index.js [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing) [MISSING_ENV_FILE] ? add one with [echo "HELLO=World" > .env.missing]This can be useful in
ciscripts where you want to fail the ci if your.envfile could not be decrypted at runtime.Ignore errors like
MISSING_ENV_FILE.$ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -f .env.missing --ignore=MISSING_ENV_FILE -- node index.js ...Load envs using Next.js' convention. Set
--conventiontonextjs:$ echo "HELLO=development local" > .env.development.local $ echo "HELLO=local" > .env.local $ echo "HELLO=development" > .env.development $ echo "HELLO=env" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run --convention=nextjs -- node index.js [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.local, .env.development, .env Hello development local(more conventions available upon request)
Load envs using dotenv-flow's convention. Set
--conventiontoflow:$ echo "HELLO=development local" > .env.development.local $ echo "HELLO=development" > .env.development $ echo "HELLO=local" > .env.local $ echo "HELLO=env" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ NODE_ENV=development dotenvx run --convention=flow -- node index.js [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.development, .env.local, .env Hello development localFurther, we recommend using
DOTENV_ENVoverNODE_ENV– asdotenvxworks everywhere, not just node.$ DOTENV_ENV=development dotenvx run --convention=flow -- node index.js [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.development, .env.local, .env Hello development localSpecify path to
.env.keys. This is useful with monorepos.$ mkdir -p apps/app1 $ touch apps/app1/.env $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env $ dotenvx run -fk .env.keys -f apps/app1/.env -- yourcommandReturn a single environment variable's value.
$ echo "HELLO=World" > .env $ dotenvx get HELLO WorldReturn a single environment variable's value from a specific
.envfile.$ echo "HELLO=World" > .env $ echo "HELLO=production" > .env.production $ dotenvx get HELLO -f .env.production productionSpecify path to
.env.keys. This is useful with monorepos.$ mkdir -p apps/app1 $ touch apps/app1/.env $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env $ dotenvx get HELLO -fk .env.keys -f apps/app1/.env worldReturn a single environment variable's value from a
--envstring.$ dotenvx get HELLO --env HELLO=String -f .env.production StringReturn a single environment variable's value where each found value is overloaded.
$ echo "HELLO=World" > .env $ echo "HELLO=production" > .env.production $ dotenvx get HELLO -f .env.production --env HELLO=String -f .env --overload WorldExit with code
1if any errors are encountered - like a missing key, missing .env file, or decryption failure.$ dotenvx get DOES_NOT_EXIST --strict [MISSING_KEY] missing DOES_NOT_EXIST keyReturn a single environment variable's value using Next.js' convention. Set
--conventiontonextjs:$ echo "HELLO=development local" > .env.development.local $ echo "HELLO=local" > .env.local $ echo "HELLO=development" > .env.development $ echo "HELLO=env" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx get HELLO --convention=nextjs development localReturn a single environment variable's value using dotenv-flow's convention. Set
--conventiontoflow:$ echo "HELLO=development local" > .env.development.local $ echo "HELLO=development" > .env.development $ echo "HELLO=local" > .env.local $ echo "HELLO=env" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ NODE_ENV=development dotenvx get HELLO --convention=flow development localFurther, we recommend using
DOTENV_ENVoverNODE_ENV– asdotenvxworks everywhere, not just node.$ DOTENV_ENV=development dotenvx get HELLO --convention=flow development localReturn a json response of all key/value pairs in a
.envfile.$ echo "HELLO=World" > .env $ dotenvx get {"HELLO":"World"}Return a shell formatted response of all key/value pairs in a
.envfile.$ echo "HELLO=World" > .env $ echo "KEY=value" >> .env $ dotenvx get --format shell HELLO=World KEY=valueThis can be useful when combined with
envon the command line.$ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js $ env $(dotenvx get --format=shell) node index.js Hello value Worldor with
export.$ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js $ export $(dotenvx get --format=shell) $ node index.js Hello value WorldReturn an
eval-ready shell formatted response of all key/value pairs in a.envfile.$ echo "HELLO=World" > .env $ echo "KEY=value" >> .env $ dotenvx get --format eval HELLO="World" KEY="value"Note that this exports newlines and quoted strings.
This can be useful for more complex .env values (spaces, escaped characters, quotes, etc) combined with
evalon the command line.$ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js $ eval $(dotenvx get --format=eval) node index.js Hello value WorldBe careful with
evalas it allows for arbitrary execution of commands. Preferdotenvx run --but in some casesevalis a sharp knife that is useful to have.Return preset machine envs as well.
$ echo "HELLO=World" > .env $ dotenvx get --all {"PWD":"/some/file/path","USER":"username","LIBRARY_PATH":"/usr/local/lib", ..., "HELLO":"World"}Make the output more readable - pretty print it.
$ echo "HELLO=World" > .env $ dotenvx get --all --pretty-print { "PWD": "/some/filepath", "USER": "username", "LIBRARY_PATH": "/usr/local/lib", ..., "HELLO": "World" }Set an encrypted key/value (on by default).
$ touch .env $ dotenvx set HELLO World set HELLO with encryption (.env)Set an (encrypted) key/value for another
.envfile.$ touch .env.production $ dotenvx set HELLO production -f .env.production set HELLO with encryption (.env.production)Specify path to
.env.keys. This is useful with monorepos.$ mkdir -p apps/app1 $ touch apps/app1/.env $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env set HELLO with encryption (.env)Put it to use.
$ dotenvx get -fk .env.keys -f apps/app1/.envUse it with a relative path.
$ cd apps/app1 $ dotenvx get -fk ../../.env.keys -f .envSet a value containing spaces.
$ touch .env.ci $ dotenvx set HELLO "my ci" -f .env.ci set HELLO with encryption (.env.ci)If your value starts with a dash (
-), then place two dashes instructing the cli that there are no more flag arguments.$ touch .env.ci $ dotenvx set HELLO -f .env.ci -- "- + * ÷" set HELLO with encryption (.env.ci)Set a plaintext key/value.
$ touch .env $ dotenvx set HELLO World --plain set HELLO (.env)Encrypt the contents of a
.envfile to an encrypted.envfile.$ echo "HELLO=World" > .env $ dotenvx encrypt ✔ encrypted (.env) ✔ key added to .env.keys (DOTENV_PRIVATE_KEY) ⮕ next run [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys ⮕ next run [DOTENV_PRIVATE_KEY='122...0b8' dotenvx run -- yourcommand] to test decryption locallyEncrypt the contents of a specified
.envfile to an encrypted.envfile.$ echo "HELLO=World" > .env $ echo "HELLO=Production" > .env.production $ dotenvx encrypt -f .env.production ✔ encrypted (.env.production) ✔ key added to .env.keys (DOTENV_PRIVATE_KEY_PRODUCTION) ⮕ next run [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys ⮕ next run [DOTENV_PRIVATE_KEY='bff...bc4' dotenvx run -- yourcommand] to test decryption locallySpecify path to
.env.keys. This is useful with monorepos.$ mkdir -p apps/app1 $ echo "HELLO=World" > apps/app1/.env $ dotenvx encrypt -fk .env.keys -f apps/app1/.env ✔ encrypted (apps/app1/.env)Put it to use.
$ dotenvx run -fk .env.keys -f apps/app1/.envUse with a relative path.
$ cd apps/app1 $ dotenvx run -fk ../../.env.keys -f .envSpecify the key(s) to encrypt by passing
--key.$ echo "HELLO=World\nHELLO2=Universe" > .env $ dotenvx encrypt -k HELLO2 ✔ encrypted (.env)Even specify a glob pattern.
$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt -k "HE*" ✔ encrypted (.env)Specify the key(s) to NOT encrypt by passing
--exclude-key.$ echo "HELLO=World\nHELLO2=Universe" > .env $ dotenvx encrypt -ek HELLO ✔ encrypted (.env)Even specify a glob pattern.
$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt -ek "HO*" ✔ encrypted (.env)Encrypt the contents of a
.envfile and send to stdout.$ echo "HELLO=World" > .env $ dotenvx encrypt --stdout #/-------------------[DOTENV_PUBLIC_KEY]--------------------/ #/ public-key encryption for .env files / #/ [how it works](https://dotenvx.com/encryption) / #/----------------------------------------------------------/ DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45" # .env HELLO="encrypted:BDqDBibm4wsYqMpCjTQ6BsDHmMadg9K3dAt+Z9HPMfLEIRVz50hmLXPXRuDBXaJi/LwWYEVUNiq0HISrslzQPaoyS8Lotg3gFWJTsNCdOWnqpjF2xNUX2RQiP05kAbEXM6MWVjDr"or send to a file:
$ echo "HELLO=World" > .env $ dotenvx encrypt --stdout > somefile.txtDecrypt the contents of an encrypted
.envfile to an unencrypted.envfile.$ echo "HELLO=World" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx decrypt ✔ decrypted (.env)Decrypt the contents of a specified encrypted
.envfile to an unencrypted.envfile.$ echo "HELLO=World" > .env $ echo "HELLO=Production" > .env.production $ dotenvx encrypt -f .env.production ✔ encrypted (.env.production) $ dotenvx decrypt -f .env.production ✔ decrypted (.env.production)Specify path to
.env.keys. This is useful with monorepos.$ mkdir -p apps/app1 $ echo "HELLO=World" > apps/app1/.env $ dotenvx encrypt -fk .env.keys -f apps/app1/.env ✔ encrypted (apps/app1/.env) $ dotenvx decrypt -fk .env.keys -f apps/app1/.env ✔ decrypted (apps/app1/.env)Decrypt the contents of a specified key inside an encrypted
.envfile.$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx decrypt -k HELLO ✔ decrypted (.env)Even specify a glob pattern.
$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx decrypt -k "HE*" ✔ encrypted (.env)Decrypt the contents inside an encrypted
.envfile except for an excluded key.$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx decrypt -ek HOLA ✔ decrypted (.env)Even specify a glob pattern.
$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx decrypt -ek "HO*" ✔ encrypted (.env)Decrypt the contents of an encrypted
.envfile and send to stdout.$ dotenvx decrypt --stdout #/-------------------[DOTENV_PUBLIC_KEY]--------------------/ #/ public-key encryption for .env files / #/ [how it works](https://dotenvx.com/encryption) / #/----------------------------------------------------------/ DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45" # .env HELLO="World"or send to a file:
$ dotenvx decrypt --stdout > somefile.txtPrint public/private keys for
.envfile.$ echo "HELLO=World" > .env $ dotenvx encrypt $ dotenvx keypair {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}Print public/private keys for
.env.productionfile.$ echo "HELLO=Production" > .env.production $ dotenvx encrypt -f .env.production $ dotenvx keypair -f .env.production {"DOTENV_PUBLIC_KEY_PRODUCTION":"<publicKey>","DOTENV_PRIVATE_KEY_PRODUCTION":"<privateKey>"}Specify path to
.env.keys. This is useful for printing public/private keys for monorepos.$ mkdir -p apps/app1 $ echo "HELLO=World" > apps/app1/.env $ dotenvx encrypt -fk .env.keys -f apps/app1/.env $ dotenvx keypair -fk .env.keys -f apps/app1/.env {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}Print specific keypair for
.envfile.$ echo "HELLO=World" > .env $ dotenvx encrypt $ dotenvx keypair DOTENV_PRIVATE_KEY <privateKey>Print a shell formatted response of public/private keys.
$ echo "HELLO=World" > .env $ dotenx encrypt $ dotenvx keypair --format shell DOTENV_PUBLIC_KEY=<publicKey> DOTENV_PRIVATE_KEY=<privateKey>Print all
.envfiles in a tree structure.$ touch .env $ touch .env.production $ mkdir -p apps/backend $ touch apps/backend/.env $ dotenvx ls ├─ .env.production ├─ .env └─ apps └─ backend └─ .envPrint all
.envfiles inside a specified path to a directory.$ touch .env $ touch .env.production $ mkdir -p apps/backend $ touch apps/backend/.env $ dotenvx ls apps/backend └─ .envGlob
.envfilenames matching a wildcard.$ touch .env $ touch .env.production $ mkdir -p apps/backend $ touch apps/backend/.env $ touch apps/backend/.env.prod $ dotenvx ls -f **/.env.prod* ├─ .env.production └─ apps └─ backend └─ .env.prodGlob
.envfilenames excluding a wildcard.$ touch .env $ touch .env.production $ mkdir -p apps/backend $ touch apps/backend/.env $ touch apps/backend/.env.prod $ dotenvx ls -ef '**/.env.prod*' ├─ .env └─ apps └─ backend └─ .envRotate public/private keys for
.envfile and re-encrypt all encrypted values.$ echo "HELLO=World" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx rotate ✔ rotated (.env)Rotate public/private keys for a specified encrypted
.envfile and re-encrypt all encrypted values.$ echo "HELLO=World" > .env $ echo "HELLO=Production" > .env.production $ dotenvx encrypt -f .env.production ✔ encrypted (.env.production) $ dotenvx rotate -f .env.production ✔ rotated (.env.production)Specify path to
.env.keys. This is useful with monorepos.$ mkdir -p apps/app1 $ echo "HELLO=World" > apps/app1/.env $ dotenvx encrypt -fk .env.keys -f apps/app1/.env ✔ encrypted (apps/app1/.env) $ dotenvx rotate -fk .env.keys -f apps/app1/.env ✔ rotated (apps/app1/.env)Rotate the contents of a specified key inside an encrypted
.envfile.$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx rotate -k HELLO ✔ rotated (.env)Even specify a glob pattern.
$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx rotate -k "HE*" ✔ rotated (.env)Rotate the encrypted contents inside an encrypted
.envfile except for an excluded key.$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx rotate -ek HOLA ✔ rotated (.env)Even specify a glob pattern.
$ echo "HELLO=World\nHOLA=Mundo" > .env $ dotenvx encrypt ✔ encrypted (.env) $ dotenvx rotate -ek "HO*" ✔ rotated (.env)Rotate the contents of an encrypted
.envfile and send to stdout.$ dotenvx rotate --stdout #/-------------------[DOTENV_PUBLIC_KEY]--------------------/ #/ public-key encryption for .env files / #/ [how it works](https://dotenvx.com/encryption) / #/----------------------------------------------------------/ DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45" # .env HELLO="encrypted:12345"or send to a file:
$ dotenvx rotate --stdout > somefile.txtOutput help for
dotenvx.$ dotenvx help Usage: dotenvx run -- yourcommand a better dotenv–from the creator of `dotenv` Options: -l, --log-level <level> set log level (default: "info") -q, --quiet sets log level to error -v, --verbose sets log level to verbose -d, --debug sets log level to debug -V, --version output the version number -h, --help display help for command Commands: run inject env at runtime [dotenvx run -- yourcommand] get [KEY] return a single environment variable set <KEY> <value> set a single environment variable encrypt convert .env file(s) to encrypted .env file(s) decrypt convert encrypted .env file(s) to plain .env file(s) keypair [KEY] print public/private keys for .env file(s) ls [directory] print all .env files in a tree structure Advanced: pro 🏆 pro ext 🔌 extensionsYou can get more detailed help per command with
dotenvx help COMMAND.$ dotenvx help run Usage: @dotenvx/dotenvx run [options] inject env at runtime [dotenvx run -- yourcommand] Options: -e, --env <strings...> environment variable(s) set as string (example: "HELLO=World") (default: []) -f, --env-file <paths...> path(s) to your env file(s) (default: []) -fv, --env-vault-file <paths...> path(s) to your .env.vault file(s) (default: []) -o, --overload override existing env variables --convention <name> load a .env convention (available conventions: ['nextjs']) -h, --help display help for command Examples: $ dotenvx run -- npm run dev $ dotenvx run -- flask --app index run $ dotenvx run -- php artisan serve $ dotenvx run -- bin/rails s Try it: $ echo "HELLO=World" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js $ dotenvx run -- node index.js [dotenvx@1.X.X] injecting env (1) from .env Hello WorldCheck current version of
dotenvx.$ dotenvx --version X.X.X
Extensions 🔌
CLI extensions.
In one command, generate a
.env.examplefile from your current.envfile contents.$ echo "HELLO=World" > .env $ dotenvx ext genexample ✔ updated .env.example (1)# .env.example HELLO=""Pass multiple
.envfiles to generate your.env.examplefile from the combination of their contents.$ echo "HELLO=World" > .env $ echo "DB_HOST=example.com" > .env.production $ dotenvx ext genexample -f .env -f .env.production ✔ updated .env.example (2)# .env.example HELLO="" DB_HOST=""Generate a
.env.examplefile inside the specified directory. Useful for monorepos.$ echo "HELLO=World" > .env $ mkdir -p apps/backend $ echo "HELLO=Backend" > apps/backend/.env $ dotenvx ext genexample apps/backend ✔ updated .env.example (1)# apps/backend/.env.example HELLO=""Gitignore your
.envfiles.$ dotenvx ext gitignore ✔ ignored .env* (.gitignore)Gitignore specific pattern(s) of
.envfiles.$ dotenvx ext gitignore --pattern .env.keys ✔ ignored .env.keys (.gitignore)Prevent
.envfiles from being committed to code.$ dotenvx ext precommit [dotenvx][precommit] .env files (1) protected (encrypted or gitignored)Install a shell script to
.git/hooks/pre-committo prevent accidentally committing any.envfiles to source control.$ dotenvx ext precommit --install [dotenvx][precommit] dotenvx ext precommit installed [.git/hooks/pre-commit]Prevent
.envfiles from being committed to code inside a specified path to a directory.$ echo "HELLO=World" > .env $ mkdir -p apps/backend $ echo "HELLO=Backend" > apps/backend/.env $ dotenvx ext precommit apps/backend [dotenvx][precommit] apps/backend/.env not protected (encrypted or gitignored)Prevent
.envfiles from being built into your docker containers.Add it to your
Dockerfile.# Dockerfile RUN curl -fsS https://dotenvx.sh | sh ... RUN dotenvx ext prebuild CMD ["dotenvx", "run", "--", "node", "index.js"]Prevent
.envfiles from being built into your docker containers inside a specified path to a directory.Add it to your
Dockerfile.# Dockerfile RUN curl -fsS https://dotenvx.sh | sh ... RUN dotenvx ext prebuild apps/backend CMD ["dotenvx", "run", "--", "node", "apps/backend/index.js"]Scan for leaked secrets.
$ dotenvx ext scan 100 commits scanned. no leaks foundUses gitleaks under the hood.
Library 📦
Use dotenvx directly in code.
Use directly in node.js code.
# .env HELLO="World"// index.js require('@dotenvx/dotenvx').config() console.log(`Hello ${process.env.HELLO}`)$ node index.js [dotenvx@1.X.X] injecting env (1) from .env Hello WorldIt defaults to looking for a
.envfile.Specify path(s) to multiple .env files.
# .env.local HELLO="Me"# .env HELLO="World"// index.js require('@dotenvx/dotenvx').config({path: ['.env.local', '.env']}) // esm // import dotenvx from "@dotenvx/dotenvx"; // dotenvx.config({path: ['.env.local', '.env']}); console.log(`Hello ${process.env.HELLO}`)$ node index.js [dotenvx@1.X.X] injecting env (1) from .env.local, .env Hello MeUse
overloadto overwrite the prior set value.# .env.local HELLO="Me"# .env HELLO="World"// index.js require('@dotenvx/dotenvx').config({path: ['.env.local', '.env'], overload: true}) // esm // import dotenvx from "@dotenvx/dotenvx"; // dotenvx.config({path: ['.env.local', '.env'], overload: true}); console.log(`Hello ${process.env.HELLO}`)$ node index.js [dotenvx@1.X.X] injecting env (1) from .env.local, .env Hello WorldUse
strictto throw if an error is encountered - like a missing .env file.# .env HELLO="World"// index.js require('@dotenvx/dotenvx').config({path: ['.env.missing', '.env'], strict: true}) // esm // import dotenvx from "@dotenvx/dotenvx"; // dotenvx.config({path: ['.env.missing', '.env'], strict: true}); console.log(`Hello ${process.env.HELLO}`)$ node index.js Error: [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)Use
ignoreto suppress specific errors likeMISSING_ENV_FILE.# .env HELLO="World"// index.js require('@dotenvx/dotenvx').config({path: ['.env.missing', '.env'], ignore: ['MISSING_ENV_FILE']}) // esm // import dotenvx from "@dotenvx/dotenvx"; // dotenvx.config({path: ['.env.missing', '.env'], ignore: ['MISSING_ENV_FILE']}); console.log(`Hello ${process.env.HELLO}`)$ node index.js [dotenvx@1.X.X] injecting env (1) from .env Hello WorldUse
envKeysFileto customize the path to your.env.keysfile. This is useful with monorepos.# .env HELLO="World"// index.js require('@dotenvx/dotenvx').config({path: ['.env'], envKeysFile: '../../.env.keys'})Parse a
.envstring directly in node.js code.// index.js const dotenvx = require('@dotenvx/dotenvx') const src = 'HELLO=World' const parsed = dotenvx.parse(src) console.log(`Hello ${parsed.HELLO}`)$ node index.js Hello WorldSometimes, you want to run
parsewithout it accessingprocess.env. (You can pass a fake processEnv this way as well - sometimes useful.)// index.js const dotenvx = require('@dotenvx/dotenvx') const src = 'USER=Me' const parsed = dotenvx.parse(src, { processEnv: {} }) console.log(`Hello ${parsed.USER}`)$ node index.js Hello MeDecrypt an encrypted
.envstring withprivateKey.// index.js const dotenvx = require('@dotenvx/dotenvx') const src = 'HELLO="encrypted:BE9Y7LKANx77X1pv1HnEoil93fPa5c9rpL/1ps48uaRT9zM8VR6mHx9yM+HktKdsPGIZELuZ7rr2mn1gScsmWitppAgE/1lVprNYBCqiYeaTcKXjDUXU5LfsEsflnAsDhT/kWG1l"' const parsed = dotenvx.parse(src, { privateKey: 'a4547dcd9d3429615a3649bb79e87edb62ee6a74b007075e9141ae44f5fb412c' }) console.log(`Hello ${parsed.HELLO}`)$ node index.js Hello WorldProgrammatically set an environment variable.
// index.js const dotenvx = require('@dotenvx/dotenvx') dotenvx.set('HELLO', 'World', { path: '.env' })Programmatically get an environment variable at access/runtime.
// index.js const dotenvx = require('@dotenvx/dotenvx') const decryptedValue = dotenvx.get('HELLO') console.log(decryptedValue)This is known as Decryption at Access and is written about in the whitepaper.
Pro 🏆
Dotenvx Pro is a commercial extension for dotenvx.
Secrets Management – Done Right. Encrypted, Cloaked, Secrets as Code.
Print fully managed public/private keys for
.envfile.$ echo "HELLO=World" > .env $ dotenvx encrypt $ dotenvx pro push $ dotenvx pro keypair {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}Print fully managed public/private keys for
.env.productionfile.$ echo "HELLO=Production" > .env.production $ dotenvx encrypt -f .env.production $ dotenvx pro push $ dotenvx pro keypair -f .env.production {"DOTENV_PUBLIC_KEY_PRODUCTION":"<publicKey>","DOTENV_PRIVATE_KEY_PRODUCTION":"<privateKey>"}Print specific fully managed keypair for
.envfile.$ echo "HELLO=World" > .env $ dotenvx encrypt $ dotenvx pro push $ dotenvx pro keypair DOTENV_PRIVATE_KEY <privateKey>Print organization.
$ dotenvx pro settings org motdotlaPrint organization public key–used for encrypting project private keys.
$ dotenvx pro settings orgpublickey 02761eccd2a442ebbfa14ac2e72762d885a1e96b8949428deea62db305947d6408Print masked organization private key–used for decrypting project private keys.
$ dotenvx pro settings orgprivatekey 322c004*********************************************************Print unmasked organization private key–used for decrypting project private keys.
$ dotenvx pro settings orgprivatekey --unmask 322c004271ac6ad1b548df3f316ff4e8f08e17e0b15f459db64f3f3b48b0efb7Print team status in tabular format.
$ dotenvx pro settings orgteam ╔═══════════╤════════╗ ║ username │ synced ║ ╟───────────┼────────╢ ║ motdotla │ ✔ ║ ╟───────────┼────────╢ ║ motdotenv │ ✔ ║ ╚═══════════╧════════╝Print encrypted store tree–backing your dotenvx pro installation.
$ dotenvx pro settings storetree ├─ .env └─ pro.dotenvx.com ├─ user-1-organization-1.json ├─ user-1-private-key.json └─ user-1.json
Whitepaper
Dotenvx: Reducing Secrets Risk with Cryptographic Separation
Abstract. An ideal secrets solution would not only centralize secrets but also contain the fallout of a breach. While secrets managers offer centralized storage and distribution, their design creates a large blast radius, risking exposure of thousands or even millions of secrets. We propose a solution that reduces the blast radius by splitting secrets management into two distinct components: an encrypted secrets file and a separate decryption key.
...
Guides
Go deeper with
dotenvx– detailed framework and platform guides.
5 months ago
5 months ago
5 months ago
11 months ago
10 months ago
10 months ago
9 months ago
12 months ago
12 months ago
12 months ago
9 months ago
9 months ago
12 months ago
8 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
8 months ago
6 months ago
6 months ago
11 months ago
11 months ago
11 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
6 months ago
11 months ago
11 months ago
11 months ago
10 months ago
7 months ago
7 months ago
6 months ago
6 months ago
6 months ago
11 months ago
10 months ago
10 months ago
6 months ago
11 months ago
10 months ago
10 months ago
10 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
