Skip to content

📝 .env.example Generator

Paste your real .env and the tool replaces values with safe placeholders while preserving comments and structure, producing a .env.example you can safely commit to Git.

100% Free No signup Browser-only 5 languages Dark mode

🔒 Privacy is our top priority

📥 Input (.env)

📤 .env.example

➕ Add from form

Pick a key name and category to append to the .env.example.

📖 Where people get stuck

Paste a real .env and it replaces the values with safe placeholders while preserving the comments and structure, producing a .env.example you can commit. Everything runs in the browser and nothing is transmitted. Replacing the values is not the same as leaving no secrets behinda real value written inside a comment passes straight through to the output. Read the result yourself before you commit it.

Case What happens What to do
A real value survives inside a comment The replacement targets the value in KEY=VALUE, so lines beginning with # pass through untouched. Real .env files, however, frequently contain secrets in the shape of comments: # production uses sk-live-abc123, # old key: xoxb-..., # connects to postgres://user:pass@prod-db.internal:5432. Comments are written as notes, which makes them less guarded than the value field. Likewise, a key name can carry information by itselfACME_CORP_API_KEY publishes the name of a client. Read the generated .env.example from top to bottom before committing itessential when you enabled comment preservation. Look for three things: real values written into comments, client or internal system names embedded in key names, and hostnames or ports that reveal your internal topology. A comment is the place to say why a key is needed, not what its value isif you want to note the real value somewhere, that belongs in the .env itself or in a password manager. Reviewing the comments in the original .env before converting saves you removing them from the example afterwards.
A list of key names alone does not get a newcomer running The purpose of a .env.example is to convey what has to be configured to run the project. But a file of key names and placeholders conveys almost none of what is needed: the line STRIPE_SECRET_KEY=your_key_here says nothing about where to obtain one, whether it is the test or the live key, or whether it is required at all. The result is that a newcomer has to ask an existing member, and the existence of the example file becomes a formality. Put one line of comment above each key, saying where to obtain it, whether it is required, and the shape of the value. A single line such as # Stripe dashboard, Developers, API keys. Use the one starting sk_test_ in development. Required. lets a newcomer resolve it without asking. For optional keys, state the default too# defaults to 3000. The value of this work is in fact greater for the existing members: the person who reads it when rebuilding an environment six months later, or reviewing the production settings, is usually the one who wrote it. What you wrote for the newcomer ends up helping you most.
The example exists but the real .env got committed anyway Writing .env in .gitignore has no effect on a file that is already tracked.gitignore is a rule for ignoring files not yet tracked, so anything you ever ran git add on continues to have its changes tracked. The other common problem is how the pattern is written: .env* also ignores .env.example, so the template you just made never gets committeda repository with no .env.example in it is frequently this misconfiguration. Write the exclusion as two lines!.env.example on the line after .env* (the order matters; a negation before the exclusion has no effect). If the file is already tracked, git rm --cached .env removes it from tracking while leaving your local copy alone. Verify with git ls-files | grep env: seeing only .env.example is the correct state. And the most important point: if .env appeared in a past commit, rewriting history is not a remedy. It survives in forks, CI logs, other people local clones and the GitHub cache, so the only correct response is to revoke that key and issue a new onedo that before you start tidying the history, the moment you notice.

It is worth knowing the limits of the .env mechanism itself. First, it cannot express a value containing a newlinetrying to put a private key or a certificate in one always stalls here. The workaround is Base64 on a single line, but that is a compromise made in acknowledgement of the limit. Second, there are no types: everything is a string, so DEBUG=false is the string "false", which most languages evaluate as true. Third, there is no mechanism for managing differences between environments — keeping separate .env files for development, staging and production means synchronising all of them by hand every time a key is added. In production, use a secret manager rather than .env — AWS Secrets Manager, Google Secret Manager, HashiCorp Vault — because access control, audit logging and automatic rotation, which .env cannot have in principle, are usually needed only in production. Development can stay on .env.

📖 How to Use

  1. 1
    Paste your real .env
    Paste your real .env into the left textarea. You can also start from a preset.
  2. 2
    Auto-sanitize
    Keys with PASSWORD/SECRET/TOKEN/KEY become random placeholders; URLs become example.com; ports become typical values like 3000.
  3. 3
    Get a commit-safe file
    Copy the right output, or download as .env.example, then git add and commit.

❓ Frequently Asked Questions

Are you absolutely sure my .env is not uploaded?
Yes. Everything is processed in your browser by JavaScript. You can verify zero network requests in the Network tab. If still concerned, you can run it offline.
Which keys are detected as secrets?
Keys whose name contains PASSWORD, SECRET, TOKEN, KEY, API_KEY, PRIVATE, or CREDENTIAL are auto-treated as secrets and replaced with random placeholders.
Are comments and blank lines preserved?
Yes. Section comments and blank lines used for grouping are preserved. Toggle off Keep comments to strip them.
🐛 Found a bug or issue with this tool?

Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.

* Browser info (UA / screen / language / URL) is sent automatically to help reproduce the issue