Skip to content

HOCON, four times over

One specification. Four parsers that agree. A shared conformance corpus that keeps them honest.

Most HOCON libraries are one person’s port of the parts of the spec they needed. These four are the same parser written four times: the same three-stage pipeline, the same specification, and the same test corpus, with every divergence between them recorded rather than discovered later in production.

TypeScript

Node.js 22+

Runs in Node and the browser. Ships an optional Zod bridge for typed config.

npm install @o3co/ts.hocon

Go

Go 1.23+

Zero external dependencies in the core; adapters live in a nested module.

go get github.com/o3co/go.hocon

Rust

Rust 1.82+

One dependency (indexmap). Serde and every adapter are feature-gated.

cargo add hocon-parser

Python

Python 3.11+

Pure standard library. Imported as `hocon`, published as `hocon-parser`.

pip install hocon-parser

Actually the whole language

Substitutions, self-reference, += append, includes, duration and byte-size units, triple-quoted strings, deep merge with last-wins semantics. Not a JSON parser that tolerates comments.

Almost no dependencies

Python is pure standard library. Go and TypeScript have zero runtime dependencies in the core. Rust has one. Foreign-format adapters are opt-in and never reach the core.

Differences on the record

Where a language forces a hand — surrogate pairs in JavaScript strings, byte-oriented Go strings — the divergence is a numbered item in the shared checklist, not a surprise.

Verified against the reference

Expected values come from Lightbend’s own implementation, not from hand-written guesses about what the spec means.

HOCON is JSON with the things configuration files actually need. Comments survive. Values reference other values. Files include other files. Environment variables layer over defaults without a templating step.

# Comments, and no quotes needed for ordinary keys and strings
app {
name = my-service
host = "0.0.0.0"
port = 8080
# Substitution — and ${?VAR} falls back silently when unset
base-url = "http://"${app.host}":"${app.port}
log-level = info
log-level = ${?LOG_LEVEL}
# Units are part of the language, not something you parse yourself
timeout = 30s
max-upload = 64MiB
}
# Later files deep-merge over earlier ones
include "overrides.conf"

Read the whole format →

If the tool consuming your configuration does not speak HOCON, hocon2 converts in both directions — HOCON to JSON, YAML, TOML and Java Properties, and back.

Terminal window
go install github.com/o3co/hocon2/cmd/hocon2json@latest
hocon2json app.conf

hocon2 →