Daniel
Labs

writing / on-restraint-in-software

8 min read

On restraint in software

The most consequential architectural decisions are not what you add but what you refuse to build. A case for aggressive omission.

There is a particular kind of engineering confidence that expresses itself through addition. A new abstraction, a new configuration surface, a new escape hatch for the edge case that hasn't happened yet. This confidence is often mistaken for capability.

The more difficult skill is restraint: knowing precisely what not to build and being willing to defend that absence.

The cost of optionality

Every option you expose is a contract. Every configuration parameter is a test case, a documentation entry, an upgrade concern, a source of user confusion. The API surface of a system is not neutral — it accumulates weight, and that weight is carried by every engineer who touches the codebase after you.

The discipline of omission asks: what is the minimum interface that makes this useful? Not the minimum that makes it complete. Usefulness and completeness are often in tension.

The best code is code that doesn't exist.

This is not laziness. It is the recognition that software has an entropy problem — it grows in complexity with time, and the only reliable countermeasure is to start with less.

What restraint looks like in practice

Restraint is visible in what a system refuses to do:

  • An editor that doesn't support drag-and-drop because drag-and-drop implies a document model that fights the writer's intent
  • A type system that doesn't allow any in domain code because any is a deferred runtime error wearing a compile-time mask
  • A CMS that exposes three primitives instead of forty because the fortieth primitive is a solution to a problem that the product shouldn't have

In each case, the absence is a decision. The default is to add. Choosing not to requires a clarity of purpose that most codebases never develop.

The source of the pressure

Why do systems accumulate complexity? Rarely because of poor individual decisions. More often because the pressure to add is constant and the pressure to remove is intermittent.

A user requests a feature. A colleague suggests an improvement. A blog post describes an architecture that looks applicable. Each of these pressures is real and often well-intentioned. But without an equally real pressure in the other direction — a principle, a constraint, a sentence about what the system is not — the system will grow toward the center of all possible systems: indistinct, general, and difficult to reason about.

The purpose statement is load-bearing. "This is a tool for writers who think in structure" is a decision surface. It answers the feature requests before they are made.

Restraint as craft

The analogy to prose is not accidental. A sentence that says too much says nothing. A paragraph that anticipates every objection becomes unreadable. The writer's job, like the engineer's, is to understand the full space of what could be said and then choose the minimum that conveys the maximum.

This is not a skill that improves automatically with experience. It requires active practice, which means actively choosing to remove things: code, features, options, configuration surfaces. The refactor that deletes more than it adds is the hardest kind to ship and the most valuable.

The systems that age well are not the ones that prepared for everything. They are the ones that were clear about what they were for.

ArchitectureCraftDesign
← All writing