A design system nobody opens is just a beautiful file

How to build one your developers want to work with, not against.

When we step into someone else's project, one of the first things we ask for is access to the design file and to the code repository, on the same day. Not out of impatience. The distance between those two things tells you almost everything about how the team actually works.

What you usually find is an impressive Figma file. Tokens for colour and spacing, a component library with states and variants, sometimes a documentation page explaining when to use what. You can tell someone gave this months, and usually also fought for those months against a schedule that did not want to give them.

Then you open the code. The primary button is there, and beside it sit two or three more versions under different names. Spacing is written as hard numbers instead of tokens. The stylesheet carries eleven shades of grey while the design file carries four.

The tempting explanation is discipline. The team was sloppy, the developers never read the docs, there was never enough time to do it properly. That explanation is comfortable because it blames execution rather than planning. It is also almost always wrong. We have seen very disciplined teams arrive at exactly the same place, sometimes faster precisely because of the discipline.

What happened is simpler. The system was built as a deliverable, and it needed to be an agreement.

The difference between a deliverable and an agreement

A component library is a deliverable. It has a producer and a consumer, and a clear line between them. The designer builds, the developer receives, and when something does not fit he asks for a new version. That is a perfectly sensible model, and it works beautifully for an icon set or a font file.

A design system does not behave that way, because most of what it contains is not form but decision. Why this component is called a card and not a panel. Whether the secondary button has a loading state. What the table does when it has no rows. Every one of those questions gets answered in two places at once, in the file and in the code, and if the answers differ there is no mechanism that will quietly bring them back in line.

That is what makes it an agreement. Not in any ceremonial sense, just the plain one. Two sides that settled on the same list of names and the same list of behaviours, and that share an accepted way of changing the list when it turns out to be insufficient.

The practical consequence is that a deliverable can be built alone in a room over two months and then presented. An agreement cannot.

How to tell it has happened

The first sign is that nobody remembers the names. Someone asks in a meeting where the secondary button is, and people open the file to answer. A system the team cannot speak out loud is a system the team is not really using, even if it is open in a tab.

The second sign is a component in the code called ButtonNew, or something close to it. There is always one. It does not point to carelessness. It points to someone running into a real need the system could not meet, with no reasonable way to extend it. So he went around.

The third sign is the hardest to spot, because it looks like success. Nobody is complaining. No arguments about naming, no debates about what to use when, two quiet months. A living design system produces steady friction, because people keep hitting its edges and arguing about them. Complete quiet usually does not mean agreement. It means nobody is consulting it anymore.

The order of work that works for us

Over the last few years we changed the sequence. We do not start from a system file and then translate it into code. We start from the screens that already exist in the product, or from the first screens we design if the product is new, and pull out what repeats.

In practice that means the first component is born only after we have already used it in three different places and satisfied ourselves that it really is the same thing. Sometimes it turns out not to be. Two buttons that look identical can be two separate components if they behave differently, and merging them only creates a problem that will surface six months later.

The less pleasant side of this is that there is never a moment where you present a whole, orderly system. In its place there is a long run of small decisions, some of them dull. In return, at any given moment the system describes something that actually runs. It never gets ahead of the product, so it never comes loose from it.

On documentation

We used to write long, thorough documentation. Almost nobody opened it. This was not laziness. In the two seconds a developer needs to know whether to use a card or a panel, he is not going off to find a document. He looks at what is next to him and decides.

What works is letting the component name do most of the job. If it takes a paragraph to explain why a card differs from a panel, one of the two is probably unnecessary, or the names are bad. And when an explanation genuinely is needed, its place is inside the code, next to the thing it explains, in a sentence or two.

What did not work for us

At one point we tried to enforce the system technically. We added an automated check that failed on any colour value not drawn from the token list, on the assumption that if it cannot be bypassed it will not be bypassed.

That held for about two weeks. Then people began adding new tokens in order to pass the check, and a few months later we had a colour list considerably longer than the one we started with, except now all of it was compliant.

The lesson was not especially comfortable. The check was not the problem. The problem was that we built the list without the people who had to live with it, and then tried to enforce on them a decision they were not in the room for.

Closing

There are several ways to measure a design system. How many components it holds, how many screens are covered, what share of the code uses tokens. All of those are real, and all of them are easy to fake.

The measure we watch is different. When someone on the team has to add a new screen at four in the afternoon on a Tuesday, does he open the system or go around it. If he goes around it, that does not make him unprofessional. It means the agreement was not written with him, and it is worth sitting down and writing it again.

We would like to hear

Tell us what's stuck

One line is enough. You get an opinion back, not a generic quote.