Convert a .env file to JSON, or a JSON object back
into .env lines. The parser follows the dotenv quote rules, and on
the way back it wraps any value containing a space, #,
quote or newline in double quotes so it reads back unchanged.
# Application
APP_NAME="Checkout API"
APP_ENV=production
APP_DEBUG=false
# Database
DB_HOST=127.0.0.1
DB_PORT=5432
DB_PASSWORD='p@ss#word'
GREETING="Hello\nWorld"
EMPTY= {
"APP_NAME": "Checkout API",
"APP_ENV": "production",
"APP_DEBUG": "false",
"DB_HOST": "127.0.0.1",
"DB_PORT": "5432",
"DB_PASSWORD": "p@ss#word",
"GREETING": "Hello\nWorld",
"EMPTY": ""
} \n inside double quotes becomes a real newline. That is how a multi-line private key fits in one environment variable, and why it breaks when someone switches to single quotes.
\n inside single quotes stays as a backslash and an n. Use single quotes for passwords full of symbols, where you want every character kept as typed.
Loaders disagree on unquoted hashes. Node's dotenv treats any # as the start of a comment, so DB_PASSWORD=p@ss#word loads as p@ss. This tool only cuts at a # that follows a space. Quote the value and every loader agrees.
Environment variables have no types, so DB_PORT=5432 is the text "5432". Tick Parse numbers and booleans to get real numbers, true, false and null in the JSON. Your process still receives strings.
JSON has no syntax for comments, so going to JSON drops every
comment and blank line. Going back the other way gives you keys
in object order with no comments. Keep the original file
when its comments document the settings, as a good
.env.example does, and use the conversion for the
values only.
The conversion runs in JavaScript on this page, so nothing is uploaded. However, we recommend keeping production secrets out of every tool, including this one. Work out the shape with placeholder values, then fill in the real ones in your secret store.
// Node 20.6+ reads it natively, no package needed
// node --env-file=.env app.js
// Or the classic:
// npm i dotenv
require("dotenv").config();
// Everything is a string, always
const port = Number(process.env.PORT ?? 3000);
const debug = process.env.DEBUG === "true"; // "false" is truthy as a string
// Fail loudly at boot rather than mysteriously later
for (const key of ["DATABASE_URL", "SESSION_SECRET"]) {
if (!process.env[key]) throw new Error(`Missing ${key}`);
} Every process.env value is a string, and the string "false" is truthy. Writing if (process.env.DEBUG) turns debug mode on for DEBUG=false, so compare against "true" explicitly.
<?php
// composer require vlucas/phpdotenv
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
$dotenv->required(['DB_HOST', 'DB_PASSWORD'])->notEmpty();
$port = (int) ($_ENV['DB_PORT'] ?? 5432);
// In Laravel, env() should only ever be called from config files.
// Once config is cached, env() returns null everywhere else and the
// app breaks in production only. Read config('database.port') instead. # pip install python-dotenv
import os
from dotenv import load_dotenv
load_dotenv()
port = int(os.getenv("DB_PORT", "5432"))
debug = os.getenv("DEBUG", "false").lower() in ("1", "true", "yes")
# pydantic-settings validates and coerces at startup instead
# pip install pydantic-settings
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
db_host: str
db_port: int = 5432
debug: bool = False
settings = Settings() # raises if db_host is missing The .env format has no specification. dotenv in Node, phpdotenv, python-dotenv and Docker Compose each parse it slightly differently, mainly around quoting, escapes, multi-line values and export prefixes. For example, a file can load correctly in Docker Compose and break in phpdotenv with neither loader at fault. Quote anything unusual and keep one value per line to stay inside the common subset.
This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.
Yes. Pick .env to JSON or JSON to .env in the direction menu, or click Swap to feed the output back in as input.
Single and double quotes around a value are stripped, the way dotenv does it. Inside double quotes, \n becomes a real newline, while inside single quotes it stays literal. That difference explains why a multi-line private key loads correctly in one file and breaks in another.
Going to JSON they are dropped, because JSON has no syntax for comments. Going the other way, keys come out in object order with no comments added.
Yes. A value containing a space, #, quote, $, backslash or newline is wrapped in double quotes on the way out, with inner quotes and newlines escaped, so it reads back unchanged.
The conversion runs in JavaScript on this page and nothing is uploaded. However, we recommend keeping production secrets out of every tool, browser-based or not. Use placeholder values while you work out the shape.
For other config formats, use the YAML and JSON formatters. A value that arrives Base64-encoded can be unwrapped with the Base64 decoder.