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 TOML to JSON gives you the same configuration in a format every language and every shell tool can already read: tables become nested objects and arrays of tables become arrays of objects. What JSON cannot carry is the typing TOML was chosen for — its real datetimes become strings, and its distinction between an integer and a float disappears.
Up to 100 files at once. Mixed formats are fine.
They convert one after another and download together as a ZIP.
TOML to JSON
TOML has been the standard for Python and Rust packaging for years, and the tooling around a repository often has not caught up. A CI step with jq available and nothing else, a Node script that has to read the version out of a Cargo.toml, a dashboard counting dependencies across two hundred repositories — all of them can read JSON and none of them can read TOML without a new dependency.
That is the case this conversion serves, and it works cleanly because the two data models overlap almost entirely. TOML is a table of key-value pairs with nesting and arrays, which is a JSON object with nesting and arrays. The interesting parts are the four places where TOML knows something JSON does not.
A bracketed header becomes a nested object, and a dotted header becomes nesting several levels deep — a header written for a tool and then a linter under it produces an object inside an object, so the JSON path matches the header exactly. Nothing about the structure needs interpreting.
A double-bracket header is the array of tables, and it becomes a JSON array of objects with one entry per occurrence. That is what holds the authors of a Python package, the binaries of a Rust crate and the targets of a build, and it is the construct people worry about most and need to worry about least. Order is preserved.
TOML is the only format in this family with genuine temporal types: offset datetimes, local datetimes, local dates and local times are in the specification, and a parser returns them as dates. JSON has no date type at all, so each one becomes a string.
The values survive with one wrinkle. An offset datetime keeps its offset rather than being normalised to UTC, which is better behaviour than several other conversions on this site. A local date comes across exactly as written. A local time picks up a millisecond component it did not have — a time written as eight in the morning arrives with a fractional part attached. If something downstream compares those strings rather than parsing them, that extra suffix is the thing that will break the comparison.
TOML 1.0 requires an implementation to handle 64-bit signed integers. JSON numbers are IEEE doubles and are exact only to about nine quadrillion. A TOML file holding an integer above that range is entirely legal, and the parser here stops with an error saying the integer cannot be represented losslessly rather than producing JSON with a wrong number in it.
Refusing is the right call and it is worth understanding rather than working around blindly. A silently rounded identifier is a bug that surfaces weeks later in a join that matches nothing. If your TOML holds a value of that size — a snowflake ID, a large serial, a nanosecond timestamp as an integer — quote it as a string in the source. It was never a quantity, and quoting it makes every downstream consumer correct at once.
TOML floats include inf and nan as literal values. JSON has neither, and the serialiser writes null for both. That is the standard JavaScript behaviour and it is lossy in a way nothing reports — a configured upper bound of infinity and an unset upper bound become the same thing in the JSON.
The subtler loss is typing. TOML distinguishes an integer from a float, so 1 and 1.0 are different values with different types, and a schema or an application can rely on that. JSON has one number type, and 1.0 is serialised as 1. If a consumer of the JSON needs to know that a value was declared as a float, that information has to travel some other way, because it is not in the file any more.
Tables and keys come out in the order the TOML declared them, which keeps a converted file readable and keeps a diff between two conversions meaningful. The output is indented two spaces and ends with a newline.
The exception is numeric keys. A quoted TOML key that is a number — which appears in configs that index things by year or by port — is reordered ahead of every other key in its object and sorted ascending, because that is how JavaScript objects order integer-like keys. It is the only place where the JSON does not read in the same sequence as the source.
The output is ordinary JSON, so jq reads it with no flags: pulling a project version, listing dependency names or checking whether a tool section exists are all one-line expressions. That is usually the whole reason for the trip, and it turns a shell script that was going to grep a TOML file into one that queries it properly.
It also opens up validation. JSON Schema is mature and widely implemented, and TOML has no schema language in its specification, so converting and then validating is a genuine way to enforce house rules across many repositories — every package must declare a licence, every crate must pin its edition — that cannot be checked against the TOML directly.
TOML supports comments and uses them heavily: the reason a dependency is pinned, the ticket number next to a workaround, the block explaining which environment a setting applies to. JSON has no comment syntax under RFC 8259, so none of it arrives.
That settles the direction of the relationship. The TOML is the file people edit and review, and the JSON is generated from it whenever something needs to read it. Checking the JSON into the repository alongside the TOML creates two versions of the truth that will drift; generating it in the build step does not.
If the reading happens inside an application rather than in a build step, use a parser. Every major language has one — Python has had tomllib in its standard library for several versions, and Rust, Go and JavaScript all have well-maintained options. Reading the file directly keeps the temporal types and the integer-float distinction that this conversion flattens.
The converter earns its place at the boundary: a one-off inspection, a CI step where adding a dependency is more trouble than it is worth, or a pipeline whose next stage speaks nothing but JSON. Everything runs in your browser, so a private config with credentials in it is safe to drop here, and the free ceiling of 100 MB is far beyond any configuration file.
| TOML | JSON | |
|---|---|---|
| Full name | Tom's Obvious Minimal Language | JavaScript Object Notation |
| File extension | .toml | .json |
| Media type | application/toml | application/json |
| First published | 2013 | 2001 |
| Specification | TOML 1.0 | RFC 8259 |
| Licensing | Open standard | Open standard |
| Standing today | Current | Current |
| Opens in a browser | No browser | Every browser |
| Considered instead | YAML, INI | XML, YAML, NDJSON |
Comments do not survive. TOML lets you annotate a file and JSON has no syntax for it, so every explanatory line is dropped — which matters most on exactly the files people comment: configuration somebody else has to maintain.
Nothing is discarded. TOML and JSON 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.
JSON opens in every current browser. TOML has narrower browser support than that. If the file is going onto a web page or into a form, that is usually the whole reason for the conversion.
Visual Studio Code reads both TOML and JSON, so there is a way to check the result against the original without a second tool.
The two are aimed at different work: TOML at editing, JSON at moving data between programs and the web. That is worth weighing before converting, because the reason one exists is usually the reason the other is awkward.
TOML was published in 2013. The specification is TOML 1.0, and it is worth reading if the file has to outlive the tool that wrote it.
JSON dates from 2001, specified as RFC 8259. Visual Studio Code, jq and Postman all read 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.
As a JSON array of objects. A double-bracket header repeated twice — the shape used for authors, binaries and targets — becomes an array with one object per occurrence, in the order they appeared.
They become strings, because JSON has no date type. An offset datetime keeps its offset, a local date stays as written, and a local time gains a millisecond component. Nothing is lost in value; the type is.
Because it holds an integer too large for a JSON number to represent exactly. TOML requires 64-bit integers and JSON numbers are IEEE doubles, so the parser stops rather than rounding your value. Quote that integer as a string in the TOML if you need it converted.
null. TOML defines both as float values and JSON has neither, so the serialiser writes null. If the distinction matters, replace them with a sentinel string before converting.
No. TOML supports comments and JSON, under RFC 8259, has no syntax for them, so every explanatory line disappears. Treat the JSON as a derived artefact and keep the TOML in version control.
No. Both the parser and the serialiser run in this page in JavaScript, so a config with a private registry token in it stays on your machine.