JSON

.env file

Going from JSON back to an environment file

This is the direction people need when configuration already exists somewhere structured — a secrets manager export, a Terraform output, a chunk of a Helm values file — and something downstream wants a plain .env. Paste the object, get the file.

The part worth getting right is quoting. A value only needs quotes when it contains something that would otherwise change its meaning: whitespace, a # that would start a comment, a quote character, or a newline. Quoting everything is safe but produces a file that looks machine-written and is annoying to read; quoting nothing produces a file that breaks on the first value with a space in it. This page quotes exactly what needs quoting, and escapes what it quotes.

Nesting is the other question, and there is no correct answer — which is why this page refuses to invent one. A .env is a flat map of strings; that is all the environment is at the operating-system level, as the POSIX definition of the environment makes plain. So a nested object could become DB__HOST, or DB_HOST, or DB.HOST — three real conventions used by three different frameworks. Picking one here would hand you a file your own loader disagrees with, so nested values are written as compact JSON in the value instead. That survives a round trip and is unambiguous about what it is.

Everything runs in the browser. Nothing is uploaded, which matters because the JSON you paste here is often a secrets export.

How to use it

  1. Paste a JSON object – A flat object of string, number and boolean values is the common case. Nested objects and arrays are handled too, as JSON inside the value.
  2. Read the .env on the right – One KEY=value per line, in the order the object listed them, with quoting applied only where it is needed.
  3. Turn on the toggles if your setup wants them – The export prefix makes the file sourceable by a shell. Uppercasing follows the usual convention for environment variable names.
  4. Check for skipped keys – A JSON key with a hyphen or a space in it cannot be an environment variable name. Those are listed rather than silently mangled.
  5. Download or copy – Save it as .env, or paste it into whatever wanted the file.

If a value comes out unquoted and you expected quotes, that is deliberate — PORT=5432 and PORT="5432" load to exactly the same string, and the shorter one reads better. The quoting here exists to preserve meaning, not to decorate. Paste the result into .env to JSON to confirm you get your original object back.

What gets quoted, and why

Five of the eight values below are written without quotes because nothing in them needs protecting. The banner is quoted because it contains spaces. The note is quoted because a bare "#" would start a comment. The nested "database" object becomes JSON in the value, and the empty string is quoted so the line does not look like a key with nothing after it by accident.

network KPI collectorJSON to .env
config.json8 keys
{
  "NODE_ENV": "production",
  "PORT": 8080,
  "BANNER": "network KPI collector",
  "RUNBOOK_NOTE": "alerts muted # see runbook 41",
  "ROAMING_ENABLED": true,
  "MAINTENANCE_MESSAGE": "",
  "database": { "host": "kpi-db.internal" }
}
.envquoted where needed
NODE_ENV=production
PORT=8080
BANNER="network KPI collector"
RUNBOOK_NOTE="alerts muted # see runbook 41"
ROAMING_ENABLED=true
MAINTENANCE_MESSAGE=""
database="{\"host\":\"kpi-db.internal\"}"
# quotes only where the value needs them

When this comes up

A secrets manager export that needs to be a file

Vault and AWS Secrets Manager both hand back JSON. A local process, a Docker container or a CI step frequently wants .env instead. This is the two-second version of that conversion.

Seeding a new service from an old one

Convert the working service's file with .env to JSON, edit the object — rename the service, change the ports, drop the keys that do not apply — and convert it back. Editing structured data is far less error-prone than editing 60 lines of text.

Filling in a container environment

Compose's env_file reads exactly this format, and so does kubectl create configmap --from-env-file. Generating the file from a checked-in JSON document keeps one source of truth instead of two.

What it does with the awkward cases

  • Quotes a value only when it contains whitespace, a quote, a #, a backslash or a newline — and escapes it properly when it does.
  • Writes null as an empty value rather than the four characters null, which would be a string your code has to special-case.
  • Serialises a nested object or array as compact JSON in the value, instead of guessing at a flattening convention your loader may not share.
  • Names any key that is not a legal environment variable name rather than mangling it into one.
  • Optional export prefix for a file meant to be sourced by a shell.
  • Optional uppercasing, which is convention rather than a rule — nothing at the OS level cares.
  • Round-trips: converting back through .env to JSON returns the same values.

Questions worth answering

Why are my nested objects not flattened into DB_HOST style keys?

Because there are at least three conventions in active use and no way to tell which one you need. Spring Boot reads DB_HOST, several Node config libraries read DB__HOST, and others use a dotted form. Emitting one of those would produce a file that looks right and loads wrong. Compact JSON in the value is honest about the shape and survives a round trip. If you want a specific flattening, flatten the object before pasting it — then the convention is yours and visible.

Can I put a multi-line value like a private key in here?

Yes — a newline inside a value is written as \n inside a double-quoted string, which is how private keys normally live in a .env. Loaders expand it back. What you should not do is paste the key across several real lines in the file, because loaders disagree about whether that is legal.

Do numbers stay numbers?

They become text, because an environment variable can only be text. {"port": 5432} becomes port=5432, and the process reading it gets the string "5432". This is the same reason the reverse tool does not guess types on the way in.

Is a .env file a sensible place for secrets?

For local development it is the path of least resistance and everybody uses it. For anything deployed, the twelve-factor argument is that configuration should come from the environment the platform provides, and secrets specifically should come from a managed store. The practical risk with a file is not sophisticated: it is that .env is one missing .gitignore line away from being in your repository history forever.

What order do the keys come out in?

The order the JSON object listed them. JSON object keys have no guaranteed order in the specification, but every mainstream parser preserves insertion order for string keys, so what you paste is what you get. If you want them sorted, sort them on the way in with .env to JSON's sort option and convert back.

Related tools

Further reading

  • dotenv – The loader whose behaviour most .env conventions are measured against.
  • Kubernetes ConfigMaps – How the same flat key-value idea is expressed once configuration leaves the filesystem.