Things I Don't Like in Configuration Languages

4 hours ago 1

Spoiler: I created my own configuration language maml.dev

Here will be a list of all markup languages/configuration languages I found on the internet, and things I don't like about them.

YAML

- - 1 - 2 - - 3 - 4

YAML 1.2 is better than YAML 1.0. But still, the YAML specification is monstrous, and I don't get how people trying to implement it are not going insane. YAML contains too many features.

XML

<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="http://ex.com/catalog" xmlns:cat="http://ex.com/catalog" xmlns:old="http://ex.com/oldcatalog"> <item id="0042"> <name>R&amp;D Handbook</name> <notes priority="1 2 3">n/a</notes> </item> </catalog>

The era of XML is in the past. I remember the hype around XML, how it was thought to be a universal format, and people created a lot of stuff around it. But now it's dead.

JSON

{"name": "John", "age": 30, "car": null}

JSON is nice and JSON won. It's a universal, data-interchange format for the Web and applications. This is why I based my MAML on top of JSON. I fixed things that were a little bit annoying for me inside JSON.

TOML

[[servers.web]] name = "frontend" ip = "192.168.1.10" [[servers]] region = "eu-central" [[servers.web]] name = "backend" ip = "192.168.1.11"

I don't get why the [table] is more readable, and I don't understand [[array of tables]] out of order. And the lack of null.

JSON5

{ lineBreaks: 'Look, Mom! \ No \\n\'s!', hexadecimal: 0xdecaf, a: +.8675309, b: +8675309., }

Too many unnecessary features. Object key-value pairs are still unordered. No distinction between integers and floats.

HJSON

{ Hjson: a string RegEx: \s+ md: ''' First line. Second line. This line is indented by two spaces. ''' }

Unquoted strings and three different types of comments. Multi-line strings with significant indentation.

JSONH

{ // use #, // or /**/ comments keys: without quotes, isn\'t: { that: cool? # yes } }

JSONH is same as HJSON but different.

RJSON

{ shopping-list: [ milk butter /* don't forget the beer */ beer ] a\ space : t\:em item\ with\ spaces }

Strings without quotes, but only if they don't contain spaces or commas. No specification.

JSONC

{ /* This is a multi-line comment that spans multiple lines */ "name": "Jane Doe", "age": 25, }

There are so many implementations and differences in implementations of JSON with comments. For example, this one has trailing commas. Still allows duplicate keys, still no integers, unordered key-value objects.

HCL

service "aws_ami" "ubuntu" { most_recent = true instance_type = var.instance_type != "" ? var.instance_type : "t3.micro" }

I don't like nesting with service "http" "web_proxy" or ability to specify service multiple times in different parts of the file.

Pkl

class Bird { name: String hidden taxonomy: Taxonomy } pigeon: Bird = new { name = "Common wood pigeon" taxonomy { species = "Columba palumbus" } }

This is not a markup language. This is a full-blown programming language. I honestly would just use TypeScript instead of this one.

RON

GameConfig( // optional struct name window_size: (800, 600), key_bindings: { "up": Up, "down": Down, "left": Left, "right": Right, }, )

Very Rust-centric.

EDN

#:demo{:id #uuid "de305d54-75b4-431b-adb2-eb6b9e546014" :ts #inst "2025-11-04T09:00:00Z" :nums [1 2 3 4/2 5.5M] :set #{:a :b :c} :rx #"[A-Z]+" :q #queue ["x" "y"] :tag #user{:name "Zed"}}

I guess Clojure developers love it. I'm not one of them.

HOCON

include required("foo.conf") a : [ 1, 2 ] [ 3, 4 ] data-center-east = ${data-center-generic} { name = "east" } { foo include : 42 }

Too many features. Is it some sort of programming language? And it looks like it's very focused on just one project.

NestedText

default repository: home report style: tree compact format: {repo}: {size:{fmt}}. Last back up: {last_create:ddd, MMM DD}. date format: D MMMM YYYY size format: .2b

YAML variant with only strings. But I need booleans!

KDL

author "Alex Monad" [email protected] active=#true scripts { message """ hello world """ }

KDL is much closer to XML with properties on nodes. But I like JSON-like data structures. They are easier to understand. Also, I don't like significant indentation on multi-line strings.

SDLang

// Trailing semicolons are optional prop true; anotherprod on; author "Peter Parker" this-is.1_valid$Tag-Name renderer:options "invisible" physics:options "nocollide" title \ "Some title"

They do have true and false. Why adding on and off? By default, integers are 32 bits long. Suffix 10L is needed for 64-bits.

CUE

import "math" piPlusOne: math.Pi + 1 "quoted field names": { "four^four": math.Pow(4, 4) }

I would just use TypeScript instead of this programming language. Too many features; the specification is too big.

Dhall

let makeUser = \(user : Text) -> let home = "/home/${user}" let privateKey = "${home}/.ssh/id_ed25519" let publicKey = "${privateKey}.pub" in { home, privateKey, publicKey } {- Add another user to this list -} in [ makeUser "bill" , makeUser "jane" ]

Again, it is a programming language. So I guess only one implementation of Dhall exists?

Jsonnet

local my_function(x, y=10) = x + y; { person1: { name: "Alice", welcome: "Hello " + self.name + "!", }, person2: self.person1 { name: "Bob" }, len: [ std.length('hello'), std.length([1, 2, 3]), ] }

Well, this is some sort of programming language with dynamic types. But there are so many good programming languages, so I don't know why this one needs to be used.

Nickel

let conf = { name = "NiCl", version = "0.0.1$", description = "My cool app!" } in let SemanticVersion = fun label value => let pattern = "^\\d{1,2}\\.\\d{1,2}(\\.\\d{1,2})?$" in if std.string.is_match pattern value then value else let msg = "invalid version number" in std.contract.blame_with_message msg label in let AppSchema = { name | String, version | SemanticVersion, description | String, } in conf | AppSchema

Nice programming language. Not a markup language.

Starlark

def fizz_buzz(n): """Print Fizz Buzz numbers from 1 to n.""" for i in range(1, n + 1): s = "" if i % 3 == 0: s += "Fizz" if i % 5 == 0: s += "Buzz" print(s if s else i) fizz_buzz(20)

Starlark is a programming language. Good lack porting/reimplementing Starlark in another programming language.

UCG

let tuple = { inner = { field = "value", }, list = [1, 2] + [3], "quoted field" = "quoted value", };

This is just an implementation of a language. Not portable to other languages.

UCL

.include "${CURDIR}/path.conf" .macro_name(param={key=value}) "something"; section "blah" "foo" { key = value; }

Okay. An implementation of a configuration language. No specification. No other implementations.

Confetti

probe-device eth0 eth1 user * { login anonymous password "${ENV:ANONPASS}" machine 167.89.14.1 proxy { try-ports 582 583 584 } }

Nice logo! But other than that, I found it difficult to understand what's going on in this example. What about escaping in strings?

HUML

website:: ports:: 80, 443 enabled: true factor: 3.14 props:: mime_type: "text/html", encoding: "gzip" tags:: - "markup" - "webpage" - "schema"

Nice idea to make YAML less worse. But it's still a YAML, with the same problems and significant indentation.

MAML

{ project: "MAML" tags: [ "minimal" "readable" ] # A simple nested object spec: { version: 1 author: "Anton Medvedev" } # Array of objects examples: [ { name: "JSON", born: 2001 } { name: "MAML", born: 2025 } ] notes: """ This is a multiline raw strings. Keeps formatting as-is. """ }

So, I decided to create a specification for my own language. And I wanted a distinctive name, not JSON something. I wanted a nice name and a strict specification. All languages have trade-offs. MAML as well.

Read Entire Article