Configuration Over Code

Why the future of application building isn't about writing less code — it's about not writing code at all


In 2004, David Heinemeier Hansson pulled Ruby on Rails out of Basecamp and gave the software world a phrase it's been repeating ever since: convention over configuration. The idea was simple and, at the time, radical. Stop making developers specify every decision. If a class is named Sales, assume the database table is called sales. If a controller is named ArticlesController, assume it wants a folder called articles. Follow the pattern, and the framework fills in the rest. Deviate, and you write the code to say so.

It worked. Rails became one of the most influential frameworks in the history of the web, precisely because it removed hundreds of small, arbitrary decisions from a developer's day. But it's worth being precise about what convention over configuration actually is, because two decades of repeating the phrase have sanded down its edges.

CoC is a guessing game with good odds. The framework looks at how you named something, infers what you probably meant, and builds around that inference. It's implicit. The power is in what you don't have to write, because the framework guessed right. And when it guesses wrong — when your domain doesn't fit the pattern — you're back to writing code, just now fighting the framework's assumptions on top of it.

That's not a criticism. It's just a description of the shape of the idea. And it's a shape built for a specific problem: developers, writing code, who wanted fewer boilerplate decisions to make while writing it.

That's not the problem I'm solving.

A different question

DataPublisher didn't start from "how do we make developers write less code." It started from a different question entirely: what if the person who understands the domain never has to write code in the first place?

Not "write less of it." Not "let the framework guess your intent from your file names." Just — describe the domain. The fields. The relationships. The workflow a document needs to move through, who needs to sign it, where it goes when it's done. Describe that, once, in a structured way, and let the system build the application from the description.

That's not convention over configuration. That's configuration over code.

The distinction sounds subtle until you sit with it, and then it stops being subtle at all:

  • Convention over configuration says: the framework decides for you, silently, by pattern-matching the shape of your code.
  • Configuration over code says: you decide, explicitly, in a declaration — and the engine builds from that declaration instead of you hand-writing the plumbing.

One is a framework that reduces the coding you have to do. The other replaces coding with declaring. Those are different categories of tool, aimed at different people, solving different problems.

Why this isn't just semantics

I've spent a long time turning over the question of what DataPublisher actually is — whether "document automation add-in" undersells it, whether "application generator engine" oversells it, where the honest line sits. This is where the line sits.

A Domain App in DataPublisher isn't a config file bolted onto hand-written application logic, the way a Rails config/database.yml sits next to thousands of lines of Ruby someone still had to write. The configuration is the application. Declare the domain — the CRUD layer, the merge fields, the DataRequest lifecycle, the distribution rules — and increasingly, there's no second step where a developer translates that declaration into working software. The declaration is the working software.

That puts DataPublisher in a different neighborhood than Rails-style frameworks, and it's worth being honest about the neighborhood it's actually in: low-code and no-code tooling. Gartner's own definition of a low-code platform leans on exactly this — declarative, high-level, model-driven, metadata-based programming abstractions instead of traditional code, trading some raw flexibility for enormous gains in speed and accessibility. That's the family DataPublisher belongs to.

But most no-code tools pay for that speed with a black box. Drag-and-drop builders hide the model from you — you can shape the application, but you can't read what you built, can't version it cleanly, can't hand it to another domain expert and have them understand it at a glance. That's the tradeoff GitHub's Chris Wanstrath was gesturing at when he said the future of coding is no coding at all, and it's the same tradeoff critics point to when they note that low-code tends to break down as complexity climbs — the same story Visual Basic lived through in the 90s.

Configuration over code, done right, doesn't have to make that trade. A Domain App Pack is a structured, legible declaration — not a settings panel bolted onto someone else's code, and not a black box you can shape but not read. It's the source of truth the application is generated from, and it stays inspectable the whole way through. You can hand it to a career center student learning the Guild apprenticeship model, or to a records manager who's never opened a code editor, and they can follow what it says. That's the wedge no-code tools usually can't offer, because most of them were built to hide complexity rather than declare it plainly.

The older idea underneath the new name

None of this is entirely without ancestry, and it's worth naming that honestly too. "Configuration over code" doesn't have a founding document the way convention over configuration has DHH's Rails Doctrine. It's floated up independently in a few adjacent places — the DevOps world's move toward declarative infrastructure (Kubernetes YAML, Terraform, describe the end state and let the system reconcile toward it, rather than scripting the steps to get there); the older enterprise instinct to externalize configuration out of hardcoded logic so a setting can change without a redeploy; and now the low-code movement's push toward metadata-driven application generation.

What ties those threads together, and what DataPublisher sits at the intersection of, is a single underlying move: push more of the system into declared state, and less of it into imperative steps someone has to write and maintain. Convention over configuration was one specific, branded instance of that older impulse — a clever way to reduce imperative decisions for developers who were still, ultimately, going to write code. Configuration over code is the fuller version of the same impulse, aimed at people who were never going to write code at all, and shouldn't have to.

Why it matters

Every domain expert who has ever needed a working application and had to wait on a developer to build it has felt the cost of that gap. The homeschool co-op coordinator. The real estate office running the same intake form by hand for the hundredth time. The records manager who knows exactly what the workflow should look like but has no way to say so except in a meeting with someone who does know how to code.

Convention over configuration made things faster for the people already inside the codebase. Configuration over code is trying to close the distance between the person who understands the problem and the software that solves it — so that the description of the domain isn't a spec handed off to someone else to implement. It's the implementation.

That's the chord I was reaching for. Not a better tagline for a familiar idea, but a name for the actual thing being built: an engine where declaring what you need is building what you need, and nothing gets lost in the translation between them.