April 3, 2026
3m 37s

We often treat code as the implementation of a design. In practice, code is frequently the design itself. It is the most precise, complete, and continuously maintained description of how a software system behaves.
I have rarely seen design documentation that accurately reflects the current state of a mature software system. Architecture diagrams, UML models, requirements documents, and interface specifications all tend to drift over time. The code changes daily. The documentation changes when someone remembers.
This is not an argument against documentation. Documentation serves many important purposes: communication, onboarding, planning, architectural discussion, and capturing intent. But we should be honest about its limitations. Documentation describes a system. Code defines it.
As I have argued elsewhere, UML is often a poor abstraction for software. The problem is not that UML is inaccurate. The problem is that software evolves faster than any static representation can keep up with. A diagram that was correct six months ago may now describe a system that no longer exists.
Code is not the only artifact that evolves with the system. Tests evolve as well.
In many mature systems, the combination of code and tests provides a more accurate description of the design than any collection of documents. The code describes structure, interfaces, ownership, and execution. The tests describe expected behavior, constraints, and assumptions.
When engineers modify a system, they often update the code and tests together. Documentation may or may not be revised. Over time, this makes the codebase and test suite the most reliable source of truth about what the system actually does.
A new engineer trying to understand a component will frequently learn more from reading the implementation and its tests than from reading a design document written years earlier. The tests reveal the behaviors that the team considered important enough to preserve.
Code is different. Every bug fix, feature addition, refactoring, and test update changes the design. The design evolves because the code evolves.
This becomes especially obvious in systems developed iteratively. Engineers begin with an architectural vision, implement part of it, test it, discover problems, and revise the design. New constraints appear. Better abstractions emerge. Components are reorganized. The architecture itself may change in response to what is learned during implementation.
In that sense, software design is not something that happens before coding. Design happens through coding.
Well-structured systems make this easier to see. Responsibilities are clear. Ownership is explicit. Component boundaries are visible. An engineer can often infer the design simply by following the flow of data through the code.
The opposite is also true.
In what I have previously called Coral Reef Software, years of accumulated changes can obscure the original design. Responsibilities become scattered, dependencies become tangled, and behavior emerges from interactions that are difficult to trace. The code remains the most accurate description of the system, but the design it describes may itself have become difficult to understand.
This does not invalidate the idea that code is the design language. It reinforces it.
A coral reef codebase is not evidence that code fails as a design language. It is evidence that the design itself has become difficult to understand.
The final design of a successful system is rarely the one that existed on the whiteboard at the beginning of the project. It is the one that survived implementation, testing, maintenance, and real-world use.
Documentation explains intent. Architecture establishes boundaries. Tests preserve behavior.
But code remains the place where all three ultimately meet.
Code is not merely the implementation of a design. For software systems, code is the design language itself.