</>DevTools

ENV.env Parser

Parse and edit .env files

.env File Syntax and What to Know About Environment Variables

A .env file is a simple format: one KEY=value per line. But no official standard defines that simplicity, so details like quoting and multi-line values behave differently across libraries. This tool breaks pasted .env content into key-value pairs so you can see what a parser actually reads.

Basic syntax

By convention keys use only uppercase letters and underscores, because they must be exportable as shell environment variables — a key containing a hyphen can't be handled by a shell. Avoid spaces around the equals sign too: written as KEY = value, some parsers produce the key "KEY " and others the value " value".

A typical .env file
# comments start with #
NODE_ENV=production
PORT=3000

# quote values containing spaces
APP_NAME="My Application"

# empty values are valid
OPTIONAL_FLAG=

# values full of special characters, like URLs
DATABASE_URL=postgres://user:pass@localhost:5432/mydb

# multi-line values (only in parsers that support them)
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBg...
-----END PRIVATE KEY-----"

How to use it

  1. Paste your .env content.
  2. Review the parsed key-value list — confirm each value is what you intended and that quotes aren't part of the value.
  3. If a value looks truncated, check the quoting and special-character section below.
  4. Copy the results into your code or deployment configuration.

When quoting is needed, and its side effects

The most common real incident involves $ and # inside passwords. Some parsers expand $VAR as a reference to another variable and discard everything after a #, so the password is silently truncated and shows up as an authentication failure — and since you don't log passwords, diagnosing it takes a long time. Wrapping values with special characters in single quotes is the safest choice.

Written asParses toNotes
KEY=hellohelloThe simplest form
KEY="hello world"hello worldThe quotes are stripped
KEY=hello worldhello world or helloParser-dependent — use quotes
KEY="line1\nline2"A value containing a newline\n is interpreted only in double quotes
KEY='line1\nline2'The literal text line1\nline2Single quotes don't interpret escapes
KEY=value # commentvalue, or value # commentInline comment support varies
KEY=pa$$wordpa, or pa$$word$ may be treated as variable expansion

Environment variables are only ever strings

At the OS level an environment variable's value is always a string, and that produces a classic bug. Setting DEBUG=false still gives you the string "false" in process.env.DEBUG, and since any non-empty string is truthy in JavaScript, if (process.env.DEBUG) passes. Numbers behave the same way: PORT=3000 is "3000", so arithmetic silently becomes string concatenation.

The recommended pattern is to validate and coerce all of them in one place at startup. Defining a schema with zod or envalid means the application dies with a clear error at boot when a required value is missing — far better than behaving strangely mid-run because something was undefined.

Validate at startup
import { z } from "zod";

const env = z.object({
  NODE_ENV: z.enum(["development", "production", "test"]),
  PORT: z.coerce.number().default(3000),
  DEBUG: z.stringbool().default(false),
  DATABASE_URL: z.string().url(),
}).parse(process.env);

// downstream, env.PORT is a real number
export default env;

Precedence and multiple files

Most libraries will not overwrite a real environment variable that is already set with a value from a .env file — so anything exported in your shell or injected into your container wins. That's deliberate: in a deployed environment, platform-injected values should take precedence over files.

There's also a convention of splitting files: .env for shared defaults, .env.local for personal machine-specific settings (not committed), and .env.production for per-environment values. Tools like Next.js and Vite define a fixed load order, so when a value isn't what you expect, work out which file won.

Security essentials

  • Put .env in .gitignore, and commit a .env.example listing the key names with empty values so the team knows what's required.
  • If it's already committed, removing it from history isn't enough — rotate the exposed credentials immediately. If the repo was ever public, assume automated scanners already have them.
  • Know which variables are exposed to the client. Values prefixed NEXT_PUBLIC_ (Next.js) or VITE_ (Vite) are embedded in the browser bundle, so putting a secret behind that prefix publishes it instantly.
  • Production secrets belong in a secret manager (AWS Secrets Manager, GCP Secret Manager, Vault) rather than a file, which gives you access auditing and rotation.
  • Never dump environment variables into CI logs. Output from env or printenv exposes them to everyone with log access.

Frequently Asked Questions

Is what I paste sent to a server?
No, parsing happens in your browser. Even so, don't paste a .env holding real production credentials into a third-party site. If you're checking syntax, substitute dummy values first.
How do I put a newline in a value?
Where the parser supports it, wrap in double quotes and either embed a real newline or use a \n escape. Because support varies, multi-line values like RSA private keys are commonly Base64-encoded into a single line and decoded in code instead. When entering values directly in a platform's UI, multi-line input usually works as-is.
My value gets cut off at a # character.
It was read as an inline comment. Wrapping the whole value in quotes fixes it. For passwords containing #, $, spaces, or quotes, single quotes are the most predictable choice.
Why aren't my .env values taking effect?
Check in this order: is the file in the process's working directory (running from a subdirectory won't find it)? Does the loading code run before your other imports? Is a same-named variable already set in the shell and winning? And is the filename exactly right — saving as .env.txt is a common slip.
Can keys contain hyphens?
Some parsers accept them, but don't. Hyphenated names can't be exported as shell environment variables, which breaks portability between tools. Underscores are both the convention and the practical choice.
Is an empty value different from an undefined one?
Yes. KEY= sets an empty string; omitting it leaves undefined. In JavaScript, process.env.KEY ?? "default" preserves an empty string while process.env.KEY || "default" replaces it. That distinction causes surprises, so decide which behavior you want.

💡 Note: When a value seems wrong, check the parse result here first. Usually the quotes ended up inside the value, or it was truncated at a special character.

🔗Related Tools🧰 Misc