TOML to .properties
Flatten a TOML config into key=value lines a Java Properties loader will read: nested tables become dotted keys, arrays become indexed keys or a comma list, and special characters are escaped the way .properties requires.
What this tool does
It walks the parsed TOML tree and writes one line per leaf value, with the full dotted path as the key. [spring.datasource] url = "…" becomes spring.datasource.url = … — which is exactly the key a Spring Boot application expects, so a TOML file can be the maintained source and the .properties file the build artefact.
The intent it closes: "I want to keep this config in TOML but the JVM wants .properties." Values are escaped for the format: backslashes doubled, newlines and tabs written as \n and \t, and — with Unicode on — every non-ASCII character written as a \uXXXX escape so the file survives an ISO 8859-1 reader.
Keys are escaped too. A key containing a space, an equals sign, or a colon gets those characters backslash-escaped, because in .properties any of them would otherwise end the key.
When you'd reach for it
- Build a Spring Boot config. Maintain TOML, generate
application.propertiesin CI. - Migrate away from TOML for one consumer. A single JVM service needs properties; everything else keeps reading the TOML.
- Produce a flat diff. One line per setting makes a config change trivially reviewable.
- Feed a tool that reads properties. Logback, Log4j, Kafka clients, and many CI plugins all take
.properties. - Generate an ISO 8859-1-safe file. Turn Unicode escaping on when the reader predates the UTF-8 default.
How it works
Flatten, escape, write — with the array policy as the only structural decision.
1. Flatten to dotted keys
Every leaf in the tree gets its full path as a key, joined with dots. Empty tables produce no lines, because there is no value to write.
2. Handle arrays
With Indexed keys, an array becomes one line per element with the index appended (app.feature_flags.0). With Comma-separated, the whole array becomes one line — the form Spring reads back into a List<String>. Arrays of tables always use indexed keys, since a table cannot be flattened into one comma list.
3. Escape and emit
Values get their backslashes doubled and their control characters escaped; keys get =, :, and whitespace escaped. With Unicode escaping on, characters above U+007F become \uXXXX. Lines are joined with LF and the separator style you chose.
Options reference
Separator
All three forms are legal: key = value reads best, key=value is the most common in generated files, and key: value is accepted by Properties.load() as well. Pick whatever matches the surrounding files.
Arrays
Indexed keys is the safe default and round-trips exactly. Comma-separated is what Spring's relaxed binding expects for a list property — but it breaks if any element itself contains a comma, so use it only for simple token lists.
Sort keys
Alphabetical makes the generated file byte-stable regardless of how the TOML was ordered, which keeps diffs clean when the file is committed. Document order preserves the grouping a human put there.
Unicode
Off, the file is UTF-8 and any modern reader handles it. On, every non-ASCII character becomes a \uXXXX escape, making the file pure ASCII — required if it is loaded by a legacy reader that assumes ISO 8859-1.
Example
Input:
[server]
port = 8080
[app]
feature_flags = ["beta", "metrics"]
Output (indexed arrays):
server.port = 8080
app.feature_flags.0 = beta
app.feature_flags.1 = metrics
Switch Arrays to comma-separated and the last two lines collapse to app.feature_flags = beta,metrics, which Spring binds to a list. The indexed form is the one that converts back losslessly.
FAQ
Will Spring Boot read the output?
Yes — the dotted keys are exactly Spring's relaxed-binding form, so [spring.datasource] url lands as spring.datasource.url. For list properties, choose comma-separated arrays or the indexed form, both of which Spring understands.
Are comments preserved?
No. TOML comments do not survive parsing into the value tree. Turn on the header comment option if you want the file to state that it was generated.
What happens to dates?
They are written in their TOML text form — an ISO-8601-shaped string. A properties reader treats it as a string, so parse it on the Java side with whatever your code expects.
Do I need Unicode escaping?
Only for old readers. Java's Properties.load(InputStream) historically assumed ISO 8859-1; load(Reader) and modern frameworks read UTF-8. If in doubt, turning it on is harmless — escapes are always understood.
Can I convert back?
Yes, with .properties to TOML. It re-nests the dotted keys and infers types, which the properties format itself does not record.