.env to JSON Converter

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.

Input
Output

1 .env to JSON Converter example

.env

1
2
3
4
5
6
7
8
9
10
11
12
# 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=

JSON

1
2
3
4
5
6
7
8
9
10
{
  "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": ""
}

2 Quote rules decide what your process receives

Double quotes expand escapes

\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.

Single quotes are literal

\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.

Quote any value that contains #

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.

Everything is a string

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.

3 Comments do not round-trip

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.

How to use the .env to JSON Converter tool

  1. Pick the direction: .env to JSON, or JSON to .env.
  2. Paste the file, or load it with Upload File.
  3. Tick Parse numbers and booleans to turn "5432" into 5432 and "false" into false. Leave it off to keep every value as a string, which is what the environment gives your process.
  4. Click Swap to feed the output back in as input and check that the conversion round-trips.

How to load environment variables in code

Node.js

// 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 / Laravel

<?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.

Python

# 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

Common errors and how to fix them

A password is truncated at the # character
In Node's dotenv, an unquoted # starts a comment. Wrap the value in single quotes: DB_PASSWORD='p@ss#word'.
A multi-line key arrives as one line with literal \n
Use double quotes, where dotenv expands \n into a real newline. Inside single quotes it stays two characters.
DEBUG=false behaves as true
Environment variables are strings, and "false" is a non-empty string. Compare against "true" explicitly, or use a settings library that coerces types.
The variable is missing in production but works locally
The .env file is gitignored, as it should be. Put production values in your platform's secret store instead of a file that has to be copied by hand.
Laravel's env() returns null after deployment
Someone ran config:cache. After that, env() only works inside config files, so read the value with config() everywhere else.

Good to know

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.

Specifications and references

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.

Frequently Asked Questions

Does it work in both directions?

Yes. Pick .env to JSON or JSON to .env in the direction menu, or click Swap to feed the output back in as input.

How are quotes handled?

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.

What happens to comments and blank lines?

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.

Are values with spaces or # quoted correctly?

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.

Is it safe to paste a real .env here?

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.

Related

For other config formats, use the YAML and JSON formatters. A value that arrives Base64-encoded can be unwrapped with the Base64 decoder.

More Data Converters

Browse all data converters

Copied to clipboard!