Skip to content

Instantly share code, notes, and snippets.

@oconnor663
Last active May 2, 2023 00:43
Show Gist options
  • Save oconnor663/9aeb4ed56394cb013a20 to your computer and use it in GitHub Desktop.
Save oconnor663/9aeb4ed56394cb013a20 to your computer and use it in GitHub Desktop.
TOML vs YAML

EDIT from 2019: Hi folks. I wrote this gist for myself and some friends, and it seems like it's gotten posted somewhere that's generated some (ahem, heated) discussion. The whitespace was correct when it was posted, and since then GitHub changed how it formats <pre> tags. Look at the raw text if you care about this. I'm sure someone could tell me how to fix it, but (thank you @anzdaddy for suggesting a formatting workaround) honestly this is a random throwaway gist from 2015, and someone more knowledgable about this comparison should just write a proper blog post about it. If you comment here I'll hopefully see it and stick a link to it up here. Cheers. @oconnor663

Here's the canonical TOML example from the TOML README, and a YAML version of the same.

title = "TOML Example"
 
[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00
 
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
 
[servers]
 
  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"
   
  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"
   
[clients]
data = [ ["gamma", "delta"], [1, 2] ]
 
hosts = [
  "alpha",
  "omega"
]
title: YAML Example
 
owner:
  name: Tom Preston-Werner
  dob: 1979-05-27T07:32:00-08:00
 
database:
  server: 192.168.1.1
  ports: [ 8001, 8001, 8002 ]
  connection_max: 5000
  enabled: true
 
servers:
 
  alpha:
    ip: 10.0.0.1
    dc: eqdc10
   
  beta:
    ip: 10.0.0.2
    dc: eqdc10
 
clients:
  data: [ [gamma, delta], [1, 2] ]
   
  hosts:
    - alpha
    - omega
@cdsousa
Copy link

cdsousa commented Jun 7, 2017

@quentinsf
Copy link

Yes, once it's indented properly as shown by @cdsousa, I think the YAML is much nicer.

@perfecto25
Copy link

Yaml is impossible to write w/o a linter so +1 for TOML there, but visually Yaml is nicer, almost python-like, I prefer that to Toml's INI-style

@feluxe
Copy link

feluxe commented Aug 4, 2017

I like the problems toml addresses with yaml, but I can't say that I find this visually appealing either:

[[fruit]]
name = "apple"

[fruit.physical]
color = "red"
shape = "round"

... compared to this:

fruit:
  name: apple
  physical:
    color: red
    shape: round

I like this approach, which is a simplified yaml spec.

@sorin-postelnicu
Copy link

Yes, I also agree with @feluxe.
We can say that Yaml is human-readable, while Toml is only geek-readable :)

@tclune
Copy link

tclune commented Sep 15, 2017

In my line of work (scientific software), I've only recently looked into using YAML as a replacement for some of the dated home-grown approaches to configuration files used in my community. And only learned of TOML today. Having glanced at the examples and read the comments here, I'm wondering if there is any possibility of defining a YAML-light that avoids some of the complexity of full YAML and maintains some of the other nice features? For my own work, I certainly have only implemented a subset of YAML and have not been frustrated by the missing features. (Probably helps that I'm not even really aware of what is missing.) Thoughts?

@NebulaFox
Copy link

@tclune someone has already done that https://github.com/crdoconnor/strictyaml

@miradnan
Copy link

I agree with @feluxe

@bmusin
Copy link

bmusin commented Jan 11, 2018

First is much cleaner.

@tkwilliams
Copy link

Is this a troll or is the OP a moron? Does he not realize that the "yaml" sample he's comparing to is entirely invalid, as has been pointed out multiple times, and as has been corrected in a fork of his gist? Any person with the slightest sense of rigor (or even self worth) would have fixed up the samples to actually permit an honest comparison by reasonable people, rather than intentionally skewing things as they have. If I were walking in the door, with no knowledge of either format, and saw the two (dishonest) snippets above, it's likely I would choose the first as well. But let's say, instead, that the first looked like this:

              title = "TOML \
              Example"

  [owner]
      name = "Tom Preston-Werner"
dob \
= 1979-05-27T07:32:00-08:00

[database]
server = "192.168.1.1"
ports = [
    8001,
  8001, 
8002 ]
connection_max = 5000
enabled = true

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

[servers.alpha]
dc = "eqdc10"

[servers.\
                      beta]
  ip = "10.0.0.2"
dc = \
"eqdc10"

     [clients]
data =
[
  [
      "gamma",
      "delta"
  ],
  [
      1,
      2
  ]
]

hosts =
[
"alpha",
"omega"
]

Which would you pick now? Sure, you'll complain this is intentionally mal-formatted, and very likely invalid TOML to boot, but what is presented as YAML is precisely that - intentionally (or worse, unintentionally at first but lazily NOT fixed when the error is pointed out) broken, as well as functionally invalid, YAML.

Be fair to your readers -- and avoid making yourself look like a tool in the process -- by presenting FAIR comparisons if you're going to bother to post such things at all...

@danmur
Copy link

danmur commented May 26, 2018

Brutal. Only thing I would like to add that has not been mentioned: a lot of people say that writing YAML parsers is complicated. You don't have to write your own... and if you don't like complicated things like references or the fact that YAML is a superset of JSON, just don't use those features, simple as that. I've used YAML a while and never, even as a beginner, run into difficulties with the syntax.

@grinapo
Copy link

grinapo commented May 29, 2018

As a sidenote: misformatting YAML makes it burn then explode, as the OP (and the self-promoted moron up there) shows while TOML is indent-agnostic and the syntax is the result of the symbols written.

People here seem to debate like whether Python is better than Perl just because the forced indentation and that's pretty a stupid debate: you debate the taste of others. You like either one, that's okay, but don't judge others who think otherwise. Like, I dislike python's forced indent (which screws you whenever you use a different editor with different indentational preferences), so I like TOML better, but I see why some like YAML. I prefer formal syntax instead of visual one. ;-)

@bradleypeabody
Copy link

bradleypeabody commented Jun 5, 2018

Sensitivity to whitespace is not entirely just preference, it is a tradeoff. YAML and Python treat whitespace as a meaningful part of the syntax, with the intention of making correct documents (or programs in the case of Python) also look nice and convey, visually, semantics with the indentation. However, in doing so, incorrect whitespace (including some cases of using spaces instead of tabs) also means a broken document, and sometimes in a not-very-obvious way.

The fact that the OP accidentally posted the YAML snippet with incorrect whitespace is a great example of how this approach can bite you... It's a simple mistake that results in something being broken in a non-obvious way. This doesn't make the approach wrong, but it does mean that whitespace errors will break documents in sometimes strange ways. You have to decide if the visual nicety of enforced indentation is worth that price.

I vote for TOML because this whitespace issue is IMO the most relevant difference and I think TOML gets it right.

(And FWIW, I think the Go language syntax gets it right - the compiler treats most white space as the same but there is a canonical format which can be easily enforced with gofmt [usually you set your editor up to call this during each save] - so programs generally have nicely formatted whitespace, but throwing in some extra spaces or tabs does not break things. I wish more syntaxes would adopt this approach.)

@geoff-nixon
Copy link

Um, YAML unquestionably looks nicer. It looks almost exactly like markdown. TOML looks like a shell rc file.

@exprosic-2
Copy link

exprosic-2 commented Apr 3, 2019

incorrect whitespace (including some cases of using spaces instead of tabs) also means a broken document, and sometimes in a not-very-obvious way.

Same argument applies to the infix operators with precedence problems hated by S-expression fanatics. Same solution applies too: just protect them with brackets in case of fragility.

It's a simple mistake that results in something being broken in a non-obvious way.

It's a historical disrespect for humble characters. An alphanumeric mistakenly inserted in the middle of a file path has no more natural rights than an innocent space at the beginning of a line.

@sathishsms
Copy link

sathishsms commented Apr 13, 2019

YAML seems cleaner than TOML.

@illvart
Copy link

illvart commented Jun 24, 2019

YAML for me is best because simple and faster!

@anzdaddy
Copy link

It frankly blows my mind that anyone can look at this…

[servers]

[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"

[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"

…and conclude that TOML is even a good idea, let alone better than YAML. And don't even get me started on Arrays of Tables. Wtf? For a fair bake-off, the comparable YAML should have been:

servers:
    alpha:
        ip: 10.0.0.1
        dc: eqdc10
    beta:
        ip: 10.0.0.2
        dc: eqdc10

To be clear, I am no fan of YAML for all the reasons cited by others and would be much happier if everyone moved towards Jsonnet

{
    servers: {
        alpha: {
            ip: "10.0.0.1",
            dc: "eqdc10",
        },
        beta: {
            ip: "10.0.0.2",
            dc: "eqdc10",
        },
    },
}

…which provides stronger safety guarantees while further enhancing readability. Jsonnet is cleaner than JSON, more consistent than YAML, easier to read than TOML, and much more powerful than all three…

// dcs.libsonnet
{
    eqdc10: { dc: "eqdc10", subnet:: "10.0.0" },
    eqdc11: { dc: "eqdc11", subnet:: "10.1.0" },
    ⋮
}

// config.jsonnet
local dcs = import "dcs.libsonnet";
{
     servers: {
        alpha: dcs.eqdc10 { ip: super.subnet + ".1" },
        beta: dcs.eqdc10 { ip: super.subnet + ".2" },
    },
}

But if the choice is between TOML and YAML, there is no contest.

@oconnor663
Copy link
Author

I've included the following in an edit at the top of the gist. Adding it as a comment here so that participants in this thread see it.

Hi folks. I wrote this gist for myself and some friends, and it seems like it's gotten posted somewhere that's generated some (ahem, heated) discussion. The whitespace was correct when it was posted, and since then GitHub changed how it formats <pre> tags. Look at the raw text if you care about this. I'm sure someone could tell me how to fix it, but honestly this is a random throwaway gist from 2015, and someone more knowledgable about this comparison should just write a proper blog post about it. If you comment here I'll hopefully see it and stick a link to it up here. Cheers. @oconnor663

@anzdaddy
Copy link

So it appears that a blank line inside <pre>…</pre> suppresses all subsequent indentation. You can work around this by adding &nbsp; to every blank line:

<pre>
title = "TOML Example"
&nbsp;
[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00
&nbsp;
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
&nbsp;
[servers]
&nbsp;
  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"
&nbsp;
⋮

@oconnor663
Copy link
Author

@anzdaddy done, thank you.

@anzdaddy
Copy link

anzdaddy commented Oct 15, 2019

For another data point, have a glance at the ordering of sections in https://github.com/mongodb/mongo-go-driver/blame/50e8deca6e057753b55cf8d7a3268ece2f897997/Gopkg.toml.

@eike-fokken
Copy link

With regard for the preamble:
I just googled "yaml toml json" and this is the first result. Looks like google thinks, this is the definite source on yaml toml comparison.

@sourcecodemage
Copy link

This is the definitive comparison between YAML and TOML. My professor put up a slide of this page in CS201 class and had questions about it on the final.

@oconnor663
Copy link
Author

@majorgear that is wild.

@ahmubashshir
Copy link

It frankly blows my mind that anyone can look at this…

[servers]

[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"

[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"

…and conclude that TOML is even a good idea, let alone better than YAML. And don't even get me started on Arrays of Tables. Wtf? For a fair bake-off, the comparable YAML should have been:

servers:
    alpha:
        ip: 10.0.0.1
        dc: eqdc10
    beta:
        ip: 10.0.0.2
        dc: eqdc10

To be clear, I am no fan of YAML for all the reasons cited by others and would be much happier if everyone moved towards Jsonnet

{
    servers: {
        alpha: {
            ip: "10.0.0.1",
            dc: "eqdc10",
        },
        beta: {
            ip: "10.0.0.2",
            dc: "eqdc10",
        },
    },
}

…which provides stronger safety guarantees while further enhancing readability. Jsonnet is cleaner than JSON, more consistent than YAML, easier to read than TOML, and much more powerful than all three…

// dcs.libsonnet
{
    eqdc10: { dc: "eqdc10", subnet:: "10.0.0" },
    eqdc11: { dc: "eqdc11", subnet:: "10.1.0" },
    ⋮
}

// config.jsonnet
local dcs = import "dcs.libsonnet";
{
     servers: {
        alpha: dcs.eqdc10 { ip: super.subnet + ".1" },
        beta: dcs.eqdc10 { ip: super.subnet + ".2" },
    },
}

But if the choice is between TOML and YAML, there is no contest.

well, the following is a valid toml

[servers]
alpha = {ip = "10.0.0.1",dc = "eqdc10"}
beta = {ip = "10.0.0.2", dc = "eqdc10"}

@snowman
Copy link

snowman commented Jun 28, 2022

Skip to the bottom, just to vote for YAML for it's simplicity

@jeffwright13
Copy link

jeffwright13 commented Jan 15, 2023

TOML is way better than YAML! And if you disagree with me, you're an idiot!

Also:

YAML is way better than TOML! And if you disagree with me, you're an idiot!

@anzdaddy
Copy link

anzdaddy commented Jan 18, 2023

well, the following is a valid toml

[servers]
alpha = {ip = "10.0.0.1",dc = "eqdc10"}
beta = {ip = "10.0.0.2", dc = "eqdc10"}

@ahmubashshir Have you seen any TOML actually written that way? I don't care about hypothetical usage, only real-world usage. Plus, this is a necessarily simplistic example. Real-world configs are often deeply structured, with objects of arrays of objects of arrays all over the place. Consider even basic GitHub Actions or k8s deployments. You could argue for TOML for simple cases and YAML for complex cases, but now you have to deal with two config languages for no particular reason and it'll be even more painful if you start with TOML and the schema's complexity later grows beyond what's reasonable for TOML.

@bradleypeabody
Copy link

@anzdaddy Machine-generated TOML is an example of where that is useful. For example a file starts as hand-edited configuration but then there is a UI tool that needs to read that file, make some changes to the data and then write it back out. In this case there might be a deeply nested and complex object that is convenient to emit in that longer form using {...}. It seems to be a sensible way to keep simple configuration simple but also allow these deeply nested things to exist in a succinct-but-ugly form as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment