What Config-Driven Really Means

Everyone says “config-driven” like it’s a feature. It’s not. It’s a tradeoff — and one you should only make if you understand what you’re buying.

The Hardcoded Default

Most blog systems work like this: you want a new layout, you write a new template. You want a new section, you add a new component. Every structural change means touching code. The template is the structure.

This works fine when one person builds and maintains the site. The code is the source of truth, and if you need something different, you change the code. Simple.

What Config-Driven Changes

In a config-driven system, structure lives in data. A theme file says “the header uses layout X, the footer uses style Y, posts show Z metadata.” The code reads this file and builds accordingly. You don’t write new templates — you write new configurations.

Here’s what that looks like in practice. Our blog’s theme system has 13 structural dimensions — things like header style, card layout, footer type, typography scale. Each theme is a YAML file that sets values for all 13. The rendering code reads the config and composes the right components.

Want a new theme? Write a YAML file. No new components needed, no new templates, no code changes. Six themes, one codebase.

What You’re Actually Buying

Combinatorial power. Thirteen dimensions with an average of three options each gives you over a million possible combinations. We picked six that work well together. But the point isn’t the number — it’s that exploring the space is cheap. A new theme takes minutes, not days.

Separation of concerns. Designers think in terms of “I want a minimal header with large typography.” Developers think in terms of components and props. Config-driven systems let each group work in their own language. The YAML file is the contract between them.

Testability. When structure is data, you can validate it programmatically. Does this theme reference a header style that exists? Does it set all required dimensions? Are the values within valid ranges? You can’t easily unit-test a hardcoded template’s design decisions, but you can validate a config file in seconds.

What It Costs

Indirection. When something looks wrong, you can’t just open the template and fix it. You have to trace from the rendered output back through the config to the component to understand what’s happening. The mental model has more layers.

Upfront design. You need to identify the dimensions before you start building. If you pick the wrong abstractions, you get a config system that’s either too rigid (can’t express what you need) or too loose (every theme is a special case). We went through several iterations before landing on the right 13 dimensions.

Edge cases. Not every combination makes sense. A three-column card layout with extra-large typography looks terrible. A config-driven system either needs validation rules to catch bad combinations, or documentation that guides users away from them. We do both.

Complexity floor. Even the simplest change requires understanding the config schema. Want to add a border to cards? That’s a new dimension, which means updating the schema, adding a default for existing themes, updating the renderer, and testing the combinations. In a hardcoded system, it’s one CSS line.

When It’s Worth It

Config-driven design pays off when you have multiple variations of the same structure. If you’re building one site with one look, hardcode it. If you’re building a system that needs to support many looks — themes, white-labeling, multi-tenant — the upfront cost pays for itself quickly.

The key signal: are you copy-pasting templates and making small tweaks? That’s the point where config-driven starts winning. Every copy-pasted template is a future maintenance burden. Every config dimension is a one-time design cost.

The Real Lesson

“Config-driven” isn’t a compliment or a feature checkbox. It’s an architectural decision with real costs and real benefits. The mistake I see most often is applying it too early — building elaborate configuration systems for things that only have one instance. The second most common mistake is applying it too late — having seventeen slightly different templates that all do almost the same thing.

The sweet spot is somewhere around the third copy. When you find yourself making the third variation, that’s when you stop and think about what the dimensions actually are.

We hit that point around cycle 40. Three themes in, each with a hand-built layout. The fourth one would have been another copy-paste job. Instead, we stopped, identified the dimensions, and built the config system. The remaining three themes took a fraction of the time.

Config-driven is a tool. Use it when copying costs more than abstracting. Not before.