Free .env File Diff
Paste two .env files to see which variables are missing on either side, which values changed, and which keys are defined twice.
What is a .env File Diff?
A .env file holds an app’s configuration as KEY=value lines, and every environment, from a laptop to production, has its own copy. This tool compares two .env files and lists the variables that are missing, the values that differ, and the keys defined twice.
Values are read the way the dotenv package reads them: an optional export prefix, single-quoted values kept literally, double-quoted values that expand \n and may span lines, and unquoted values that end at a space followed by #. Keys are compared after that parsing, so formatting differences alone never show as changes.
Key Features
Missing Variables Found Fast
The Missing view lists keys that exist in only one file, which is how a deploy fails for want of a new setting.
Real Value Changes Only
Quoting, spacing and comments are normalized before comparing, so PORT=3000 and PORT = "3000" count as the same value.
Duplicates Called Out
A key defined twice in one file is reported with its line, since only the later value is used and the earlier one silently stops mattering.
Multi-Line Secrets Handled
Private keys and certificates written across several lines in double quotes are read as one value and compared correctly.
Secrets Never Leave the Page
Both files are parsed in your browser and nothing is uploaded, which matters when the values are passwords and API keys.
Perfect for everyone
- Developers syncing .env.example with real environments
- DevOps engineers preparing deploys
- Teams auditing configuration drift between staging and production
How to Use the .env File Diff
Paste two env files, choose what to show, and fix the gaps.
Paste the First File
Usually the reference: .env.example from the repository, or the environment that works.
Paste the Second File
The file to check, such as .env.production or a teammate’s local file. Redact secret values first if you’re sharing your screen.
Choose Missing, Changed or All Keys
Missing lists keys in only one file, Changed lists keys with different values, and All keys lists everything with its status.
Fix the Gaps
Add missing keys to the file that needs them, and check that changed values are intentional, such as a production database URL.
Env Files Compared
Each example is the first file, three dashes, then the second file. The answer is this tool’s report in the mode on the chip, so decide which keys stand out before revealing it.
“PORT=3000 DATABASE_URL=postgres://localhost/app REDIS_URL=redis://localhost --- PORT=8080 DATABASE_URL=postgres://db.internal/app”
“PORT=3000 DATABASE_URL=postgres://localhost/app REDIS_URL=redis://localhost --- PORT=8080 DATABASE_URL=postgres://db.internal/app”
“export NODE_ENV=production PORT = 3000 # local port --- NODE_ENV="production" PORT=3000”
“COLOR=#ff0000 HASH=abc#def --- COLOR="#ff0000" HASH=abc”
“KEY="line1\nline2" --- KEY="line1 line2"”
“GREETING='hello\nworld' --- GREETING="hello\nworld"”
“PORT=3000 DEBUG=true PORT=4000 --- PORT=4000”
“A=1 B=2 --- A=1 B=2”
“DATABASE_URL postgres://localhost/app --- DATABASE_URL=postgres://localhost/app”
“API_KEY=abc --- 2FA_SECRET=xyz”
How .env Values Are Read
There’s no formal .env standard, but most loaders copy the dotenv package. These are the rules this comparison applies before deciding two values differ.
KEY=value Per Line
Each line sets one variable, with the name before the first equals sign. Spaces around the equals sign are ignored.
“What does PORT = 3000 set PORT to?”
Lines Starting With # Are Comments
A line whose first non-space character is # is skipped, which is how .env.example files document each setting.
“Is # PORT=3000 a variable?”
Inline Comments Need a Space
In an unquoted value, a # preceded by whitespace starts a comment. abc#def keeps the # because nothing separates it.
“What is the value of HASH=abc#def?”
Quote Values Containing #
Colours and passwords often contain #. Wrapping the value in quotes keeps everything inside as data.
“How do you set COLOR to #ff0000 safely?”
Single Quotes Are Literal
Inside single quotes nothing is expanded, so a backslash and n stay as two characters.
“Does '\n' in single quotes become a line break?”
Double Quotes Expand \n
Inside double quotes, \n becomes a real line break. That’s how a private key fits on one line.
“Does "a\nb" contain a line break?”
Quoted Values Can Span Lines
A double-quoted value can continue over several lines until the closing quote, which suits PEM certificates.
“Can a value cover several lines?”
export Is Optional
A leading export lets the same file be sourced by a shell. dotenv ignores the word and reads the variable normally.
“Is export PORT=3000 the same as PORT=3000?”
The Last Definition Wins
If a key appears twice, the later line overrides the earlier one. The comparison uses that later value and lists the duplicate.
“PORT=1 then PORT=2. What is PORT?”
Empty Is Not Missing
KEY= sets the variable to an empty string, while leaving the line out doesn’t set it at all. Apps often treat the two differently.
“Is KEY= the same as no KEY line?”
How Different Tools Read .env Files
The common rules hold almost everywhere, but a few loaders differ in ways that matter.
dotenv for Node.js
The reference behaviour used here. It never overrides variables already set in the environment unless told to.
Node.js --env-file
Node 20.6 and later load a .env file natively with --env-file, following dotenv’s rules closely, without the package.
Docker Compose
env_file and the project .env file accept KEY=value lines, and recent versions handle quotes and interpolation like dotenv. Older versions kept quotes as part of the value.
python-dotenv
Follows the same quoting and comment rules and also supports variable expansion such as $HOME and braced forms in values.
Next.js and Vite
Both load .env, .env.local and mode-specific files in a set order, and expose only variables with a public prefix, NEXT_PUBLIC_ or VITE_, to the browser.
Shell source
Sourcing a .env with a shell runs it as a script, so spaces around the equals sign break it and $ expands. Files meant for both should avoid those.
.env Mistakes Worth Catching
Most configuration bugs between environments come from one of these.
Forgetting to Update .env.example
A new variable added locally but not to .env.example breaks the next person’s setup. Compare the two before every merge.
Committing Real Secrets
A .env with production values belongs in a secret manager, not in git. Keep only placeholders in committed files.
Unquoted Hash Signs
A password like pa ss#word is cut at the # because a space comes before it. Quote values that contain # or spaces.
Duplicate Keys
Two definitions of the same key mean the earlier one is ignored, often a leftover from copying blocks between files.
Trailing Spaces in Values
Unquoted values are trimmed by dotenv but not by every loader. Quote values where a trailing space would matter.
Escaped Versus Real Line Breaks
A private key stored with \n in one environment and real line breaks in another is the same value, which this comparison recognises.
Assuming the File Wins
dotenv doesn’t overwrite variables already set by the host or CI. A value in the .env file can be silently ignored in production.
Public Prefixes Exposing Secrets
In Next.js and Vite, a NEXT_PUBLIC_ or VITE_ prefix sends the value to every browser. Keep secrets without those prefixes.
Keeping Environments in Sync
A diff finds drift once. These habits keep it from coming back.
Treat .env.example as the Contract
List every variable the app reads in .env.example, with a placeholder and a comment. Then any environment can be checked against it.
Validate at Startup
Have the app check required variables when it boots, with a schema library such as zod or envalid. A missing key then fails loudly instead of later.
Keep Secrets in a Manager
Store production values in a secret manager or the platform’s settings, and generate the .env only where it’s needed.
Check in CI
A small CI step can compare .env.example with the variables your code references, and fail when a new one is undocumented.
Name Variables Consistently
Upper-case names with underscores and a shared prefix per service, such as PAYMENTS_, make missing and duplicate keys easier to spot.
Comment Why a Value Differs
When staging and production intentionally differ, say so in a comment. The next comparison then explains itself.
When to Compare .env Files
Before deploys, after merges, and whenever an app works in one place but not another.
Before a Production Deploy
Compare .env.example with the production settings to catch a new variable nobody added to the server.
Onboarding a Developer
Check a new teammate’s local .env against the example file to find the setting their app is missing.
Debugging Works on My Machine
Compare a working and a broken environment to find the value that differs, such as a feature flag or a URL.
Reviewing a Pull Request
When a change adds variables, confirm the example file and the deployment config both gained them.
Migrating Hosting Providers
Export variables from the old platform and the new one as .env text, then confirm nothing was lost in the move.
Auditing Staging Against Production
List every key whose value differs, so intentional differences are documented and accidental ones are fixed.
Cleaning Up Old Variables
Keys present only in an old environment are often unused. Confirm in code, then remove them.