Self-hosted service
dotenvx/dotenvx avatar
dotenvx/dotenvx

dotenvx: committing encrypted .env files with secp256k1

a secure dotenv—from the creator of `dotenv`

5,815 stars155 forksJavaScriptBSD-3-Clause

At a glance

What is it?
dotenvx encrypts the values in your .env file so the ciphertext can travel in git while the private key stays on your infrastructure. It is a drop-in replacement for dotenv with a CLI, and it is maintained under BSD-3-Clause.
Who is it for?
Adopt dotenvx if you want .env files to live in the same repository as the code and you accept that one private key becomes the thing you must protect. Do not adopt it if your compliance model requires a central audit log of every secret read, because decryption happens locally with a key you hold.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem dotenvx solves: secrets that cannot ride along with code

A plain .env file is a text file of key-value pairs, and the README asks the obvious question about it: it is the open standard for loading secrets into code, but it is not safe to commit. Adding .env to .gitignore solves the leak and creates a different problem. Every new machine, every CI runner and every teammate needs the values copied in by hand or fetched from a separate secrets service before the application will start.

dotenvx targets that gap. The README describes the workflow in three verbs: encrypt, commit, ship. The values inside .env become ciphertext, the ciphertext is committed alongside the code, and a private key held on the infrastructure decrypts and injects the real values at runtime. The audience is any team already using .env files that wants git to be the distribution channel for the encrypted file rather than a system that must be kept out of git. The package is published as @dotenvx/dotenvx, and the README positions the global CLI as something that "unlocks dotenv for any language, framework, or platform", so the target is not only Node projects.

Three primitives: git, .env and secp256k1

The design section of the README is unusually explicit about the reasoning, and it is worth taking at face value because it explains the constraints you inherit. Git is chosen as the delivery mechanism. The README calls it "the container ship of the digital world" and argues there is no reason to invent a separate secrets delivery channel when code already travels this way. The .env format is chosen because it is the interface every runtime already understands, so the tool does not need adapters per language. The encryption algorithm is secp256k1, an asymmetric standard with small keys that the README says has been battle-tested by Bitcoin for more than seventeen years.

Asymmetry is the part that matters operationally. Because encryption and decryption use different keys, the values can be encrypted once and the private key set only on the machines that need to decrypt. The README states the result directly: the whole system works by setting a single private key on your infrastructure, with no async coordination of secrets and no central service whose downtime blocks a deploy. That is a real architectural claim, and it is also where the trade-offs live, because a single key is a single thing to lose.

Installing dotenvx and encrypting a first .env

The README lists several install paths. The npm route is the shortest if Node is already present.

bash
npm i -g @dotenvx/dotenvx
dotenvx encrypt

The command rewrites your .env file so the values are ciphertext. The README shows the output as "encrypted (.env)". There are equivalent installers for environments without npm: a curl script at https://dotenvx.sh, a Homebrew tap (brew tap dotenvx/brew, brew trust dotenvx/brew, brew install dotenvx), a Docker image at dotenv/dotenvx, a winget package, and a tarball from the GitHub releases page that is unpacked with tar and run as ./dotenvx. A Dockerfile in the repository shows the tarball approach being used inside an Ubuntu image, fetching dotenvx-${OS}-${ARCH}.tar.gz and placing the binary in /usr/local/bin.

Once encrypted, the file is safe to commit. The README gives the sequence as git add .env followed by git commit. To run code with the decrypted values injected, the CLI wraps the process:

bash
dotenvx run -- node index.js

The README shows the output as "injected env (2) from .env", and its Run Anywhere example contrasts node index.js printing "Hello undefined" with dotenvx run -- node index.js printing "Hello World". Note the separator: dotenvx run takes the command after --, which is what lets it wrap a binary that is not Node. If you prefer to load values inside the process instead of wrapping it, the package can be required directly, as in require('@dotenvx/dotenvx').config() or the ESM import '@dotenvx/dotenvx/config'.

Redaction when an AI agent holds your secrets

The README devotes four collapsible examples to running agent CLIs with real secrets while hiding the values from the agent's own transcript. The mechanism is the --redact flag on run. For Claude Code, the README shows:

bash
dotenvx run --redact -- claude -p 'Run `dotenvx get HELLO` and echo back just Hello VALUE' --dangerously-skip-permissions

The expected output is "Hello [REDACTED]". The same pattern is documented for Codex with codex exec, for Cursor with the agent command, and each example notes its prerequisite install command first. The 1Password example is different in kind: it shows a .env value written as op://Personal/hello/password, so the reference is resolved at run time rather than stored as a literal.

This is the most opinionated part of the project. Redaction is a filter on output, not a sandbox, and the README does not claim otherwise. If a process can read the environment, it has the value; redaction only stops the value from being echoed back into a log or a chat transcript.

The operational cost: one private key, no audit trail

The trade-off the README states plainly is also the one to think hardest about. Decryption depends on a private key present on the machine. Lose it and the committed ciphertext is unreadable, because there is no server-side recovery path described in the README. Leak it and the ciphertext in git stops being a protection. The README does not document a key rotation procedure, and it does not document a rollback path for the encrypt command, so those are questions to answer before the first commit rather than after.

The second cost is visibility. A central secrets manager can log which process read which secret and when. dotenvx decrypts locally, so there is no such log by construction. Teams under an audit regime that requires a record of every secret access will find that this design does not produce one. The project also ships a Dockerfile that pulls the latest release tarball at build time, which means image builds depend on GitHub releases being reachable; the README does not describe a pinned-version or offline install path.

The repository is not archived and the last push was on 2026-09-27, with v2.31.1 released the same day, so this is a current project rather than an abandoned one.

dotenvx against HashiCorp Vault and dotenv itself

The honest comparison is not with dotenv, because dotenvx is a superset of it. The README says the package is used in code "just like dotenv", and the require line is the same call. If all you need is to read a local .env into process.env and the file never leaves the machine, adding dotenvx buys you nothing and adds a binary. The difference appears only when the file has to be shared.

Against a server-based manager such as HashiCorp Vault, the difference is architectural rather than a feature list. Vault keeps secrets in a service you run and query, which gives you central revocation, access policies and an audit log, at the cost of a service that must be available when your application starts. dotenvx inverts that: secrets are already next to the code in git, and the only runtime dependency is a key in the environment. The README frames the absence of a service as the point, describing "no more centralized downtime risk". The price is that revocation means re-encrypting and re-committing, and there is no per-read log. Neither model is strictly better; they fail in opposite directions.

Editorial conclusion

Adopt dotenvx if you want .env files to live in the same repository as the code and you accept that one private key becomes the thing you must protect. Do not adopt it if your compliance model requires a central audit log of every secret read, because decryption happens locally with a key you hold. Before rolling it out, run dotenvx encrypt on a throwaway .env and confirm that dotenvx run -- node index.js prints the plaintext value while the committed file shows ciphertext.

Frequently asked questions

What is dotenvx?

It is a secure dotenv from the creator of dotenv. It encrypts the values in .env files so the ciphertext can be committed to git, and decrypts them at runtime with a private key held on your infrastructure.

How do I install dotenvx?

The README lists several routes: npm i -g @dotenvx/dotenvx, the curl script at https://dotenvx.sh, a Homebrew tap, the dotenv/dotenvx Docker image, winget, and a tarball from the GitHub releases page.

How do I use dotenvx to run a script?

Encrypt the file with dotenvx encrypt, then wrap the command with dotenvx run -- followed by your command, for example dotenvx run -- node index.js. The README shows the output as "injected env (2) from .env".

Is dotenvx free?

The package is published under the BSD-3-Clause licence, and the repository includes a funding link. The README does not describe a paid tier or a hosted component.

Should you commit your .env file with dotenvx?

Yes, after running dotenvx encrypt. The README's three-step workflow is encrypt, commit, ship, and it shows git add .env followed by git commit as the way to share the encrypted file.

Official sources

  1. dotenvx/dotenvx on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dotenvx-dotenvx.svg)](https://hysenlabs.com/projects/dotenvx-dotenvx)