Cookies for analytics and advertising
We use cookies for analytics and advertising, both sent to Google. Refusing changes nothing you can see.Read the privacy page
Converting YAML to TOML trades indentation for explicit table headers: every nested mapping becomes its own bracketed section and a list of mappings becomes an array of tables. The move is clean for anything with a value, and two YAML habits do not survive it at all — an empty key vanishes, and an empty list item stops the conversion.
Up to 100 files at once. Mixed formats are fine.
They convert one after another and download together as a ZIP.
YAML to TOML
Plain values and arrays are written at the top, then each nested mapping appears as its own bracketed table header. Nesting three levels deep produces a single header with dots in it rather than three nested blocks, so a mapping written as tool, then ruff, then a setting, comes out as one [tool.ruff] header with the setting under it.
That flattening of headers is the visible difference between the two formats. YAML expresses depth with whitespace and can nest without limit before it becomes unreadable; TOML expresses depth in the header name and stays readable at four levels because the full path is written out on every block. It is the trade the format was designed around, and for a project config it is usually the right one.
A line written key: with nothing after it is valid YAML and parses to null. TOML has no null value — the specification simply does not define one — so the writer omits the key. No error, no placeholder, no comment: the key was in your YAML and is not in your TOML.
This matters more than it sounds because empty keys are a deliberate YAML idiom. They mark a setting as present but unset, they hold a place for something an operator fills in later, and they document that an option exists. All of that is information, and all of it disappears. Search the source for lines ending in a colon before converting, and decide for each one whether it should carry an explicit value, an empty string, or a comment in the TOML.
The same null inside an array behaves differently: the writer refuses, and the conversion fails with a message saying arrays cannot contain null or undefined values. Nothing is produced.
This is the better of the two behaviours, and the inconsistency is deliberate rather than accidental. Dropping a key from a table leaves the rest of the table meaningful; dropping an element from an array shifts every element after it, which changes an ordered list into a different ordered list. Refusing is the only safe answer, and it means a YAML file with a stray dash and nothing after it tells you so rather than converting into something subtly wrong.
TOML groups by table. Everything belonging to a table has to appear after its header and before the next one, so the writer emits every scalar and array first and then each nested block in turn. A .gitlab-ci.yml converted this way puts its stages array at the top and the job definitions below it as tables, regardless of how they were ordered in the YAML.
The consequence to plan for is the diff. If the YAML file is under review and the TOML replaces it in the same repository, the first commit will look like a rewrite rather than a translation, because it is. Land the conversion as its own commit with nothing else in it, so the next reader can see that only the syntax changed.
A block scalar — the pipe character followed by an indented shell script, which is how every CI file holds its build commands — parses into a string containing newlines, and the writer emits it as an ordinary quoted TOML string with backslash-n escapes in it. A ten-line script becomes one very long line.
TOML has a multi-line string syntax using triple quotes that would hold the script legibly, and the writer does not reach for it. That is a conversion you make by hand: find the values with escaped newlines in them, and rewrite each as a triple-quoted block. It is worth doing for anything a human will edit again, and not worth doing for a value nothing but a program reads.
TOML is the only format in this family with first-class dates: offset datetimes, local datetimes, local dates and local times are all part of the specification and a TOML parser hands them back as dates rather than strings. That is the main reason a project chooses TOML over JSON.
You do not get them from this conversion. YAML 1.2 treats an unquoted 2024-01-02 as a string, so it arrives in the TOML as "2024-01-02" with quotes around it. Unquoting those values afterwards is the whole job and takes seconds; leaving them quoted works too and simply means your TOML holds text where it could hold a date. The same is true of integers written with a decimal point: a YAML value of 1.0 becomes the TOML integer 1, because the parser resolved it to a whole number before the writer saw it.
The construct people worry about turns out to be the one that works best. A YAML list whose items are mappings — a list of authors, a list of binaries, a list of jobs — becomes a TOML array of tables, with the double-bracket header repeated once per item. That is exactly the shape a pyproject.toml or Cargo.toml wants for its authors and its targets.
A list at the very top of the YAML file is the exception. TOML documents are always a table, so a document that is nothing but a list is wrapped in a table with a single key named items and the list underneath it. If your YAML is a sequence at the root, decide on the key name yourself and add it to the source before converting, so the name means something.
TOML bare keys allow letters, digits, underscores and hyphens. Anything else has to be quoted, and the writer quotes it for you: a key containing a dot comes out as "date.timezone" with the quotes included, and so does a key containing a space. Quoted keys are entirely valid TOML.
They are also a signal. A quoted key with a dot in it usually means the YAML was expressing structure in the key name rather than in the nesting, and in TOML that structure would be better written as a real table. Whether to split it is a decision about your config, not about the conversion, but the quotes in the output are a reliable place to start looking.
Both formats support comments and none of yours cross over. The parser discards them while reading and the writer has nothing to write. On a project config that is a real cost — the note explaining why a dependency is pinned, the commented-out alternative, the line saying which environment a block applies to.
The migration is only finished when those are back. Convert, then open the old YAML and the new TOML side by side and reattach the comments where they belong. It is ten minutes on a typical file and it is the difference between a config somebody can maintain and a config that works and nobody dares change.
| YAML | TOML | |
|---|---|---|
| Full name | YAML Ain't Markup Language | Tom's Obvious Minimal Language |
| File extension | .yaml, .yml | .toml |
| Media type | application/yaml | application/toml |
| First published | 2001 | 2013 |
| Specification | YAML 1.2 | TOML 1.0 |
| Licensing | Open standard | Open standard |
| Standing today | Current | Current |
| Opens in a browser | No browser | No browser |
| Considered instead | JSON | JSON, INI |
Nothing is discarded. YAML and TOML both store their content losslessly, so the conversion is a change of packaging rather than a change of quality, and it can be repeated without accumulating damage.
Comments carry across. Both YAML and TOML have a comment syntax, so notes left for whoever maintains the file next are not silently thrown away.
Visual Studio Code reads both YAML and TOML, so there is a way to check the result against the original without a second tool.
YAML was published in 2001. The specification is YAML 1.2, and it is worth reading if the file has to outlive the tool that wrote it.
TOML dates from 2013, specified as TOML 1.0. Visual Studio Code reads it.
No. This conversion runs entirely inside your browser, so the file never leaves your device. You can confirm it yourself: open the network tab of your browser's developer tools and convert something. You will see the page load, plus the analytics and advertising the site is paid for with — and nothing carrying your file.
Because its YAML value was empty. A line written key: with nothing after it parses to null, and TOML has no null — so the writer drops the key entirely rather than inventing a value. Give the key a real value in the YAML first, or add it to the TOML by hand.
A list item with no value parses to null, and a TOML array cannot contain one. The writer refuses rather than dropping an element and shifting the rest, which would be worse. Remove or fill the empty item in the source.
No, and they cannot be. TOML puts everything belonging to a table under that table header, so plain values and arrays are written first and every nested block follows as its own [table]. The data is identical; the reading order is not.
No. Under YAML 1.2 an unquoted date is an ordinary string, so it arrives as a quoted TOML string. TOML has genuine date, time and datetime types, and getting them means unquoting those values in the output by hand.
It fails to convert. A file with --- separators holds several documents and TOML describes exactly one table, so the parser stops instead of picking one. Split the file and convert each document on its own.
No. The parser and the writer are both JavaScript running in this page, so a project config with tokens or private registry URLs in it stays local. The free limit is 100 MB, which no config file will approach.