a rant of configs (and intro to ckt config files)

all config formats suck (and mine sucks just a little less)

published on 2021-04-20

all data formats suck for user facing configuration; they're either too complicated, not human readable, not machine readable, not complicated enough, or a combination of all of those.

keep in mind i am just critizing these as use for configuration files, and they may excel in other things (data serialization and the like), while ckt may not.

here are all my (least) favourite offenders.


eXtensible Markup Language

i don't think i need to go too much into XML. i don't like it, and i don't think anyone really does. it's not machine or human readable by really any sense of the word.

i don't think a lot of people really disagree with me here, and i'm not gonna preach to the choir; nobody (not many) people use XML for simple configuration files.


JavaScript Object Notation

congrats! we've taken a big huge massive fat step up from XML! here's what i really like about JSON.

1. it's human readable enough with a little bit of noise

2. it's extremely machine readable!

though of course, i have a few problems with it:

1. it's not human typeable enough; that is, all the { " , }s get in the way when you're just trying to just write a damn config file. this isn't a problem for all things, but for little configuration files it can get in the way.

2. nooo trailing commas! this is a small point but relates back to #1.

3. though the opposite of what ive typed just a second ago, it is not extremely human readable!

4. too many data types in its specification; while this might be the opposite of what you've heard / experienced with json, i am just talking about simple config formats here! id like to leave the data types up to the user rather than up to the specification. (in fact, many of these formats have the same issue, though i guess this is a highly opinionated one.)

5. no comments!

here's a quick example in JSON that ill copy in other formats to show you how they look;

   "firstName": "John",
   "lastName": "Smith",
   "isAlive": true,
   "age": 27,
   "phoneNumbers": [
           "type": "home",
           "number": "212 555-1234"
           "type": "office",
           "number": "646 555-4567"

so, what? should i make a superset of JSON? a JSON with the problems fixed?

no! i shouldn't do that. that's 1. too boring, 2. a bit pointless, 3. has been tried too many times.


Yaml Ain't Markup Language

YAML is a strict superset of JSON that is a tad bit more readable. here's what i like about it:

1. it is a tad bit more readable than JSON is, with much less noise

2. it is much more human writable than JSON, making it much better for configuration!

3. commmennntss :)

here is what i really don't like about it:

1. it is super complicated! (seriously. the spec is fucking massive; i can't imagine trying to write a completely spec-compliant YAML parser.

2. seriously the spec is too large!

while the JSON example works in YAML, ill put a more yaml-like example here for visuals

firstName: John
lastName: Smith
isAlive: true
age: 27

# john's phone numbers
   - type: home
     number: "212 555-1234"
   - type: office
     number: "646 555-4567"

this is super readable and the syntax is almost intuitive! though i am not completely satisfied


Tom's Obvious, Minimal Language

TOML isn't a superset of JSON! cool! and it's 'obvious' and 'minimal', so i should be happy with it! here is what i like about it:

1. though minor, key = value is more obvious to me than key: value (or parent: child)

2. it is designed to map unambiguously to a hash table!

3. it has a single, formal specification, while ini has many differing competing variants (this isn't completely a good thing)

4. it is easy enough to implement

here's what i don't like about it:

1. toml is not completely obvious, indicating 'obvious' is merely part of a naming template rather than an actual descriptor.

2. the spec decides data types (as in JSON, YAML, but not INI) rather than the user/implementation

3. less typeable than YAML; it is a bit more noisy

and of course, the example in TOML


# john's phone numbers
number="212 555-1234"

number="646 555-4567"

it is really unobvious how to do array of tables like this, a not immediately clear from the syntax either.


boring human readable data format for Zig

zzz syntax describes a tree of strings. it has very little syntactic noise and is really easy to implement!

here is what i really really really really like about zzz

1. it is super duper simple and lightweight - you can read its (sparse) spec in about 2-3 minutes

2. the spec itself doesn't define any data-types, only a parent:child relationship

3. super duper readable and typeable

4. reference implementation is in zig!! (yay zig!)

in fact, i really like zzz! its implementation is really great, and it's super nice and simple.

here is what i don't like about it:

1. it doesn't always unambiguously map into a hash table. consider the following:

    : value: New
      onclick: CreateNewDoc()
    : value: Open
      onclick: OpenDoc()
    : value: Close
      onclick: CloseDoc()

how would i go about putting this into a hash map?

specifically "menuitem"; it is just a bunch of k-v pairs with empty keys. hash tables can't have repeating keys, so i would have to see if the key was empty or something and use that to make a list. this is not unambiguous and lead me to a little bit of headache while trying to use it.


1. i hate XML.

2. i hate using JSON for config.

3. i hate implementing YAML.

4. i hate the lies and unobviousness of TOML.

5. i really like ZZZ, but i just want to parse some god damn thing into a hash table.


CricKet's Table notation

here's some things i thought about and tried to perfect while ckt:

1. supreme typeability (e.g. using [] rather than {} for tables means less shift holding)

2. a sort-of specific spec? one that's specific enough for ckt files not to differ in syntax, but not specific enough to make it extremely complicated to implement properly

3. supreme readability! config files are for humans to write, after all

4. obviousness - a super short read of the spec or just reading a ckt file and you should know all about how to write a ckt file

and here are some things i did not try to make ckt for:

1. complex data types (if you want/need to use complex datatypes, i do not think ckt is the way to go)

2. speed - while i'm sure one could create a blazing fast static implementation or something, i didn't really have it in mind when designing the spec or writing my implementation

3. other people - you might absolutely despise this format. that's okay. i made this format really only for myself; others are free to use, implement, fork, etc and that's great, but i had really only thought about myself while writing it. i only got opinion from one other person.

shut up and show me!

ok! here's that repeated example as a ckt file


# john's phone numbers
phone_numbers = [
        number=212 555-1234
        number=646 555-4567

here is a little description of ckt:

# ckt files describe tables
# tables inside this top-level one are
# surrounded with square braces []

# initializations are separated by
# newlines, commas, or semicolons

# key value pairs are
# 'record style initializations'

# keys are strings
# values are strings or tables
record style = woah isnt it cool ?
init table = [ key = value ]

# surrounding whitespace is trimmed
# the below is equivelant to the above
"record style" = "woah isnt it cool ?"

# duplicate keys are overwritten
x = 13
x = 161
# (x = 161)

# bare values are
# "list style initializations"
value1, value2
table = [ list, style, initialization ]

# the keys of list style initializations
# should be the previous list-style key+1,
# counting up in decimal
equivelant table = [
    0 = list,
    1 = style,
    2 = initialization

# you can mix and match
polyline = [
    color= blue; thickness = 2
    [ x = 0;   y = 0 ]
    [ x = -10; y = 0 ]
    [ x = -10; y = 1 ]
    [ x = 0;   y = 1 ]

# also, multiline strings
hehehe =
    |look at this COOL

you can read the "complete" specification here.

if you want more examples, this blog uses ckt for its posts.

if you want to use it right away, i have a small implementation written in zig! (though ckt is designed to be as easy to implement as possible)

(do note that no actual hate is directed at any of the formats hated on above.)