JSON Input

TOML Output

Success
Warning

Going the other way, and what it costs

Usually you are here because something emitted JSON and something else wants TOML — a settings file to hand-edit, a pyproject.toml section, a config a person is going to read and change. TOML is the friendlier of the two to edit by hand, and the conversion is mostly mechanical.

The interesting part is what the shapes become. A nested object turns into a [section] header. An array of objects turns into repeated [[section]] blocks — the array-of-tables construct — which is much more readable than the JSON it came from and is the main reason to do this at all. Scalars stay where they are.

Two things do not survive, and it is better to know before you paste. TOML has no null: it is not that null is spelled differently, it is that the concept is absent, so a null-valued key has to be dropped and the document comes out a different shape. And a TOML document is always a table at the root, so a bare array or a bare string has no legal representation at all.

Numbers are handled the way the rest of this site handles them. A 19-digit identifier reaches the output as a bare TOML integer rather than a quoted string, because TOML specifies 64-bit signed integers and has no reason to quote something it can hold exactly. The 53-bit ceiling is JavaScript's problem, not TOML's, and it should not leak into your config.

Converting

  1. Paste your JSONIt must be an object at the top level. A bare array is valid JSON but cannot be a TOML document, and the page says so rather than emitting something that will not parse.
  2. Watch for the null noticeIf any key held null, the output names them. They are gone from the TOML, so this is the one case where the converted document says less than the original.
  3. Read the outputArrays of objects become [[blocks]]. If that looks unfamiliar, it is the construct worth learning — it is how a Cargo.toml declares several binaries.
  4. Copy or downloadDownloads as .toml. Round-tripping it through TOML to JSON is a quick way to confirm nothing changed on the way out.

The output is valid but not styled the way a human would write it — every table gets its own header, and inline tables are never produced. If the file is going into a repository for people to edit, expect to spend a minute regrouping sections afterwards.

What an array of objects becomes

The sim array is the part worth watching: two JSON objects become two [[sim]] blocks. Note also that iccid stays a bare integer — 19 digits, unquoted.

config.json → config.toml Bare integers, not strings
config.jsonNested object, array of objects
# provisioning defaults
subscriberId: SUB-1001
msisdn: "447700900142"
iccid: "8944500102030405060"
plan: Unlimited 5G
roaming: true
rsrp: -92
apns:
  - name: internet
    qci: 9
config.toml[network] · [[sim]]
{
  "subscriberId": "SUB-1001",
  "msisdn": "447700900142",
  "iccid": "8944500102030405060",
  "plan": "Unlimited 5G",
  "roaming": true,
  "rsrp": -92,
  "apns": [
    { "name": "internet", "qci": 9 }
  ]
}

When you would use this

Producing a config from a script's output

Something generated JSON and the tool that consumes it wants TOML. This is the step between, without adding a TOML writer to the generating script.

Making a config readable before committing it

A deeply nested JSON config is hard to review in a pull request. The same data as TOML sections is a much easier diff for a human to judge.

Learning the array-of-tables syntax

Paste JSON you already understand and read what comes out. It is a faster way to internalise [[table]] than reading the specification, and TOML to JSON lets you check yourself in the other direction.

Moving between config formats

Coming from YAML, go through YAML to JSON first. Both formats describe the same tree, so JSON is a reliable staging post — with the caveat that YAML comments are already gone by then.

What it does

  • Long integers stay bare. A 19-digit ID is written as a TOML integer, not quoted into a string — TOML has no 53-bit limit, only JavaScript does.
  • Arrays of objects become [[array of tables]], which is the readable form and the reason to convert in the first place.
  • Nulls are reported, not silently dropped. TOML has no null, so the keys have to go — the page lists exactly which ones.
  • A non-object root is refused with a reason, rather than producing a file that will not parse.
  • Nothing is uploaded. The conversion happens in this tab, which matters when the JSON carries credentials.

Questions people actually ask

Why did my null keys disappear?

Because TOML has no null value — not a different spelling, no concept at all. The long-running discussion about adding one has been open for years. The keys are dropped and named under the output, since the alternative is a file that will not parse.

My JSON is an array at the top level and it refuses to convert.

A TOML document is a table at the root, so there is no legal way to write a bare array as one. Wrap it in an object first — {"items": [ … ]} — and it becomes an [[items]] block.

Can I get inline tables instead of all these sections?

Not from here. The writer produces one header per table, which is always valid but more verbose than a hand-written file. Collapsing short tables to { … } is a judgement call about readability that a converter cannot make well.

Are dates handled?

A JSON string that looks like a date stays a string, because that is what it is — JSON has no date type, so there is nothing to signal intent. If you want a real TOML datetime, unquote it in the output; the format this page emits for them is already the one TOML expects.

Is the round trip lossless?

For values, yes — convert to TOML and back with TOML to JSON and every value matches, long integers included. For formatting, no: JSON never carried comments to lose, but section grouping and number bases are decided by the writer.

Related tools

Worth reading