Compare two .env files by key

Paste .env.example and .env to see which keys are missing, extra, empty or duplicated. Values stay hidden unless you ask to see them.

How it works

  1. Paste the template file into A and your real file into B
  2. Read the table of missing, extra, empty and duplicate keys
  3. Copy the missing keys as a KEY= block and paste it into your .env

What the comparison does

To compare two .env files, paste the template (for example .env.example) into File A and your real file into File B, and the tool lists every key and whether it is missing in B, extra in B, empty in B or set more than once. Only keys are compared, never values. Each key gets one row with a Yes or No for each file and a status. Missing in B means A has the key and B does not. Extra in B means B has a key that A does not list. Empty in B means the key is there but has no value, for example SESSION_SECRET=. Duplicate means the key appears twice in one file; the later line wins, as in dotenv, and the warning names the lines. Worked example with the sample: A has 9 keys and B has 7. REDIS_URL, SMTP_HOST and FEATURE_FLAGS are missing in B, DEBUG is extra, SESSION_SECRET is empty in B, and PORT is set twice in B (lines 3 and 8), so 4000 wins. The copyable block for the three missing keys is the lines REDIS_URL=, SMTP_HOST= and FEATURE_FLAGS=, in the order they appear in A.

Which syntax it understands

Blank lines and lines that start with # are skipped. An optional export prefix is accepted, so export PORT=3000 is the key PORT. A key is letters, digits, underscore, dot and dash, and does not start with a digit. An unquoted value ends at the end of the line or at a space followed by #, so URL=http://localhost/#top keeps its hash but KEY=abc # note does not. Values in double quotes, single quotes or backticks may contain # and may run over several lines. In single quotes and backticks a backslash before the same quote keeps the quote in the value, so 'Let\\'s go' works. Only double quotes read the escapes \n, \r, \t, \" and \\. A line that does not fit is reported by its line number and skipped, and its text is not shown. That covers a key with no equals sign, a bad key, and extra text after a closing quote. An opening quote with no closing quote within 200 lines stops the comparison with an error that names the line, because the lines after it may be part of the value and are not read as keys. A bare KEY with no equals sign, which Docker Compose reads as a pass-through variable, is reported too. Keys are case-sensitive unless you switch that off, and then Port and PORT count as one key. A byte-order mark at the start is ignored.

Values stay out of the way

The table has no value columns until you turn on Show values, and it is off until you turn it on. When it is on, each file gets a value column, with line breaks in a value shown as \n. The copyable missing-keys list, the Download and the warnings never contain a value, and warnings never repeat the text of a line that failed to parse. Empty is decided on the parsed value: KEY=, KEY="" and KEY= # note are all empty, while KEY=" " is not. This tool does not check that a value is correct or secret-safe, does not compare values between the files, and cannot tell whether a key is required by your code. A key that is missing in B may be optional, and a key that is extra in B may be read by code the template forgot to list.

Limits and what happens to your files

Each file can hold up to 1,000,000 characters. The table draws the first 2,000 keys and says so; the missing-keys block always lists every missing key. The work is done by your browser in this tab and nothing is uploaded. The page saves the three option switches on your device, never the text. Show values is one of them, so it is kept if you turn it on and you can turn it off again at any time. The result follows dotenv rules as described here, but different tools differ in small ways: Docker Compose, Node and Python each handle some edge cases differently, such as interpolation with ${OTHER}, which this page does not expand.

Frequently asked questions

How do I compare my .env with .env.example?

Paste .env.example into File A and .env into File B. The table lists each key with its status, such as Missing in B or Extra in B, and the Missing in B box holds a block like REDIS_URL= and SMTP_HOST= that you can paste into your .env and fill in. Turn on Hide keys that match to see only the differences.

Does it show my secret values?

No, not unless you turn on Show values, which is off by default. The table, the copied missing-keys list, the downloaded .env and the warnings carry key names and line numbers only. Even with Show values on, nothing is added to the copy or download output.

What happens when a key appears twice in the same file?

The later line wins, as it does in dotenv, and the tool shows a warning such as File B: PORT is set 2 times (lines 3, 8). The last one wins. The row gets the status Duplicate in B. The earlier value is ignored, so a PORT=3000 on line 3 is overridden by PORT=4000 on line 8.

Why is a line reported as not a KEY=value line?

It has no equals sign, the key starts with a digit or holds a space, or there is text after the closing quote. A quote that is never closed stops the comparison with an error that names the line. For example, a line with only DEBUG is reported as line N and skipped. The report gives the line number and never repeats the line, because it may hold a secret.

Does it handle quoted values with a # or several lines?

Yes. In FEATURE_FLAGS="beta # on, search" the # is part of the value because it is inside quotes. A value in double quotes can run over up to 200 lines, and the key counts once. Without quotes, a space followed by # starts a comment, so KEY=abc # note has the value abc.

Are my .env files uploaded?

No. The text is processed in your browser and is not uploaded. The two files stay in this tab. The page saves only its three option switches on this device, never the text, and it does not send keys or values anywhere.