Skip to content
Deftkit

TOML ⇄ JSON Converter

Convert between TOML and JSON in both directions. TOML 1.0 compliant parser, handles tables, arrays of tables, dates, and nested structures. Runs in your browser.

Type or paste on the left — the right side updates live. Uses smol-toml (TOML 1.0 compliant) for parsing.

What is TOML?

TOML stands for "Tom's Obvious, Minimal Language" — a configuration file format created by Tom Preston-Werner (GitHub co-founder) in 2013. It was designed to be strictly more obvious than YAML, strictly more human-editable than JSON, and to have a formal specification that different parsers actually agree on (YAML has a famously fuzzy spec where different parsers produce different results on the same input).

TOML reached 1.0.0 in January 2021 and is now the native configuration format of the Rust ecosystem (Cargo.toml), Python's build system (pyproject.toml), many CI/CD tools, and a growing list of modern dev tools that want human-readable config without YAML's edge cases.

Example: the same data in both formats

TOML:

title = "Deftkit"
version = "1.0.0"
authors = ["Alice", "Bob"]

[features]
dark_mode = true
max_items = 100

[[servers]]
name = "alpha"
ip = "10.0.0.1"

[[servers]]
name = "beta"
ip = "10.0.0.2"

JSON:

{
  "title": "Deftkit",
  "version": "1.0.0",
  "authors": ["Alice", "Bob"],
  "features": {
    "dark_mode": true,
    "max_items": 100
  },
  "servers": [
    { "name": "alpha", "ip": "10.0.0.1" },
    { "name": "beta", "ip": "10.0.0.2" }
  ]
}

Both encode the exact same data. TOML's [section] syntax and the [[arrays.of.tables]] double-bracket notation are the two main features that distinguish it visually. JSON wins on compactness; TOML wins on readability for nested config with arrays of records.

Why TOML exists — the YAML alternative

TOML was designed as a reaction to YAML's well-documented problems:

  • No Norway problem. YAML 1.1 parses NO as the boolean false (the country code for Norway becomes false). TOML has exactly two boolean literals: true and false, both lowercase. Everything else is a string unless quoted differently
  • No significant whitespace. TOML uses explicit [sections] and braces. You cannot accidentally change the meaning of a TOML document by adding or removing a leading space. YAML's whitespace-sensitive syntax has caused countless CI failures
  • Formal spec, concrete compliance tests. TOML has an official test suite that parsers must pass to claim compliance. YAML's spec has so many ambiguities that different parsers legitimately disagree on how to read the same file
  • First-class datetime support.TOML has native date, datetime, and time types with timezone awareness. JSON doesn't; YAML's is optional and often missing in stricter parser modes
  • Comments work everywhere. # starts a line comment. JSON has no comments at all. YAML comments work but round-tripping them through most parsers drops them

TOML syntax, the parts that matter

Key/value pairs

# Strings
title = "Deftkit"
empty = ""
multiline = """
multi
line
"""
raw = 'no \n escape here'

# Numbers
port = 8080
pi = 3.14
hex = 0xff
octal = 0o755
binary = 0b1010
negative = -1.5

# Booleans
debug = true
cache = false

Tables (sections)

TOML's killer feature is [sections]. A section header creates a nested object.

[database]
host = "localhost"
port = 5432

[server]
host = "0.0.0.0"
port = 8080

# Nested via dotted keys
[server.cors]
allowed_origins = ["*"]

Equivalent JSON:

{
  "database": { "host": "localhost", "port": 5432 },
  "server": {
    "host": "0.0.0.0",
    "port": 8080,
    "cors": { "allowed_origins": ["*"] }
  }
}

Arrays of tables

Double-brackets [[name]]create an array of tables — the feature you cannot easily replicate with YAML mapping syntax and one of TOML's strongest ergonomic wins.

[[servers]]
name = "alpha"
ip = "10.0.0.1"

[[servers]]
name = "beta"
ip = "10.0.0.2"

Equivalent JSON:

{
  "servers": [
    { "name": "alpha", "ip": "10.0.0.1" },
    { "name": "beta", "ip": "10.0.0.2" }
  ]
}

Inline tables

For small objects, TOML has a JSON-like inline syntax:

point = { x = 1, y = 2 }
tokio = { version = "1.0", features = ["full"] }

Dates and times

TOML has four native temporal types:

# Offset date-time (RFC 3339 with timezone)
created = 2026-04-09T12:34:56Z

# Local date-time (no timezone)
due = 2026-04-09T12:34:56

# Local date
birthday = 1985-04-12

# Local time
alarm = 07:30:00

When converting TOML → JSON, datetime values are serialized as ISO 8601 strings (2026-04-09T12:34:56.000Z) because JSON has no native datetime type. The round trip is lossy: converting back to TOML produces a string, not a datetime. This is a fundamental limitation of JSON, not a bug in the converter.

How to use this tool

  1. Pick a direction: TOML → JSON or JSON → TOML
  2. Paste your source on the left
  3. The converted output appears on the right instantly
  4. Click Swap sides to flip direction and move the current output to the input
  5. Click Sample to load a representative Cargo.toml-style example
  6. Click Copy to put the output on your clipboard

Under the hood

Conversion uses the smol-toml library running in your browser — a TOML 1.0.0 compliant parser that weighs ~9KB minified + gzipped. No external service, no upload, no logging.

For TOML → JSON, the input is parsed into a plain JavaScript object tree and serialized with JSON.stringify at 2-space indentation. Date objects (TOML has first-class datetime, JavaScript exposes them as Date) are converted to ISO 8601 strings.

For JSON → TOML, the input is parsed with native JSON.parse and serialized via smol-toml.stringify. The top-level value MUST be a JSON object (TOML requires a table at the root) — if you pass an array or primitive, the tool rejects it with an error message.

Where TOML wins and loses

TOML wins for

  • Rust projects — Cargo.toml is the universal build manifest for every Rust crate
  • Modern Python build configs — pyproject.toml replaces setup.py, setup.cfg, and a handful of other legacy files in one place
  • Hugo static site config, mdBook, Zola, and most Rust-adjacent tools
  • Any config file that needs tables of records — the [[servers]] array-of-tables syntax is more readable than YAML's dashed list of mappings
  • Teams burned by YAML's ambiguity — the formal spec and reference compliance tests mean switching parsers won't change your data

TOML loses for

  • API payloads — JSON is what every HTTP library on the planet speaks natively. TOML has no place on the wire
  • Very deeply nested data— TOML's section-header syntax gets awkward past 3-4 levels. JSON's braces handle arbitrary depth cleanly
  • Dynamic/programmatic config — TOML has no template or substitution syntax. For parameterized config, use JSON with a templating layer (Jinja, envsubst) or switch to YAML if your tool supports anchors
  • Tools that expect JSON — most linters, CI systems, and data-pipeline tools have JSON inputs by convention. Converting TOML → JSON before feeding downstream is a common pattern this tool automates

Privacy

All parsing and conversion happens in your browser via the smol-toml library and native JSON.parse. Your data never leaves your device — safe for private Cargo.toml files, internal build configs, and unpublished project metadata.

Frequently asked questions

Is TOML better than YAML?

"Better" depends on the use case. TOML has a formal spec, first-class datetimes, and avoids whitespace-sensitivity bugs — clear wins. YAML has anchors, references, multi-document files, and is more concise for deeply nested data — also clear wins. If your config is flat or shallowly nested (2-3 levels), TOML is almost always better. If it's deeply nested or needs repeated fragments, YAML pulls ahead.

Can I convert JSON Schema to TOML?

This tool converts JSON data, not JSON Schema. JSON Schema is itself a JSON document describing another JSON document's shape — you can paste a JSON Schema file into this tool and get a TOML version of the schema structure, but TOML has no native schema validation ecosystem. For schema work, stay in JSON land.

Why does my TOML convert but then fail when I convert back?

The most common cause is datetime round-tripping. TOML has native dates; JSON doesn't. When converting TOML → JSON, dates become ISO strings. Converting back JSON → TOML produces strings, not dates — which is valid TOML but not what the original file had. Another common cause is top-level arrays: JSON allows them, TOML requires a table root, so a top-level JSON array cannot be converted to TOML directly — wrap it in an object with a single key first.

Does this tool support TOML 0.x?

Partial. The smol-toml parser targets TOML 1.0.0 specifically, but most 0.5+ syntax is forward-compatible with 1.0. If you have a very old Cargo.toml from pre-2018, it may hit spec differences — use an older parser for those files, or update them to 1.0 syntax (which is trivial in most cases).

Can I use this for Cargo.toml?

Yes — Cargo.toml follows the TOML 1.0 spec. Paste it in and you get JSON out, suitable for feeding into jq-style tools or any script that expects JSON. This is a common workflow for teams with mixed Rust and non-Rust tooling.

What's the difference between TOML inline tables and arrays of tables?

Inline tables (point = { x = 1, y = 2 }) are single objects written on one line. Arrays of tables ([[servers]]) are multiple objects, each with the same shape, collected into a JSON array. Use inline tables for fixed-shape one-offs; use array-of-tables for variable-length lists of records.

Is my data sent anywhere?

No — all parsing and conversion happens in your browser via the smol-toml library. No TOML or JSON content you paste ever leaves your device.