MUST USE for any task involving the dotenvx CLI tool — encrypting .env files, running commands with injected env vars, managing secrets across environments, and decrypting at runtime. Use this skill whenever the user mentions dotenvx, dotenv encryption, DOTENV_PRIVATE_KEY, encrypted .env files, or the dotenvx encrypt/run/set/get/decrypt/keypair commands. Also trigger when the user wants to: commit .env files safely to git, stop sharing secrets over Slack/chat, encrypt environment variables with public-key cryptography, set up multi-environment .env configs (production/staging/ci), manage secrets in a monorepo with -fk flag, migrate from python-dotenv or plain dotenv to encrypted envs, inject env vars into any process across any language (Node, Python, Ruby, Go, Rust, etc.), or configure CI/CD pipelines (GitHub Actions, Docker) with encrypted env files. This skill contains the authoritative CLI reference — without it, responses will hallucinate non-existent commands and flags.
dotenvx is a secure dotenv — from the creator of dotenv. It provides encrypted environment variables, cross-platform run injection, and multi-environment support.
Key capabilities:
dotenvx run — inject env vars into any command, any languagedotenvx encrypt — encrypt .env files with public-key cryptography (secp256k1)dotenvx set / get — manage individual env varsdotenvx decrypt — decrypt .env files back to plaintext-f flag and DOTENV_PRIVATE_KEY_* convention# npm (local to project)
npm install @dotenvx/dotenvx --save
# global installs
curl -sfS https://dotenvx.sh | sh # curl
brew install dotenvx/brew/dotenvx # brew
winget install dotenvx # windows
docker run -it --rm -v $(pwd):/app dotenv/dotenvx help # docker
For Node.js, also usable as a library:
require('@dotenvx/dotenvx').config()
// or: import '@dotenvx/dotenvx/config'
dotenvx runInject environment variables from .env files into any process. This is the primary command.
dotenvx run -- <command>
Flags:
| Flag | Description |
|---|---|
| -f <file> | Specify env file(s). Repeatable. Default: .env |
| --env KEY=value | Set inline env var |
| --overload | Later files/values override earlier ones (default: first wins) |
| --strict | Exit code 1 on any error (missing file, decrypt failure) |
| --ignore=ERROR_CODE | Ignore specific errors (e.g., MISSING_ENV_FILE) |
| --convention=nextjs\|flow | Load files using Next.js or dotenv-flow convention |
| -fk <path> | Specify path to .env.keys file (useful for monorepos) |
| --quiet | Suppress all output except errors |
| --verbose | Verbose logging |
| --debug | Debug-level logging |
| --log-level=<level> | Set log level: error, warn, info, verbose, debug, silly |
Examples:
# Basic usage
dotenvx run -- node index.js
# Specific env file
dotenvx run -f .env.production -- node index.js
# Multiple env files (first file's values win by default)
dotenvx run -f .env.local -f .env -- node index.js
# Override: last file wins
dotenvx run -f .env.local -f .env --overload -- node index.js
# Inline env var (overrides file values)
dotenvx run --env HELLO=String -f .env -- node index.js
# Any language works
dotenvx run -- python3 app.py
dotenvx run -- ruby index.rb
dotenvx run -- go run main.go
dotenvx run -- cargo run
dotenvx run -- php artisan serve
dotenvx run -- next dev
# Shell expansion (use subshell to prevent premature expansion)
dotenvx run --env="HELLO=World" -- sh -c 'echo Hello $HELLO'
# Strict mode for CI
dotenvx run -f .env.ci --strict -- node build.js
Precedence rules:
.env file values-f files, the first file's value wins (historic dotenv behavior)--overload reverses this: later files override earlier ones--env flag values take precedence over file valuesVariable expansion and interpolation:
dotenvx supports ${VAR} expansion, default values, alternate values, and command substitution inside .env files:
# Variable expansion
USERNAME="admin"
DATABASE_URL="postgres://${USERNAME}@localhost/mydb"
# Default values (use fallback if unset/empty)
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-5432}
# Alternate values (use alternate if variable IS set)
DEBUG_MODE=${NODE_ENV:+false}
# Command substitution
WHOAMI="$(whoami)"
Multiline values are supported — wrap in double quotes:
CERT="-----BEGIN CERTIFICATE-----
MIIB...
-----END CERTIFICATE-----"
Do NOT hallucinate these — they do not exist:
dotenvx keys — use dotenvx keypair insteaddotenvx status — no such commanddotenvx rotate — to rotate, use dotenvx set to update values, or decrypt → delete .env.keys → re-encrypt--env-name flag — does not exist.env.vault files — dotenvx encrypts in place, not to a separate vault fileDOTENVX_PRIVATE_KEY — the correct env var is DOTENV_PRIVATE_KEY (no X in the middle)pip install dotenvx — there is no Python package; dotenvx is a CLI tool that wraps any languagedotenvx.load_dotenv() — no Python API; use dotenvx run -- python app.py at the CLI leveldotenvx encryptEncrypt .env file(s) in place. Generates a DOTENV_PUBLIC_KEY (added to the .env file) and a DOTENV_PRIVATE_KEY (saved to .env.keys).
dotenvx encrypt # encrypts .env
dotenvx encrypt -f .env.production # encrypts specific file
dotenvx encrypt --stdout # output to stdout instead of in-place
After encryption:
.env contains encrypted values + DOTENV_PUBLIC_KEY.env.keys contains DOTENV_PRIVATE_KEY (keep this secret, never commit it).env is safe to commit to version controldotenvx decryptDecrypt an encrypted .env file back to plaintext.
dotenvx decrypt # decrypts .env
dotenvx decrypt -f .env.production # decrypts specific file
dotenvx decrypt --stdout # output to stdout
Requires the private key to be available (via .env.keys file or DOTENV_PRIVATE_KEY* env var).
dotenvx setSet an individual environment variable in a .env file. Creates the file if it doesn't exist. If the file is encrypted, re-encrypts automatically.
dotenvx set KEY value # set in .env
dotenvx set KEY value -f .env.production # set in specific file
dotenvx set KEY "multi word value" # quoted values
dotenvx set KEY value -fk .env.keys -f apps/app1/.env # monorepo
dotenvx getRetrieve a single environment variable's value.
dotenvx get HELLO # from .env
dotenvx get HELLO -f .env.production # from specific file
dotenvx get HELLO --env HELLO=Override # from --env string
dotenvx get HELLO --overload # with overload semantics
dotenvx get HELLO --strict # exit 1 if key missing
dotenvx get HELLO --convention=nextjs # with convention
dotenvx get HELLO -fk .env.keys -f app/.env # monorepo
Get all as JSON:
dotenvx get # all vars from .env as JSON
dotenvx get -f .env.production # all vars from specific file
dotenvx get --all # include DOTENV_PUBLIC_KEY
dotenvx get --format shell # output as KEY=value lines
dotenvx keypairOutput the public/private keypair for an encrypted .env file.
dotenvx keypair # all keypairs as JSON
dotenvx keypair DOTENV_PRIVATE_KEY # just the private key
dotenvx keypair -f .env.production # for specific file
dotenvx keypair DOTENV_PRIVATE_KEY_PRODUCTION -f .env.production
# 1. Create your .env
echo "DATABASE_URL=postgres://localhost/mydb" > .env
echo "API_KEY=sk-secret123" >> .env
# 2. Encrypt it
dotenvx encrypt
# ✔ encrypted (.env)
# Creates .env.keys with your private key
# 3. Commit .env (encrypted, safe), do NOT commit .env.keys
echo ".env.keys" >> .gitignore
git add .env .gitignore
git commit -m "add encrypted env"
Each environment gets its own keypair. The naming convention is automatic:
# Encrypt each environment
dotenvx encrypt -f .env.production
dotenvx encrypt -f .env.staging
dotenvx encrypt -f .env.ci
# Each creates a corresponding private key in .env.keys:
# DOTENV_PRIVATE_KEY_PRODUCTION="..."
# DOTENV_PRIVATE_KEY_STAGING="..."
# DOTENV_PRIVATE_KEY_CI="..."
Set the appropriate DOTENV_PRIVATE_KEY_* env var, and dotenvx run decrypts automatically:
# The private key suffix matches the file suffix
DOTENV_PRIVATE_KEY="key" dotenvx run -- node app.js # decrypts .env
DOTENV_PRIVATE_KEY_PRODUCTION="key" dotenvx run -- node app.js # decrypts .env.production
DOTENV_PRIVATE_KEY_CI="key" dotenvx run -- node app.js # decrypts .env.ci
# Combine multiple
DOTENV_PRIVATE_KEY="k1" DOTENV_PRIVATE_KEY_PRODUCTION="k2" dotenvx run -- node app.js
# Comma-separated keys for monorepos (same environment, different apps)
DOTENV_PRIVATE_KEY_CI="key1,key2" dotenvx run -f app1/.env.ci -f app2/.env.ci -- node app.js
# GitHub Actions example
name: deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: curl -fsS https://dotenvx.sh/install.sh | sh
- run: dotenvx run -- node build.js
env:
DOTENV_PRIVATE_KEY_PRODUCTION: ${{ secrets.DOTENV_PRIVATE_KEY_PRODUCTION }}
--convention=nextjsLoads files in Next.js priority order:
.env.$(NODE_ENV).local.env.local.env.$(NODE_ENV).envdotenvx run --convention=nextjs -- next dev
--convention=flowLoads files in dotenv-flow priority order. Uses DOTENV_ENV or NODE_ENV:
DOTENV_ENV=development dotenvx run --convention=flow -- node app.js
Use -fk to specify a shared .env.keys path:
# Set values for different apps
dotenvx set HELLO app1 -fk .env.keys -f apps/app1/.env
dotenvx set HELLO app2 -fk .env.keys -f apps/app2/.env
# Run with shared keys
dotenvx run -fk .env.keys -f apps/app1/.env -- node apps/app1/index.js
# Get values
dotenvx get HELLO -fk .env.keys -f apps/app1/.env
FROM node:latest
RUN curl -fsS https://dotenvx.sh/install.sh | sh
COPY . .
CMD ["dotenvx", "run", "--", "node", "index.js"]
Or run directly:
docker run -it --rm -v $(pwd):/app dotenv/dotenvx run -- node index.js
Add a new secret to an encrypted file:
dotenvx set NEW_SECRET "value" -f .env.production
# Automatically re-encrypts
Rotate a value:
dotenvx set API_KEY "new-key-value" -f .env.production
View decrypted values without running a command:
dotenvx get -f .env.production # needs private key available
dotenvx get API_KEY -f .env.production # single value
Convert existing plaintext .env to encrypted:
dotenvx encrypt -f .env.production
# Done. Commit the encrypted .env.production, store .env.keys privately.
Suppress dotenvx output in scripts:
dotenvx run --quiet -- ./my-script.sh
Fail CI on missing/broken env:
dotenvx run -f .env.ci --strict -- npm test
# Never commit private keys
.env.keys
# Encrypted .env files ARE safe to commit
# !.env
# !.env.production
# !.env.staging
MISSING_ENV_FILE — the specified .env file doesn't exist. Create it or use --ignore=MISSING_ENV_FILE.MISSING_KEY — the requested key isn't in the .env file.DOTENV_PRIVATE_KEY_* is set. The suffix must match the file suffix (e.g., _PRODUCTION for .env.production).deno run npm:@dotenvx/dotenvx encrypt. Deno has incomplete cipher support. Install dotenvx as a binary instead.$VARS prematurely — use a subshell: dotenvx run -- sh -c 'echo $MY_VAR'dotenvx ext)Utility commands for managing dotenvx workflows:
dotenvx ext genexample # generate .env.example from .env
dotenvx ext genexample -f .env.production # from specific file
dotenvx ext gitignore # append .env.keys to .gitignore
dotenvx ext ls # list all .env files in project
dotenvx ext ls -f .env.production # check specific file
dotenvx ext settings # view current dotenvx settings
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer