Lagom And The Art Of Development
On sufficiency, judgement and the responsibility of knowing what is enough.
Key observations
- Development is not simply implementation after thinking is complete; it is sense-making through making.
- The central judgement is whether a team understands enough to make the next commitment responsibly.
- Certainty should be proportionate to consequence and reversibility.
- Complexity is not free: the cost of producing it is often smaller than the cost of carrying it.
- AI makes production easier, but does not remove the responsibility of deciding what is enough.
# Lagom And The Art Of Development
Development has an awkward relationship with enough.
We tend to describe it as progress. A thing begins in a simpler state and ends in a more advanced one. More capable. More mature. Often more complex.
Software has made a mess of this definition, as software tends to do when given a perfectly serviceable word.
A system can become more capable and less useful. It can grow while becoming harder to change. It can accumulate features, abstractions and dependencies until the main evidence of its development is the effort required to keep it alive. More is not a reliable sign of progress. Nor, for that matter, is change. Software changes all the time. Some of it even improves.
The Swedish word lagom is usually translated as “not too much, not too little”, which makes it sound rather beige. Sensible portions. Sensible shoes. Nothing that might trouble the neighbours.
But the useful part of lagom is not moderation.
It is sufficiency.
Enough without feeling lacking. Enough without becoming a burden.
That is a harder standard than it sounds, and a more useful one for development than most of the words we normally borrow from factories, construction sites or military planning rooms.
Enough To Begin
Development is often presented as the part that happens after the thinking.
A problem is identified. Requirements are gathered. A design is produced. Someone draws several boxes connected by arrows, which is how organisations reassure themselves that an idea has encountered reality. The thing then passes into development, where it is turned into software.
This is tidy because it suggests that development begins with understanding.
It rarely does.
Requirements are partial accounts of a situation. Designs are proposals about how people might behave. Architectural diagrams describe systems that have not yet had the inconvenience of existing. They may all be useful, and often are, but they are not the same as knowledge.
Much of what a team believes it understands remains surprisingly stable until someone attempts to make it real. Then an ambiguity becomes a decision. A requirement meets an old database. A simple workflow encounters an institution that has spent twenty years developing exceptions to it. A user behaves like a person rather than a persona. Another system refuses to do what the diagram strongly implied it would.
Development is where abstractions become answerable.
This is why it is not simply implementation. It is also a form of sense-making. We build partly because building changes what can be known.
Before something exists, people respond to descriptions of it. Once even a crude version exists, they can respond to the thing itself. They notice what feels wrong. They discover that two requirements cannot both be true. They ask for the feature they had forgotten to mention because, until now, they had forgotten it existed.
The software begins to answer back.
The conventional question is whether we know enough to implement the solution, but this still gives the solution rather too much credit. It assumes there is a settled object waiting to be built, and a point at which thinking can safely give way to execution.
A better question is whether we know enough to make the next commitment responsibly.
That commitment might be a prototype, a data model, an architectural choice, a dependency, a narrow first release or a decision that will quietly shape the next five years. These are not equivalent, and treating them as if they are is one of the small ways organisations make expensive mistakes while feeling admirably consistent.
A paper prototype can be wrong with very little ceremony. That is more or less its job. A data model is less forgiving. Once other things begin to depend on it, an early guess acquires tenants. A production release carries a different weight again, because people may begin to organise work, money or expectations around what it does.
The amount we need to know depends on what we are about to make difficult to undo.
This is where judgement enters: not as a ceremonial act at the end, when the options have been arranged into a table, but at the point where a team decides that what it knows is sufficient for the risk it is about to take.
The Difficulty Of Proportion
Software teams are often encouraged to remove uncertainty before committing to action, which sounds sensible in the same way that “be careful” sounds sensible. It is not wrong. It is merely insufficient.
Uncertainty is not a temporary flaw in development. It is one of its materials. The work is not to eliminate it, but to decide how much of it can be carried into the next step.
A reversible decision can tolerate more uncertainty. A decision that is expensive to reverse should probably tolerate less. A decision involving health, safety, money or rights should attract more care than the colour of a button on a temporary campaign page.
Again, this sounds obvious, which is always the most dangerous kind of principle. In practice, teams can spend three meetings discussing copy that can be changed tomorrow, then choose a foundational technical dependency between lunch and another meeting.
We are not always good at directing caution towards the places where being wrong will matter.
Part of the problem is that visible decisions attract attention. They can be discussed, presented, minuted, approved and later misremembered as alignment. Less visible decisions tend to arrive disguised as implementation detail, where they can do a surprising amount of governing without ever acquiring the dignity of a decision.
A choice about data can decide which future changes are easy and which become expensive. Automation can decide which exceptions remain visible. Simplification can redefine whose needs are normal and whose become edge cases.
Development distributes consequences long before anyone calls them consequences.
This is why the balance between understanding, complexity and risk is not particularly tidy. More understanding may reduce risk, but gaining it takes time. More complexity may make a system more faithful to reality, while also making it harder to understand. Simplification may reduce technical burden, while moving the burden somewhere less visible.
There is no stable optimum waiting to be discovered, which is unfortunate, because stable optimums make excellent diagrams.
There is only the next decision, the context around it, and the consequences of being wrong.
Lagom is useful here because it resists the idea that one of these things should always be maximised. Complete understanding would prevent most work from beginning. Minimum complexity would produce systems that function beautifully in situations that do not exist. Zero risk would require us to stop changing anything, which is itself a rather consequential choice.
The aim is proportion. Enough understanding for this commitment. Enough complexity for the reality we are dealing with. Enough caution for the cost of being wrong.
The difficulty is that nobody can tell you exactly how much that is.
The Failure Of More
Development culture has rarely been shy of abundance.
More scalability. More flexibility. More abstraction. More automation. More data. More process, usually introduced after the other kinds of more have gone badly.
Each can be justified, which is part of the problem. A scalable system can support growth. A flexible system can respond to change. An abstraction can prevent repetition. Automation can reduce error and drudgery. Nobody is usually asking for worse software on purpose, though some procurement processes appear to be running a long experiment.
But each kind of more adds something that must be carried.
A flexible system has more possible behaviours. An abstract system places greater distance between what it says and what it does. An automated system may operate faster while making failure harder to see. A configurable platform can accommodate every possible future, provided the present team can still work out how to configure it.
The initial cost of producing complexity is often the least interesting part. The larger cost is living with it.
Every abstraction has to be understood by someone who was not present when it seemed like a good idea. Every dependency introduces a relationship with another team, company, release cycle or set of assumptions. Every option becomes another branch through the system, another route through testing, another explanation waiting to go stale.
This does not mean that simplicity is always better. Some situations are genuinely complicated, and a system that ignores their complexity may simply be transferring it to the people forced to work around it. The ideal is not a smaller system by default. It is a system that has not mistaken its own cleverness for necessity.
More is not automatically a sign of maturity.
Sometimes maturity looks like refusing to prepare for a future that has not arrived. Sometimes it means solving the narrow problem in front of us without also building a platform for all similar problems everywhere. Sometimes it means leaving something manual because the volume, consequence or repetition does not yet justify automation.
This can look unambitious. It can also be evidence that someone has noticed the difference between possibility and need.
Experienced developers often appear to do less. They may write less code, decline to generalise a pattern after seeing it twice, ask whether a new service is necessary, or wonder aloud whether a field in the existing database might survive another year.
This is not always wisdom. Sometimes they are merely tired. But there is a kind of experience that expresses itself through restraint. It recognises which decisions need to be made now, which can remain reversible, and which problems have not yet earned a solution.
The skill is not only knowing how to build something.
It is knowing how much of it to build.
Development As A Series Of Commitments
The idea of implementation suggests a crossing point. Before it, the organisation thinks. After it, the development team executes.
This is a pleasing arrangement for everyone except the people involved in development.
Development is better understood as a series of commitments, each producing the conditions for the next. We gather enough certainty to commit, commit enough to learn, and learn enough to judge the next commitment.
Some questions can be answered through research. Some through experience. Some through conversation. Others remain theoretical until something is made, because the world has an irritating habit of withholding its objections until they are inconvenient.
This is why a small working thing can sometimes be more informative than a large amount of planning. It gives uncertainty somewhere to become visible.
The trick is to make the commitment large enough to teach us something, but small enough that being wrong remains useful. Too small, and the experiment avoids the difficult parts of the problem. Too large, and it becomes an expensive way of discovering what a conversation might have revealed. Too provisional, and nobody treats it seriously enough to learn from it. Too polished, and people become reluctant to question it.
There is no framework that removes this judgement, which is a terrible disappointment to anyone with a framework to sell.
A metric can show that a system is slow. It cannot decide whether making it faster matters more than making it comprehensible. A technical pattern can describe a sensible way to structure something. It cannot know whether the team maintaining it can carry that structure. A risk register can record possible harms. It cannot decide whose harms deserve the most weight.
These are decisions about context, consequence and value.
This is the art of development.
Not art as personal expression. Nor art as a flattering way to avoid explaining how anything works. Art in the older sense of a practised ability to judge well where rules are helpful but insufficient.
Development becomes an art at the point where no formula can tell us what enough looks like.
And Then Came AI
AI has made it much easier to produce more.
It has done rather less for our ability to recognise when more is the problem.
Code is cheaper to generate. So are tests, specifications, alternatives, documentation and architecture diagrams showing several boxes connected by arrows, because the machines have been trained on us and therefore inherited some of our more tragic habits.
This changes the economics of making. It does not remove the economics of carrying.
Generated code still becomes part of a system. Someone still has to understand what it does, decide whether it belongs, notice when it fails and work out whether changing it will disturb something elsewhere.
A cheap abstraction is still an abstraction. A plausible answer still requires someone to decide whether the question was worth answering.
AI can generate options, compare patterns, identify likely risks and produce an implementation before a team has finished agreeing on the requirement. What it does not currently do is bear the consequence of deciding that the implementation is enough.
It does not remain with the maintenance burden. It does not have to explain the decision to a user, an auditor or the person who inherits the system later. It can apply criteria, but judgement often lies in deciding which criteria matter. It can identify risk, but it does not decide whose risk counts.
This is not an argument that AI cannot participate in judgement. It already can, in useful ways. It can expose assumptions, suggest alternatives and point towards consequences a team has missed.
But it does so without responsibility.
The final decision about sufficiency still belongs to someone who must accept what follows from it.
As production becomes easier, this decision becomes more important. The scarce skill is no longer simply the ability to make. It is the ability to recognise when making more would make the work worse.
Enough
Development is usually described as movement towards a more advanced state.
Sometimes it is.
Sometimes a system becomes more mature by becoming smaller. Sometimes a team advances by deciding not to automate something. Sometimes the best next version adds no capability at all, but makes the existing capability easier to understand. And sometimes the most responsible commitment is not to begin building yet.
None of this argues for timidity.
Lagom is not an excuse for underinvestment, weak ambition or software that is almost useful. Enough should not feel lacking. It should meet the situation fully, without dragging unnecessary futures into the present.
That is the judgement at the centre of development.
Not whether we can build more, but whether we understand enough to make the next commitment responsibly. Whether the system contains enough complexity to remain truthful without becoming a burden. Whether the risk is carried by the people best placed to carry it, rather than quietly passed to someone else.
The answer will not remain correct for long. The next commitment will change what we know.
Then we judge again.
Not too little.
Not too much.
Enough.