YAML to TOML Converter

Convert YAML to TOML and TOML to YAML instantly. Handles nested objects, arrays, and all common data types. Free, browser-based, no upload required.

  • Runs in your browser
  • Your data never leaves your browser
  • Free · No Sign-Up
Move the entire YAML and TOML panes, keeping their labels and text together. Focus moves to the new first pane. Pending conversion is cancelled; Swap does not convert.
Clear both panes, the status and pending conversion. Ctrl+L (⌘+L on Mac) does the same while focus is inside this tool.
Paste one YAML document with a mapping at the root. TOML updates 0.3 seconds after typing stops. Values TOML cannot preserve stop conversion and are listed by field path.
Copy all current text in the YAML pane, including your edits. An empty pane cannot be copied.
Paste TOML here. YAML updates 0.3 seconds after typing stops, with two-space indentation and no line folding. Values YAML cannot preserve stop conversion.
Copy all current text in the TOML pane, including your edits. An empty pane cannot be copied.
Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.

Worked Example

YAML input

database:
  host: localhost
  port: 5432
  enabled: true
tags:
  - web
  - backend

Equivalent TOML output

tags = [ "web", "backend" ]

[database]
host = "localhost"
port = 5432
enabled = true

Notice that tags moved above [database]. In TOML every key after a [table] header belongs to that table, so top-level plain values must come first. The converter (smol-toml 1.7.1 for TOML, js-yaml 4.3.2 for YAML) reorders keys this way: within each table, plain values keep their order and sub-tables follow them.

Example: a Cargo.toml to YAML

Pasting this into the TOML panel:

[package]
name = "zerotool"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = { version = "1.0", features = ["derive"] }

[[bin]]
name = "cli"
path = "src/main.rs"

gives this YAML:

package:
  name: zerotool
  version: 0.1.0
  edition: '2021'
dependencies:
  serde:
    version: '1.0'
    features:
      - derive
bin:
  - name: cli
    path: src/main.rs

The inline table becomes a nested mapping and [[bin]] (an array of tables) becomes a list. The strings “2021” and “1.0” are quoted in YAML because unquoted they would be read as numbers; 0.1.0 is not a number, so it stays unquoted. Going the other way, a YAML list of mappings such as a services: list becomes repeated [[services]] blocks.

Values That Change on the Way

These are the actual results for inputs that commonly surprise people:

InputOutputWhy
YAML version: 1.10TOML version = 1.1Unquoted 1.10 is a float in YAML. Quote version numbers.
YAML flag: yesTOML flag = "yes"js-yaml follows YAML 1.2, where only true/false are booleans.
TOML hex = 0xffYAML hex: 255Hex, octal and binary integers are written in decimal.
TOML local = 09:30:00YAML local: 09:30:00.000Local times gain milliseconds.

Dates and Times

YAML timestamps are written as TOML dates, not as strings:

release:
  date: 2026-10-01
  at: 2026-10-01 09:30:00 +9
  utc: 2026-10-01T00:30:00Z
  label: "2026-10-01"
  ratio: .inf
[release]
date = 2026-10-01
at = 2026-10-01T09:30:00.000+09:00
utc = 2026-10-01T00:30:00.000Z
label = "2026-10-01"
ratio = inf

A date alone becomes a TOML local date. A date-time keeps its offset, written as +09:00; a date-time without an offset is written with Z, because the YAML timestamp type reads it as UTC. The quoted “2026-10-01” stays a string, and .inf becomes TOML inf. TOML dates keep milliseconds, so a timestamp with more digits, such as 09:30:00.123456Z, stops the conversion, and so does an impossible date such as 2026-02-31.

The other way, the TOML parser keeps milliseconds and drops further digits, so TOML → YAML stops on a finer time: started = 2026-10-01T09:30:00.123456Z in a [build] table gives Not converted: YAML cannot hold these values without changing them: /build/started: 2026-10-01T09:30:00.123456Z has more than millisecond precision. A TOML local date-time has no offset, and YAML reads a timestamp without one as UTC, so started = 2026-10-01T09:30:00 in a [build] table stops too: Not converted: YAML cannot hold these values without changing them: /build/started: 2026-10-01T09:30:00 is a local date-time, and YAML reads a time without an offset as UTC. In YAML → TOML, a YAML -0.0 is written as TOML -0.0, keeping its sign, and a whole float such as ratio: 1.0 stays a float (ratio = 1.0).

Values TOML Cannot Hold

When a value would change, nothing is converted. The status line lists each field as a JSON Pointer and says why:

service:
  id: 9007199254740993
  owner: ~

Not converted: TOML cannot hold these values without changing them: /service/id: integer 9007199254740993 is outside ±(2^53 − 1), so JavaScript would round it; /service/owner: null — TOML has no null

The TOML panel is cleared and its Copy button is disabled, so an older result cannot be copied by mistake. Quote large IDs (id: "9007199254740993") and replace or remove nulls, then convert again. Integers from −(253 − 1) to 253 − 1 convert unchanged.

Limits and Error Messages

  • Root must be a mapping. A YAML list or scalar at the top level gives “YAML root must be a mapping (object), not a scalar or sequence.”
  • One document. YAML with --- between documents gives “expected a single document in the stream, but found more”.
  • Large integers stop the conversion in both directions. TOML → YAML: big = 9007199254740993 gives “integer value cannot be represented losslessly” with the line shown. YAML → TOML: the field is listed as above.
  • Duplicate TOML keys give “trying to redefine an already defined table or value”, with the line and a caret under the problem.
  • js-yaml work limits. js-yaml 4.3.2 stops a document whose collections are nested more than 100 levels deep, whose merge keys (<<) handle more than 10,000 mappings and keys in total, or that lists more than 100 mappings in one merge key. The error names the limit and its line and column.
  • Comments are dropped in both directions, because both parsers return plain data. Keep a copy of a commented file before converting it.
  • Anchors are expanded. y: *a becomes a full copy of the anchored mapping; the TOML output has no way to share it.

YAML vs TOML

YAML is widely used for application configuration (Docker Compose, Kubernetes, GitHub Actions) due to its human-friendly, indentation-based syntax. TOML is the standard for Rust projects (Cargo.toml), Python packaging (pyproject.toml), and tools like Hugo and Zola. This tool converts between them for data types common to both formats. To convert either one to JSON instead, use the YAML ↔ JSON or TOML ↔ JSON converter.

FAQ

What data types are supported?

Strings, integers, floats (including inf and nan), booleans, arrays, nested objects and dates are supported in both directions. A YAML date such as 2026-10-01 becomes a TOML local date, and a YAML date-time keeps its offset. YAML anchors and aliases are resolved before conversion, so each alias becomes a full copy. TOML date-times are written to YAML as unquoted ISO 8601 values (2026-10-01T09:30:00.000+09:00), which YAML parsers usually read back as timestamps.

Why does my YAML fail to convert to TOML?

TOML requires the root document to be a key-value mapping, so a YAML list or scalar at the root cannot be converted. The tool also stops, and lists each field by its path (such as /service/owner), when a value would change on the way: null (TOML has no null), integers outside ±(2^53 − 1), timestamps with more than millisecond precision, and impossible dates. The TOML panel is cleared and its Copy button is disabled until the input converts.

Are YAML multi-document streams supported?

No. Only single-document YAML is supported. Input with several documents separated by --- shows the error 'expected a single document in the stream'; convert one document at a time. The YAML validator on this site can check multi-document files.

Is my data sent anywhere?

No. All conversion runs in your browser. Your data never leaves your machine.