Skip to content
Voltar ao blog
Tutoriais

Arquivos .env explicados: parsing, conversão JSON e config

Guia prático de arquivos .env: o formato dotenv e suas regras de parsing, quando converter entre .env e JSON, e como validar sua configuração.

9 min de leitura

Arquivos .env explicados: parsing, conversão JSON e config

Um arquivo .env é uma lista de texto puro com pares KEY=VALUE que mantém configuração e segredos fora do seu código-fonte. É o formato que Node, Vite, Next.js, Python, Ruby e Docker Compose carregam para dentro do ambiente do processo. Se você está pesquisando por env to json, normalmente quer uma de duas coisas: transformar um .env em JSON estruturado para ferramentas, ou entender as regras bem o suficiente para fazer isso sem se queimar.

Três coisas costumam confundir as pessoas, então vamos resolvê-las logo de cara:

  1. Um arquivo .env é plano. Não existe aninhamento. Toda chave fica no nível de topo.
  2. Todo valor é uma string. O dotenv nunca faz coerção de tipos. PORT=8080 é carregado como "8080", não como 8080.
  3. A gramática é informal. Não há especificação formal, então os loaders divergem nas bordas: aspas, comentários, escapes.

Este guia cobre as regras de parsing do dotenv, o mapeamento .env↔JSON (e por que você converteria em qualquer direção), uma matriz de decisão sobre quando usar .env em vez de JSON, e como validar sua configuração antes de ela ir para produção. Tudo o que está descrito aqui roda no Conversor ENV para JSON inteiramente no seu navegador, então mesmo um .env cheio de credenciais reais nunca sai da página.

O que é um arquivo .env?

O arquivo .env é o padrão de fato para configuração de ambiente. A biblioteca dotenv, e seus ports para praticamente toda linguagem, lê o arquivo e injeta cada par no processo em execução. Seu app então lê process.env.DATABASE_URL em vez de fixar a string de conexão no código. Como o arquivo guarda senhas de banco de dados, chaves de API, segredos OAuth e tokens de acesso, ele quase sempre fica no git-ignore e é tratado como sensível.

Anatomia de uma linha

Cada linha relevante é um par KEY=VALUE, dividido no primeiro sinal de =. Linhas de comentário e linhas em branco são ignoradas, e um prefixo export opcional é removido:

# Database — this whole line is a comment
DATABASE_URL=postgres://user:pass@localhost:5432/mydb
DATABASE_POOL_SIZE=10

# A blank line above is ignored
export DEPLOY_ENV=production   # the `export` prefix is removed
JWT_SECRET="super secret value"

A chave é tudo que vem antes do primeiro =, sem os espaços ao redor. O prefixo export existe para que o arquivo possa receber source diretamente em um shell, e os loaders do dotenv o removem automaticamente. Dividir no primeiro = importa porque valores como DATABASE_URL muitas vezes contêm seus próprios caracteres = em query strings.

Por que a config mora no ambiente

O raciocínio vem do Twelve-Factor App, que diz para armazenar a config no ambiente. A config muda a cada deploy (dev, staging, produção) enquanto o código permanece o mesmo. Mantê-la no ambiente significa que você troca o host de um banco de dados sem editar nem reimplantar o código-fonte, e o mesmo build roda em todos os lugares.

Uma leitura equivocada comum: as pessoas citam “config nunca em um arquivo” e concluem que .env é proibido. A regra real é mais estreita. A config não deveria ser um arquivo commitado dentro do app, misturado com código e versionado. Um .env local, no git-ignore, para desenvolvimento é correto e padrão. O que você evita é enviar um .env real para produção com segredos embutidos.

Regras de parsing do .env (os casos de borda em que as ferramentas divergem)

Como não há especificação formal contra a qual fazer parse a .env file, cada loader toma suas próprias decisões nos limites. As regras abaixo são as convenções amplamente seguidas do dotenv, as que o conversor implementa e com as quais a maioria dos runtimes concorda.

Aspas e escapes

Como um valor é aspeado muda tudo:

  • Aspas duplas processam sequências de escape. \n vira uma quebra de linha, \t uma tabulação, \r um retorno de carro, \\ uma barra invertida e \" uma aspa dupla literal. Um valor entre aspas duplas também pode se estender por várias linhas até a aspa de fechamento, que é como chaves privadas PEM cabem em um .env.
  • Aspas simples são literais. Nenhum processamento de escape acontece, exatamente como no shell. 'no \n escapes here' mantém a barra invertida e o n literalmente.
  • Valores sem aspas vão até o fim da linha, com o espaço em branco no final removido. Um # inline (um espaço seguido de uma cerquilha) inicia um comentário que é descartado.

Essa última regra pega as pessoas com cores hexadecimais. COLOR=#ff0000 perde tudo depois do #. Coloque entre aspas, COLOR="#ff0000", e o valor sobrevive.

Tudo é uma string

Este é o fato mais importante sobre o dotenv format. PORT=8080 não é carregado como o número 8080. É carregado como a string "8080", porque os valores de process.env são sempre strings em tempo de execução. O dotenv nunca faz coerção de tipos.

Isso causa bugs reais. if (process.env.DEBUG) é truthy mesmo quando DEBUG=false, porque "false" é uma string não vazia. Comparações numéricas falham silenciosamente porque "8080" não é 8080. Qualquer recurso de “inferir tipos”, incluindo o toggle no conversor, é uma camada de conveniência adicionada por cima do dotenv, não parte do padrão. Use-a de forma deliberada, sabendo que o JSON então vai diferir do que seu app de fato recebe.

Chaves duplicadas, valores multilinha e interpolação

Quando a mesma chave aparece duas vezes, a última ocorrência vence. O valor anterior é descartado silenciosamente. Essa é uma armadilha frequente de má configuração: uma duplicata perdida perto do fim de um arquivo longo silenciosamente sobrepõe o valor que você pretendia usar. Um bom conversor sinaliza duplicatas com um aviso em vez de engoli-las.

Valores multilinha funcionam apenas dentro de aspas duplas, quebrando por várias linhas até o " de fechamento. Já a interpolação ${VAR}, ou seja, referenciar uma variável a partir de outra, existe em alguns loaders, mas não é universal. Não dependa dela entre runtimes; um arquivo que interpola bem em uma stack pode carregar a string literal ${VAR} em outra.

Regras de parsing em resumo

Linha de entradaValor parseadoRegra
PORT=8080"8080"Sem aspas, mantido como string (sem coerção de tipo)
APP_NAME=My App # title"My App"Sem aspas: comentário inline # removido, espaço final cortado
GREETING="Hello,\nWorld"Hello,⏎WorldAspas duplas processam \n como quebra de linha real
LITERAL='no \n escapes'no \n escapesAspas simples são literais, sem processamento de escape
COLOR=#ff0000""# sem aspas inicia um comentário; o valor se perde, então coloque entre aspas
export AWS_REGION=us-east-1us-east-1Prefixo export removido
EMPTY=""Valor vazio é uma string vazia válida

.env vs JSON na config: quando usar cada um

A resposta honesta não é “JSON é melhor”. Eles resolvem problemas diferentes. Um arquivo .env é plano, só de strings, aceita comentários e funciona por ambiente, feito para segredos e overrides em tempo de deploy. JSON é aninhado, tipado e estruturado, mas não tem comentários e é fácil de commitar sem querer. Escolher entre eles é a verdadeira decisão env vs json config.

O que o .env não consegue fazer

Um .env não consegue aninhar, não consegue guardar arrays e não consegue carregar tipos de verdade. É uma lista plana de strings. Se sua config é naturalmente agrupada, você a achata com uma convenção de prefixo em vez de aninhar: DB_HOST e DB_PORT no lugar de um objeto db. As chaves permanecem planas, e você remonta o agrupamento no código.

Em que o JSON é melhor

JSON ganha quando estrutura é o ponto: objetos aninhados, arrays e números, booleanos e null reais. É o formato que você valida contra um schema e o que você usa para gerar tipos. Se você precisa de uma hierarquia que um arquivo plano não consegue expressar, JSON (ou YAML, coberto abaixo) é a ferramenta certa.

Matriz de decisão

Necessidade.envJSONPor quê
Segredos / credenciais⚠️.env fica no git-ignore por convenção; config em JSON é fácil de commitar sem querer
Overrides por ambiente⚠️Um .env por ambiente é o padrão de deploy
Estrutura aninhada.env é plano; JSON aninha nativamente
Valores tipados (número/bool/null)Valores de .env são sempre strings; JSON tem tipos reais
Comentários inline.env suporta #; JSON não tem sintaxe de comentário
Validação por schema⚠️Valide depois de converter .env→JSON; JSON valida diretamente

Convertendo .env para JSON e de volta

Converter em qualquer direção é mecânico depois que você conhece as regras. O mapeamento é 1:1 no nível de topo, com cada linha KEY=VALUE virando uma propriedade JSON, e a única sutileza está nos tipos e no aninhamento.

.env → JSON

Cada par KEY=VALUE vira uma propriedade JSON. Por padrão, todo valor é uma string, fiel ao que o dotenv carrega em tempo de execução; um toggle opcional de inferência de tipos promove números, booleanos e null sem aspas. O resultado é um objeto plano. Você faria isso para alimentar a config em ferramentas que só aceitam JSON, importar em massa para um gerenciador de segredos, validar contra um schema, ou só ler um .env extenso como dados estruturados. O Conversor ENV para JSON faz exatamente isso no navegador, com um aviso quando detecta chaves duplicadas.

JSON → .env

O caminho inverso aceita apenas um objeto: um array no topo ou um escalar solto não tem nomes de chave para mapear em variáveis. Números e booleanos são escritos sem aspas (PORT=8080), null vira um KEY= vazio, e qualquer string que contenha um espaço, #, quebra de linha ou aspa é automaticamente colocada entre aspas duplas e escapada para fazer o round-trip com segurança. Objetos e arrays aninhados não cabem em um arquivo plano, então cada um é serializado para uma string JSON e sinalizado com um aviso. Chaves opcionais normalizam as chaves para UPPER_SNAKE_CASE e adicionam um prefixo export. O Conversor JSON para ENV cuida de tudo isso.

Segurança no round-trip e a ressalva do aninhamento

O auto-aspeamento existe para que um valor sobreviva ao ciclo .env → JSON → .env inalterado. Veja o round-trip como código executável, condizente com o comportamento dos conversores; note que PORT permanece uma string durante todo o ciclo, exatamente como o dotenv carregaria:

import { parse } from 'dotenv';

// 1. Start with a .env file as text
const envText = `DATABASE_URL=postgres://user:pass@localhost:5432/mydb
PORT=8080
GREETING="Hello, World"
NOTE="value with # hash"`;

// 2. .env -> JSON (dotenv.parse returns string values only)
const config = parse(envText);
console.log(JSON.stringify(config, null, 2));
// {
//   "DATABASE_URL": "postgres://user:pass@localhost:5432/mydb",
//   "PORT": "8080",
//   "GREETING": "Hello, World",
//   "NOTE": "value with # hash"
// }

// 3. JSON -> .env (quote only strings that need it)
const needsQuotes = (s) => /[\s#"'\n]/.test(s);
const env = Object.entries(config)
  .map(([key, value]) =>
    needsQuotes(value) ? `${key}=${JSON.stringify(value)}` : `${key}=${value}`
  )
  .join('\n');

console.log(env);
// DATABASE_URL=postgres://user:pass@localhost:5432/mydb
// PORT=8080
// GREETING="Hello, World"
// NOTE="value with # hash"

O detalhe é o aninhamento. O round-trip é sem perdas para config plana, mas uma estrutura profundamente aninhada só consegue passar pelo .env como strings JSON opacas, ilegíveis para qualquer app que espere a estrutura de volta. Se sua config é genuinamente hierárquica, recorra ao YAML. O conversor YAML para JSON e o guia do problema Norway do YAML cobrem esse caminho e suas próprias arestas.

Validando a configuração de ambiente

Uma variável de config faltando ou malformada não deveria aparecer como um undefined is not a function às 3 da manhã em produção. A abordagem Twelve-Factor é falhar rápido, verificando a config antes do deploy, não depois. Converter .env para JSON torna isso prático, porque o JSON tem ferramentas de validação maduras que variáveis de ambiente cruas não têm.

Valide por schema na CI

Converta .env → JSON e então valide o JSON contra um schema que declara chaves obrigatórias, enums permitidos e formatos de valor. Um ambiente mal configurado, seja um DATABASE_URL faltando, um LOG_LEVEL inválido ou uma porta que não é número, falha na verificação da CI em vez de no deploy. O guia de Validação com JSON Schema mostra como escrever o schema, e o Validador JSON Schema o executa no navegador.

Config tipada

Além de checar presença, você pode derivar um objeto de config tipado para que process.env.PORT não seja uma string sem tipo espalhada pela base de código. Valide e faça a coerção na inicialização com uma biblioteca de schema em runtime como o Zod, ou gere uma interface TypeScript a partir do JSON e leia a config por ela. O guia JSON para TypeScript e o conversor JSON para TypeScript cobrem a etapa de geração. Formate ou confira o JSON primeiro com o Formatador JSON para que uma surpresa estrutural apareça cedo.

Higiene de segredos: lidando com um .env com segurança

Um .env é, na prática, uma lista de credenciais. Trate-o como tal.

Nunca commite .env. Adicione-o ao .gitignore. Commite um .env.example que liste cada chave com valores vazios ou de placeholder, tipo DATABASE_URL= em vez da string de conexão real. Esse arquivo é o contrato da equipe: documenta de quais variáveis um novo clone precisa sem vazar nenhuma delas.

.env é para local e dev; produção usa um gerenciador de segredos. Ferramentas como Vault, Doppler e AWS Secrets Manager injetam segredos no ambiente em tempo de deploy. Não envie um .env real com segredos ativos para um host de produção. Busque-os do gerenciador, para que um arquivo vazado ou um container mal configurado não entregue suas chaves.

Só converta segredos em uma ferramenta que roda apenas no navegador. Colar um .env real em um conversor server-side envia suas credenciais pela rede para a máquina de outra pessoa. Os dois conversores aqui rodam inteiramente no seu navegador, então abra a aba Network do DevTools e confirme que colar dispara zero requisições. É essa diferença que torna seguro converter um .env de produção em vez de uma amostra higienizada.

FAQ

Como converto um arquivo .env para JSON?

Cole o arquivo no Conversor ENV para JSON e ele faz o parse para JSON instantaneamente no seu navegador. Cada linha KEY=VALUE vira uma propriedade. Os valores são strings por padrão (condizente com o dotenv); ative a inferência de tipos se quiser números e booleanos. Nada é enviado, então segredos reais ficam no seu dispositivo.

Valores de .env são números e booleanos, ou strings?

Sempre strings. O dotenv nunca faz coerção de tipos: em tempo de execução, todo valor de process.env é uma string, então PORT=8080 é "8080" e DEBUG=false é a string "false" (que é truthy). Qualquer opção de “inferir tipos” é uma camada de conveniência adicionada por cima do padrão, não parte do dotenv em si.

Qual é a diferença entre um arquivo .env e um arquivo de config JSON?

Um .env é plano, só de strings, aceita comentários e foi feito para segredos e overrides por ambiente. JSON é aninhado e tipado, com números, booleanos e null reais, e valida contra um schema, mas não tem comentários e é fácil de commitar sem querer. Use .env para segredos, JSON para config estruturada.

Um arquivo .env pode ter valores aninhados ou agrupados?

Não. Um .env é uma lista plana de pares KEY=VALUE sem aninhamento e sem arrays. Para expressar agrupamento, achate com uma convenção de prefixo (DB_HOST e DB_PORT em vez de um objeto db) e remonte a estrutura no código. Se você realmente precisa de hierarquia, use JSON ou YAML.

Como aspas, # e valores multilinha são tratados no .env?

Aspas duplas processam escapes (\n, \t, \\, \") e podem se estender por várias linhas até a aspa de fechamento. Aspas simples são literais, sem escapes. Valores sem aspas vão até o fim da linha, cortam o espaço em branco final e tratam um espaço-mais-# como comentário inline, então coloque entre aspas qualquer valor que contenha legitimamente um #.

Devo commitar meu arquivo .env no Git?

Não. Adicione .env ao .gitignore e commite um .env.example listando as chaves com valores vazios. O arquivo real guarda senhas de banco de dados, chaves de API e tokens; commitá-lo vaza credenciais para o seu histórico, onde elas persistem mesmo depois de você apagar o arquivo.

Tags: Environment Variables JSON Configuration Security

Artigos relacionados

Ver todos os artigos