Parse dotenv file content into key-value pairs
Dotenv files look simple until values contain spaces, comment characters, empty assignments, or escaped text.
Run — free
This parser turns complete .env file content into a clean object of key-value pairs while applying clear, predictable syntax rules. It ignores blank lines and comments, preserves quoted content, recognizes inline comments on unquoted assignments, and reports the exact line when an assignment is malformed. The result is useful for configuration previews, migration tools, validation steps, and developer utilities that need structured data without loading variables into a process environment.
Provide the complete dotenv text
Paste or submit the contents of a .env file in the text field. Each meaningful line must contain a key, an equals sign, and a value. Keys begin with an ASCII letter or underscore and may continue with letters, digits, or underscores. Blank lines are accepted, and any line whose first non-space character is a hash sign is treated as a comment. Empty assignments such as CACHE_PREFIX= are valid and produce an empty string. The parser returns a values object containing the parsed pairs plus a count of unique keys. If a key appears more than once, the later assignment replaces the earlier one, matching the practical override pattern commonly used when configuration fragments are combined. The parser never writes to the machine environment, expands variables, reads files, or contacts another service. It handles only the text supplied in the request, which makes its behavior safe to preview and straightforward to reproduce in a build script, editor extension, configuration checker, or migration workflow.
Understand quotes, escapes, and comments
Unquoted values have surrounding whitespace removed. A hash sign begins an inline comment only when whitespace appears immediately before it, so URL fragments and tokens such as color=#fff remain intact. Single-quoted values preserve their inner text literally, including hash signs and spaces. Double-quoted values also preserve spaces and hash signs, while interpreting familiar backslash escapes for newline, carriage return, tab, a double quote, and a backslash. After a closing quote, only whitespace or a comment is allowed. These rules remove ambiguity without attempting shell evaluation. The parser does not interpolate references such as ${HOST}, execute command substitutions, or convert strings like true and 8080 into booleans or numbers. Every parsed value remains a string, because dotenv data is textual and callers should decide how application-specific coercion works. This distinction matters when leading zeroes, case, or an intentionally empty value carries meaning that automatic conversion could accidentally destroy.
Handle invalid input deliberately
A nonblank, noncomment line without an equals sign is rejected rather than silently skipped. The same applies to an invalid key, a quoted value without a closing quote, or unexpected characters after a closing quote. Error messages include the one-based line number so a person or automated editor can locate the problem quickly. This strict failure behavior is especially useful before deployment: accepting half of a damaged configuration file can hide a missing setting until an application starts with surprising defaults. Submit the parser result only after the request succeeds, and treat an invalid-input response as a reason to repair the source text. Because parsing is deterministic, the same content always produces the same object and the same malformed line always produces the same error. API requests cost $0.002; the browser runner uses the same pure parsing logic, making it convenient to test syntax interactively before adding the operation to an automated configuration pipeline.
What you can do with it
Validate configuration before deployment
Reject malformed dotenv content early and point the maintainer to the exact line that needs correction.
Preview a configuration migration
Convert legacy .env text into a structured object before mapping its keys into another configuration system.
Power a developer tool
Use predictable key-value output in an editor extension, setup assistant, build utility, or configuration comparison workflow.
FAQ
What does one request cost?
An API request costs $0.002. The browser runner can parse the same content locally.
Are values converted into numbers or booleans?
No. All values remain strings, including values such as 8080, true, false, and empty assignments.
How are duplicate keys handled?
The last assignment wins, and count reports the number of unique keys in the final result.
Can a quoted value contain a hash sign?
Yes. Hash signs inside single or double quotes are part of the value and do not begin a comment.
Does the parser expand variable references?
No. References such as ${HOST} are returned literally; the parser does not evaluate shell or environment expressions.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev2/env-file-parse \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"APP_NAME=\"Example service\"\nDEBUG=true\nPORT=8080\n# Optional local override\nEMPTY="}'const res = await fetch("https://api.kit.forhosting.com/dev2/env-file-parse", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "APP_NAME=\"Example service\"\nDEBUG=true\nPORT=8080\n# Optional local override\nEMPTY="
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev2/env-file-parse",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "APP_NAME=\"Example service\"\nDEBUG=true\nPORT=8080\n# Optional local override\nEMPTY="
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev2/env-file-parse", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"APP_NAME=\\"Example service\\"\\nDEBUG=true\\nPORT=8080\\n# Optional local override\\nEMPTY="}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"APP_NAME=\"Example service\"\nDEBUG=true\nPORT=8080\n# Optional local override\nEMPTY="}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev2/env-file-parse", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "APP_NAME=\"Example service\"\nDEBUG=true\nPORT=8080\n# Optional local override\nEMPTY="
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev2.env_file_parse",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |