I built tcon to make configuration changes easier to validate and review. A file can be valid JSON or YAML while still containing a misspelled key, an invalid value, or an old setting left behind by a manual edit.
The compiler takes a typed definition and produces the configuration files an application needs. A separate check compares those outputs with the files on disk, so drift can fail CI before deployment.
Choosing predictable output#
I made generation deterministic, including key ordering, so a diff reflects a configuration change rather than a change in formatting. The same definitions can produce JSON, YAML, environment files, TOML, and properties files.
Version 1 replaces the generated file completely. I left merging out because it would make ownership less clear: when a generated value conflicts with a manual edit, someone still has to decide which one wins. Full replacement keeps the definition authoritative.
The compiler has no dependencies. That keeps it self-contained, but makes me responsible for the parser, validation, output formats, and diagnostics.
Deciding what the compiler should reject#
Validation includes where a file can be written and how secrets enter it. Output paths must remain within the owning workspace, even through symlinks. Secret fields must use environment values and cannot contain defaults.
I also treated error codes as part of the compatibility contract. People can read an error message, but CI scripts need a stable way to interpret it. Versioned fixtures check both successful output and expected failures.
tcon is open source. The language guide (opens in a new tab) and compatibility fixtures (opens in a new tab) describe the current version.