TypeScript
Node.js 22+Runs in Node and the browser. Ships an optional Zod bridge for typed config.
npm install @o3co/ts.hoconRuns in Node and the browser. Ships an optional Zod bridge for typed config.
npm install @o3co/ts.hoconZero external dependencies in the core; adapters live in a nested module.
go get github.com/o3co/go.hoconOne dependency (indexmap). Serde and every adapter are feature-gated.
cargo add hocon-parserPure standard library. Imported as `hocon`, published as `hocon-parser`.
pip install hocon-parserPick a language. The tab selection is shared across the site, so the rest of these pages follow it.
import { parse } from '@o3co/ts.hocon'
const cfg = parse(` server { host = "localhost" port = 8080 }`)
cfg.getString('server.host') // "localhost"cfg.getNumber('server.port') // 8080cfg.has('server.host') // trueimport "github.com/o3co/go.hocon"
cfg, err := hocon.ParseString(` server { host = "localhost" port = 8080 }`)if err != nil { log.Fatal(err)}
host := cfg.GetString("server.host") // "localhost"port := cfg.GetInt("server.port") // 8080use hocon;
fn main() -> Result<(), Box<dyn std::error::Error>> { let config = hocon::parse(r#" server { host = "localhost" port = 8080 } "#)?;
let host = config.get_string("server.host")?; let port = config.get_i64("server.port")?;
println!("Server: {}:{}", host, port); Ok(())}import hocon
cfg = hocon.parse(""" server { host = "localhost" port = 8080 }""")
cfg.get_string("server.host") # "localhost"cfg.get_int("server.port") # 8080cfg.has("server.host") # TrueThe accessor names follow each language’s conventions rather than a single cross-language
spelling — getString in TypeScript, GetString in Go, get_string in Rust and Python. What
they do is identical.
The pattern most configuration reaches for: a default in the file, overridden by the environment when set, with nothing to change in code.
app { log-level = info log-level = ${?LOG_LEVEL}
database { url = "postgres://localhost/dev" url = ${?DATABASE_URL} pool-size = 10 pool-size = ${?DB_POOL_SIZE} }}${?VAR} resolves against the environment, and when the variable is unset the line is skipped
entirely — so the default above it survives. No templating step, no envsubst, no sentinel
values.
The full API surface — typed accessors, Option variants, deferred resolution, fallback
merging, error types — is documented per implementation rather than duplicated here, because a
single cross-language API page would go stale in four directions at once.
.properties through the same API