INI / .properties ↔ JSON Converter
FormatEverything runs locally in your browser — nothing is uploaded
Turn a config file — INI, `.properties`, `.conf` — into JSON, or the reverse. Both dialects live in one tool behind a single option, because they are two variants of the same thing (`key = value` plus comments) and a `.conf` extension tells you nothing about which one you have. The differences follow each format’s own spec rather than being smoothed over, and that is the point of this tool: · Quotes: in INI, `key = "value"` wraps a value, so the quotes are stripped; in `.properties` quotes are ordinary characters and are kept (that is how Java’s `Properties` reads them). · Escapes and continuations: `\uXXXX`, `\n` and the trailing backslash only apply under `.properties`. In INI mode values are left alone — otherwise an INI containing a Windows path (`C:\dir\`) loses a whole line to the continuation rule. · Trailing whitespace: Java strips only the whitespace *before* a value and keeps what follows; INI strips both ends. Two things the formats simply do not have are also spelled out: duplicate keys keep the last value (matching Java and most INI readers), and arrays are written as repeated keys.
Features
- Both directions: INI → JSON and JSON → INI, detected automatically or set by hand
- One option switches dialect: INI ([sections], quotes stripped) or .properties (! comments, space separator, escapes, continuations)
- A `[db]` header becomes a nested object; the same section appearing twice is merged, not replaced wholesale
- Nesting beyond one level uses dotted section names (`[a.b]`), and each path gets exactly one header
- Duplicate keys keep the last value, and the overwritten keys are reported — that data really is gone
- `\uXXXX`, `\n` and `\: ` escapes plus backslash continuations are decoded the way Java does it
- Numbers convert only when lossless: `port = 5432` becomes a number, `zip = 007` stays a string
- `true` / `false` become booleans; `True` / `yes` stay strings (implementations disagree, so the tool does not guess)
- On output, values containing newlines, leading or trailing spaces, or starting with `#` `;` `!` are quoted so they cannot be read as comments
- JSON → INI reports nulls with their path (neither format has null)
- Parse errors name a specific location rather than saying “invalid format”
How to use
- Paste INI / .properties or JSON — anything that parses as JSON is treated as JSON, the rest as INI
- Check the dialect is right (pick the second option for a `.properties` file, or escapes and continuations will not apply)
- The result updates as you type; the direction can also be set by hand
- Copy the result
FAQ
- Should I pick INI or .properties?
- Follow where the file came from. A `.properties` file belongs to the Java world (`java.util.Properties`): it supports `\uXXXX` escapes, backslash line continuations and `!` comments, and quotes around a value are content, not delimiters. INI is the broader family (Windows `.ini`, various `.conf`): it has `[sections]`, and quotes do wrap values. With a `.conf` extension, look at the content — `[sections]` means INI, while `\u` escapes or a trailing backslash mean `.properties`. Picking the wrong one shows up as stray or missing backslashes and quotes, with no parse error.
- Why did only one line survive when I wrote a key twice?
- Because last-one-wins is the standard behaviour for both formats — Java’s `Properties` and nearly every INI reader work that way. This tool follows it, but reports the overwritten keys in the output, since that data really is lost. If you meant “this key has several values”, the conventional INI spelling is repeated keys, which readers handle individually — and that is what the export direction uses. The import direction keeps only the last one, so that path is lossy, and the tool says so.
- What about arrays and nulls?
- Neither format has arrays, and neither has null. An array is exported as repeated keys (`tags = a`, `tags = b`), the most common convention in the INI world. A null errors by default and names the key, because the alternative is the key vanishing entirely — you would get a config quietly missing a field, with nothing to tell you. You can also choose “as an empty value” or “skip the key”. ⚠️ A null inside an array cannot be skipped: removing an element shifts the index of everything after it, which is worse than an error.
- Why is `port = 5432` a number but `zip = 007` a string?
- The test is lossless round-tripping: a value becomes a number only if converting it to a number and back yields the original string. `5432` round-trips, so it becomes a number. `007` → 7 → `7`, which differs, so it stays `"007"` — the leading zero is part of the identifier and dropping it is irreversible. `true` / `false` become booleans (in a settings file, reading `debug = true` as the string `"true"` makes a downstream `if (cfg.debug)` always true), while `True` and `yes` stay strings, because implementations disagree on them and the tool will not guess. Pick “All as text” to disable inference.
Related tools
TOML Converter
FormatConvert TOML and JSON both ways: all four date/time kinds, arrays of tables and dotted keys, big integers and inf/nan kept, errors located by line.
CSV Converter
FormatConvert CSV / TSV and JSON both ways: delimiter detection, correct quoting and embedded newlines, Excel BOM stripped, numbers only when lossless.
JSON Formatter
FormatFormat, validate and minify JSON in a collapsible tree with syntax highlighting and line numbers. Search, edit, delete or convert to Python dicts.
JSON to Code
FormatTurn JSON into TypeScript interfaces, Go structs, Java classes or Rust structs, with missing keys marked optional. Runs locally in your browser.
SQL Formatter
FormatFormat SQL online: one clause per line, consistent keyword case, subqueries indented deeper. Minify strips comments and extra whitespace, all locally.
JSON5 Converter
FormatParse JSON5 into strict JSON: comments, unquoted keys, single quotes, trailing commas, hex and Infinity all work, with errors located by line.