Properties to YAML Converter
Convert Java .properties into nested YAML or flatten YAML back to dotted keys, with escapes, line continuations and key collisions handled correctly. All processing happens locally in your browser.
Convert .properties to YAML and back
Keys are parsed the way java.util.Properties does: the key ends at the first unescaped =, : or space, so a JDBC URL keeps every colon in its value. Escapes, line continuations and \\uXXXX sequences are all resolved.
# Server settings
# Datasource — note the colons in the URL
server:
port: 8080
servlet:
context-path: /api
spring:
datasource:
url: jdbc:mysql://localhost:3306/appdb?useSSL=false
username: app_user
jpa:
hibernate:
ddl-auto: validate
app:
security:
enabled: true
roles:
- admin
- editor
- viewerDotted keys become nested YAML mappings. A key that is both a value and a branch cannot exist in YAML, so those collisions are reported below.
.properties comment sits on the line above its key. YAML nesting reorders content, so the original position cannot be reconstructed reliably. All 2 comments are collected at the top of the output for you to reposition.| Line | Key | Value | Separator |
|---|---|---|---|
| 2 | server.port | 8080 | = |
| 3 | server.servlet.context-path | /api | = |
| 6 | spring.datasource.url | jdbc:mysql://localhost:3306/appdb?useSSL=fal… | = |
| 7 | spring.datasource.username | app_user | = |
| 8 | spring.jpa.hibernate.ddl-auto | validate | = |
| 10 | app.security.enabled | true | = |
| 11 | app.security.roles | admin,editor,viewer | = |
What is a .properties file, and where does parsing go wrong?
A .properties file is Java's flat key-value configuration format. Every value is a string, and hierarchy is faked with dots:
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/appdb
app.security.roles=admin,editor,viewer
It looks trivial, which is exactly why most converters get it wrong. The rules java.util.Properties actually follows are fussier than they appear, and the consequences are silent data corruption rather than an error.
The key ends at the FIRST separator
This is the rule that matters most. A key is terminated by the first unescaped =, : or whitespace. Everything after that point is the value — including any further = or : characters.
spring.datasource.url=jdbc:mysql://localhost:3306/appdb?useSSL=false
Key: spring.datasource.url
Value: jdbc:mysql://localhost:3306/appdb?useSSL=false
A converter that splits on every = or : mangles that URL into something like jdbc=mysql=//localhost.... Since almost every real Spring config contains a JDBC URL, it is the first thing worth checking in any tool of this kind. This page parses character by character and stops at the first separator, so the URL survives intact.
Three separators, all equivalent
database.host=db.internal
database.host: db.internal
database.host db.internal
All three define the same key. Whitespace as a separator is rare in hand-written files but common in generated ones.
How to convert
- Paste your properties, or switch direction The tool works both ways: dotted keys into nested YAML, or nested YAML flattened back to dotted keys.
- Decide how values are typed Java treats every value as a string. YAML has real types, so number and boolean conversion is offered as a choice rather than assumed.
- Check the parsed-keys table It shows the key, the value and which separator was used on every line — the quickest way to confirm nothing was mis-split.
- Read the collision and warning notes Duplicate keys, invalid unicode escapes and keys that are both a value and a branch are all reported.
Examples: escapes, continuations and unicode
| In the file | Parsed value | Why |
|---|---|---|
log\:level=DEBUG |
key log:level |
An escaped colon is part of the key, not a separator |
path=C:\\reports |
C:\reports |
A backslash must be doubled |
symbol=\u00A3 |
£ |
\uXXXX is a unicode escape |
msg=line one \ line two |
line one line two |
A trailing backslash continues the line; leading whitespace on the next line is discarded |
key\ with\ spaces=x |
key key with spaces |
An escaped space is part of the key |
empty= |
"" |
A separator with nothing after it means an empty string, not null |
The Windows path case catches people constantly. C:\reports written with a single backslash makes \r a carriage return, so the value silently becomes C: followed by a line break and eports. Doubling the backslash is mandatory.
Line continuation only applies when a line ends with an odd number of backslashes. path=C:\\ ends with two, so it is a literal trailing backslash rather than a continuation.
Dotted keys become nested YAML
The core transformation splits each key on dots and builds a tree:
server.port=8080
server.servlet.context-path=/api
spring.datasource.url=jdbc:mysql://localhost/db
becomes
server:
port: 8080
servlet:
context-path: /api
spring:
datasource:
url: jdbc:mysql://localhost/db
Indexed lists
Spring's relaxed binding supports an index in the key, which becomes a real YAML sequence when index expansion is enabled:
servers[0].host=alpha.internal
servers[0].port=8080
servers[1].host=beta.internal
becomes
servers:
- host: alpha.internal
port: 8080
- host: beta.internal
With expansion off, you get a mapping whose keys are literally servers[0] — occasionally what you want, if the consuming code reads the flat key.
The collision case
This is the one structural problem with no clean answer:
app=legacy-name
app.name=modern-name
app would have to be a string and a mapping at the same time, which YAML cannot express. Rather than crashing or silently dropping one, the scalar is moved to a sub-key and the collision is reported:
app:
_value: legacy-name
name: modern-name
You then decide what it should really be. In Spring this pattern usually means a property was renamed and the old key was left behind, so deleting the bare app line is often the correct fix.
Types: strings in Java, real values in YAML
Every .properties value is a string. server.port=8080 gives you "8080", and Spring converts it to an int when binding. YAML has genuine scalar types, so the conversion has to choose.
| Properties value | Conversion on | Conversion off |
|---|---|---|
8080 |
8080 (number) |
'8080' |
true |
true (boolean) |
'true' |
08080 |
'08080' (kept a string) |
'08080' |
1.0 |
1.0 (number) |
'1.0' |
admin,editor |
List of two items, if list splitting is on | 'admin,editor' |
Note the leading-zero row. A zero-padded value such as an account code or a port written 08080 is deliberately kept as a string, because converting it would drop the zero and change the value.
Comma splitting matches Spring's own relaxed binding, where roles=admin,editor binds to a List<String>. Turn it off when a value legitimately contains a comma, such as an address or a CSV fragment.
What cannot round-trip
- Comment position. A
.propertiescomment sits directly above its key. Nesting reorders content, so the original position cannot be reconstructed. Comments are collected at the top of the YAML for you to reposition. - Key order. Properties files are read in order; YAML mappings group siblings together. A file with
server.port,app.name,server.hostends up with the twoserverkeys adjacent. - The separator you used. Whether a line used
=,:or a space is not recorded in the YAML, so flattening back always emits your chosen separator. - Blank line grouping. Visual separation between config sections is lost.
- Duplicate keys. Java keeps the last value silently. The duplicate is reported here, but only one survives into the YAML.
Use cases
- Migrating a Spring Boot app to YAML.
application.propertiesandapplication.ymlare interchangeable, and YAML is far easier to read once nesting gets deep. - Flattening YAML for an environment variable pass. Dotted keys map directly to
SERVER_PORTstyle variables, so the flattened form is a useful intermediate step. - Auditing a large config file. The nested view makes it obvious which prefixes have grown and where settings overlap.
- Checking a suspect value. The parsed-keys table shows exactly how each line was split, which settles arguments about whether a URL or a Windows path is being read correctly.
- Comparing two environments. Convert both to YAML and diff them; grouping by prefix makes real differences much easier to spot than a flat file diff.
- Generating a config template. Convert to YAML, prune the values, and you have a documented skeleton.
Related config work: XML to Properties handles legacy Spring XML, YAML to JSON feeds schema validation, and JSON to Java generates the classes these properties bind to.
Privacy
Parsing and conversion run entirely in your browser. The file is not uploaded, which matters because configuration routinely contains internal hostnames, database URLs and credentials. Usage analytics record only the direction and a key count.
Frequently Asked Questions
Why do other converters break my JDBC URL?
Because they split the line on every = or : character. The Java rule is that the key ends at the FIRST unescaped separator and everything after is the value, colons included. So jdbc:mysql://host:3306/db must stay intact. Checking a JDBC URL is the fastest way to test any properties converter.
Do I need to escape colons in my keys?
Yes, if the key genuinely contains one. Writing log:level=DEBUG gives you a key of "log" with the value "level=DEBUG". Write log\:level=DEBUG to get the key you meant. The same applies to spaces and equals signs inside a key.
What happens when a key is both a value and a branch?
YAML cannot express both, so the scalar is moved to a _value sub-key and the collision is reported. In Spring config this pattern usually means a property was renamed and the old flat key was left behind, so deleting it is often the right fix.
Should I enable number and boolean conversion?
Usually yes for Spring, which binds YAML numbers and booleans to typed fields exactly as it does string properties. Turn it off if a downstream consumer expects every value to be a quoted string. Zero-padded values such as 08080 are kept as strings either way.
Why did my comments move to the top?
Because a properties comment sits above its key, and nesting reorders keys so that position no longer exists. Rather than dropping them, they are collected at the top for you to reposition. Preserving them in place would require a YAML writer that tracks provenance through the transformation.
Why is my Windows path wrong?
Almost certainly single backslashes in the source file. C:\reports makes \r a carriage return, so the value becomes C: then a line break then "eports". Java requires doubled backslashes: C:\\reports. The parsed-keys table shows what the value actually became.
Does it handle servers[0].host indexed keys?
Yes, and they become a real YAML sequence when index expansion is enabled. That matches Spring's relaxed binding, where indexed properties bind to a List. Turn expansion off if you want literal keys named servers[0].