Configuration starts as a small file with a dozen settings. Then there are three environments, so there are three files. Then the files share most of their content, so someone adds templating. Then the templates need conditionals, and the conditionals need variables, and eventually you have a string-templating language generating structured data with no type checking, no validation, and errors that surface at deploy time as an unhelpful parse failure.
That progression is nearly universal, and it is the problem typed configuration languages exist to solve.
What changed in 2026
- The category consolidated. Several typed configuration languages matured enough for production use, with clearer differentiation between validation-focused and full programming approaches.
- Validation shifted left. Catching configuration errors at author time rather than deploy time became a stated goal of platform teams rather than an aspiration.
- Generation replaced templating in more pipelines. Producing plain output files from a typed source, rather than templating them directly, became the recommended pattern.
- Schema-first approaches spread. Defining the shape of valid configuration and validating against it gained ground even in projects keeping plain files.
Approaches compared
| Approach |
Validation |
Composition |
Complexity |
| Static files per environment |
None |
Copy and paste |
Lowest; drifts badly |
| String templating over files |
None; text substitution |
Includes and variables |
Deceptively high |
| Schema validation on plain files |
Structural |
None |
Low; good value |
| Typed configuration language |
Types and constraints |
First-class |
Moderate |
| General-purpose language generating config |
Whatever you write |
Full |
High; easy to over-engineer |
The third row is underrated. Simply adding schema validation to existing plain files — defining what valid configuration looks like and checking it in continuous integration — catches a large share of real errors for very little effort, without adopting a new language at all. For many teams that is the right stopping point.
The last row is where projects overshoot. Writing configuration in a general-purpose programming language gives you unlimited power and unlimited ability to produce configuration nobody can reason about. Configuration that requires running a debugger to understand what will be deployed has failed at its job.
The pattern that works
Keep a typed source of truth, generate plain output, commit the output.
The typed source is where humans work and where validation happens. Generation produces ordinary files in whatever format the consuming tool expects. Committing the generated output means anyone can read exactly what will be deployed without running the generator, and it makes changes visible in review as concrete diffs rather than as changes to a program that produces them.
Handle environments through composition rather than duplication. One base definition, with per-environment overrides layered on top, so a change to shared behavior happens once. Parallel per-environment files always drift, and the drift is always discovered in production.
Validate in continuous integration. Whatever your source format, the check that the generated configuration is structurally valid and satisfies your constraints belongs in the pipeline alongside the other gates in CI/CD caching strategies. For validating data shapes generally, the approaches in JSON schema validation guide apply directly.
Common mistakes
- Templating structured data as text. The tool does not know it is producing YAML, so it cannot help you.
- Adopting a configuration language too early. Three files do not justify the tooling.
- Not committing generated output. Reviewers cannot see what actually changes.
- Unlimited logic in configuration. Configuration you have to debug is not configuration.
- Per-environment copies. They diverge, always, and the divergence is found late.
FAQ
Is YAML the problem?
Not really — YAML has quirks, and the actual problem is generating structured data with untyped string templating. Schema validation improves plain YAML substantially.
Which typed configuration language should I pick?
Depends on your ecosystem and what your tooling already supports. Prefer one with strong validation over one with the most expressive programming model.
Should generated files be in version control?
Generally yes. The diff is what reviewers need to see, and it means deployment does not depend on the generator running correctly.
What about secrets?
Never in configuration files, generated or not. Reference secrets by name and resolve them at runtime from a secret manager.
Where to go next
For validation mechanics, read JSON schema validation guide. For pipeline structure, CI/CD caching strategies and zero-downtime deployment.