TOML vs YAML vs JSON5 untuk config file
3 format config alternative dari JSON. YAML masih dominant. TOML simpler. JSON5 minimal departure. Verdict tergantung use case + tooling.
TL;DR
- TOML: Recommended untuk config tool Rust, Python, dev tooling
- YAML: Conditional — dominate di DevOps (Kubernetes, GitHub Actions, Docker Compose) tapi syntax fragile
- JSON5: Recommended untuk config JavaScript/TypeScript (replace JSON yang butuh comment)
- JSON: stay untuk wire format / API
Konteks
Config files yang saya manage 2024-2026:
package.json(JSON) — npm/Bun ecosystemtsconfig.json(JSON with comments, treat as JSON5) — TypeScript.github/workflows/*.yml(YAML) — GitHub Actionsdocker-compose.yml(YAML) — Docker ComposeCargo.toml(TOML) — Rust projectastro.config.mjs(JS) — Astrobiome.json(JSON) — Biomewrangler.toml(TOML) — Cloudflare Workers
Banyak format. Reality di 2026.
Format primer
JSON (untuk reference)
{
"name": "my-app",
"port": 3000,
"features": ["auth", "billing"],
"database": {
"host": "localhost",
"port": 5432
}
}
Pro: ubiquitous, parser di every language. Con: tidak ada komentar, syntax verbose (trailing comma error, double quote required).
JSON5
{
// Komentar OK!
name: 'my-app', // Single-quote OK
port: 3000,
features: ['auth', 'billing',], // Trailing comma OK
database: {
host: 'localhost',
port: 5432,
},
}
Pro: JSON + komentar + lenient syntax. Easy migration dari JSON.
Con: harus pakai library parse (npm json5), bukan native.
TOML
name = "my-app"
port = 3000
features = ["auth", "billing"]
[database]
host = "localhost"
port = 5432
Pro: visually clean untuk flat config, sections jelas via [header], syntax simple (no significant indentation).
Con: tidak cocok untuk deeply nested data (nesting [a.b.c] jadi awkward).
YAML
name: my-app
port: 3000
features:
- auth
- billing
database:
host: localhost
port: 5432
Pro: paling readable untuk nested structure, comment OK, value tanpa quotes.
Con: significant whitespace = fragile (extra space bisa break parse), boolean parsing surprises (no jadi false, yes jadi true).
Use case decision matrix
Config untuk CLI tool / library
Pilih TOML kalau:
- Tool ditulis di Rust atau Python (TOML adalah standard)
- Config relatively flat (max 2-3 level nest)
- User-facing config (developer akan edit)
Contoh: Cargo.toml, pyproject.toml, wrangler.toml.
Config untuk JavaScript/TypeScript tool
Pilih JSON5 kalau:
- Existing tool sudah pakai JSON config (tsconfig.json, jsconfig.json)
- Butuh komentar untuk dokumentasi inline
- Parser library OK to add (json5 npm package)
Pilih JS/TS module kalau:
- Config butuh logic (dynamic value, conditional)
- Anda OK dengan “config sebagai code”
Contoh: astro.config.mjs, vite.config.ts, tailwind.config.js.
Config untuk DevOps / infra
Pilih YAML (de facto standard) kalau:
- Kubernetes manifest
- GitHub Actions
- Docker Compose
- CI/CD pipeline
Tidak ada banyak pilihan — YAML dominate. Tapi gunakan dengan caution.
YAML gotchas yang harus diketahui
1. Boolean parsing surprise
country: no # NORWAY parse jadi `false` (boolean!)
yes_no: yes # parse jadi `true`
month: oct # parse jadi `false` (oct = octal yes)
Fix: quote string yang bisa misinterpret.
country: "no"
yes_no: "yes"
month: "oct"
2. Number parsing
version: 1.20 # parse jadi 1.2 (trailing zero lost)
ip: 192.168.1.1 # parse jadi string "192.168.1.1" (OK, but reason: dots prevent number parse)
3. Significant whitespace
items:
- name: A
description: B # ERROR — alignment off by 1 space
Tab characters illegal di YAML. Mixed tab/space common cause of YAML parse error.
4. Multi-line string
description: |
Line 1
Line 2
description2: >
Line 1
Line 2 # folded jadi "Line 1 Line 2"
| preserves newlines, > folds them. Subtle different behavior.
TOML gotchas
1. Datetime ambiguity
TOML support datetime tapi format strict (RFC 3339). User Indonesia sering tulis “01-12-2026” yang TOML reject.
2. Nested array of tables
[[users]]
name = "Asti"
[[users]]
name = "Reza"
[[users]] (double bracket) = array of tables. Confusing untuk pemula.
3. Comments tapi limited
TOML support # comment, tapi tidak block comment. Hanya line comment.
JSON5 gotchas
1. Tools support tidak universal
Banyak tool yang accept JSON5 syntax (TS compiler, VS Code) tapi banyak juga yang tidak. Cek per-tool.
2. Extension confusion
.json5 extension less recognized dari .json. Beberapa editor tidak auto-format JSON5.
Workaround: keep file as .json, treat as JSON5 internally. Most JSON parser yang lenient (TS, VS Code, Biome) accept.
My current config strategy
Untuk SMB Indonesia project:
| File | Format | Rationale |
|---|---|---|
package.json | JSON | npm standard |
tsconfig.json | JSON5 (de facto) | TS compiler accept comments |
astro.config.mjs | JS module | dynamic config |
biome.json | JSON | Biome standard |
.env | dotenv | simple key=value |
wrangler.toml | TOML | Cloudflare standard |
.github/workflows/*.yml | YAML | GitHub Actions standard |
docker-compose.yml | YAML | Docker standard |
Saya tidak fight tool defaults. Tetap pakai format yang tool prefer.
Konteks Indonesia
Multi-language teams: kalau team Anda mixed (JS dev + DevOps + sysadmin), YAML jadi common ground karena familiar di semua role. Worth accept friction.
Localization (datetime, number): Indonesia pakai DD/MM/YYYY format kadang. Hindari embedding tanggal di YAML/TOML config — pakai ISO 8601 string yang Anda parse di code.
# Buruk
release_date = 2026-04-12T00:00:00Z
# Lebih baik
release_date = "2026-04-12" # parse di code
Tooling
YAML linter
yamllint(Python) — comprehensive checker- VS Code: “YAML Language Support” extension
TOML linter
taplo(Rust) — fastest TOML toolchain- VS Code: “Even Better TOML” extension
JSON5
json5npm package- VS Code: built-in support untuk
tsconfig.json-style
Verdict
Conditional:
- Pakai TOML, YAML, JSON5 sesuai convention tool yang Anda pakai. Jangan fight default.
- Untuk new config Anda sendiri (e.g., config file untuk SaaS Anda), pilih TOML kalau Rust-y world atau dev tool, JSON5 kalau JS world, YAML kalau DevOps integration matter.
- Selalu document comment kenapa setting tertentu. Config tanpa comment = mystery di 6 bulan ke depan.
Hindari:
- Inventing new format
- Mix-and-match (e.g., yaml.json) — confuse tooling
- Plain JSON untuk anything beyond machine-readable wire format
Ditulis oleh Asti Larasati