RSS Feeds

Blog
Bookmarks

My View on Design Engineering

and the tasks nobody owns

“Design engineer” is a fairly new job title, and there isn’t a definition everyone agrees on yet.1 Ask a few people and you get a few different answers. A designer who can code. A frontend developer with an eye for detail. Someone who sits somewhere between design and development, whatever that means in practice.

None of those are wrong. They’re just descriptions of a person, and I don’t think a person is the interesting part. The role is: there is a specific set of tasks that has to be done in every digital product, and on most teams nobody is responsible for them.

Consistency is more important than ever

When writing code stops being the bottleneck, coherence becomes the bottleneck.

Most of this work happens on products that already exist. Not all of it, but most: something that has been running for a few years, with a backlog, a team that has changed twice, and a codebase nobody has read all of. New products get there faster than they used to. A couple of months in, and there is already a history to be consistent with.

What changed is the pace. When a change took a while to build, that time did some of the work for you, because to extend something you had to go and look at what was already there. Generated code skips that step. It reads well, it looks right, and it tends to know nothing about what sits next to it. Every new feature makes sense on its own, and so does every small change inside one. That’s the problem. Nothing is wrong anywhere in particular, and the product still falls apart.

So you get four kinds of button, three date formats and two competing ideas about what the color blue means. Spacing that is close but not the same. A panel that slides in on one page and fades in on the next, because two different people, or two different prompts, each made a reasonable choice.

SaveSaveSaveSave
Each one was a reasonable choice on the day it was made.

Mechanical engineers have a name for this. A tolerance stack-up is when every part in an assembly is within spec and the whole thing still doesn’t fit, because all the small allowances happened to lean the same way. Nobody made a mistake. It just adds up.2

This is what a design system is for, and I think it usually gets explained badly. People picture a component library, which is only one of the parts. In practice it’s a set of tools and methods that have to work together: the components, design tokens, written guidelines, and now the context files and agent skills that tell the AI writing the code what the rules already are. That list keeps changing, and keeping it current is part of the job. Together they do two things. They give guidance where somebody has to make a decision, and they put guardrails around the decisions that get made without anyone noticing. That’s how consistency survives any single person on the team and any single prompt.

Consistency isn’t something a team can own as a group. You can ask everyone to care about it, and everyone can care about it, and the product will still drift (see tolerance stack-up). It’s a job. And from my point of view a job for a designated design engineer.

Details make a product a good product

The product is the source of truth, not the design files.

Consistency is not the only aspect of a good product. You can build a product where every button matches, every spacing value comes from the same scale, nothing contradicts anything, and the whole thing is still lifeless and unpleasant to use. Coherence is the foundation and the role as a design engineer doesn’t stop here.

This is the part people feel: animations, transitions, and the microinteractions that tell you an app noticed what you did. A button reacts when you press it. A menu grows out of the thing you tapped instead of appearing from nowhere, and a message tells you your work was saved.

None of it comes for free. By default a screen jumps straight from one state to the next. A door in the real world swings open, it doesn’t teleport, and getting that same feeling on a screen takes somebody deciding to build it.

Static
With transition
Tap a tile in either grid, and again to close it. Both open the same thing, but only one of them tells you where it came from.

The same goes for everything a design file leaves out. A file shows a product at its best. One screen width, plausible data that someone made up, and the path where everything goes right. Shipping that same screen means answering a much longer list of questions. What happens with a name that’s sixty characters long? Does the layout jump around when the data finally loads? What if there is no data at all, and is that an empty state or does it look like something broke? What about a slow connection, a narrow phone, someone who never touches a mouse? More and more often there is no design file to begin with. A feature goes from a sentence to something running, and all of those questions still arrive at once, with nobody having thought about them first.

They get answered either way. Usually by whoever is holding the code at the time, near the end of a sprint, in the fastest way available. Which is fair enough. It was never really their call to make. It should be the call of a design engineer.

Two definitions of done

Designers and developers look at the same work from different places. Both have a definition of “done”, and the two definitions aren’t the same.

Done, for a developer: it works, it’s tested, it’s fast, it didn’t break anything else. Done, for a designer: it behaves the way it was meant to behave and it looks good.

They don’t use the same words either. The same feature gets described twice, in two vocabularies, and both descriptions are right.

What helps is somebody who speaks both. Somebody who knows what each side worries about and what each side judges the work by, and who can give the two of them a shared vocabulary to work in.

One more thing I’ve noticed, and can’t explain. The craft you came from first seems to stick to you. A developer who gets good at design is called well-rounded. A designer who learns to build gets asked whether they can really engineer. Same skills, opposite reaction. I don’t know why that difference gets made, or whether it goes away as more people end up doing both.3

And then there’s taste, which is a horrible word

It sounds like snobbery. It sounds like someone in an expensive chair explaining why the thing you like is bad. I’ve been looking for a better word for a while and haven’t found one, so I’m going to use this one and try to be precise about what I mean by it.

Taste isn’t knowing what’s good. Most people know what’s good. Taste is what you do when there are ten options in front of you and all of them are acceptable. It’s being able to say no to something that is fine.

It’s also the part of consistency you can’t write down. A rule can say that every dialog closes the same way. It can’t tell you that the one deleting someone’s work should be slower, or heavier, or ask twice. Every good product breaks its own rules somewhere, and no rule can tell you where.

Think about two apps that do exactly the same thing, where one of them feels noticeably better and you can’t explain why. You can’t point at the feature responsible, because there isn’t one. It’s the sum of a few hundred small decisions, none of which would survive being written down as a requirement. That’s the awkward thing about this part of the work: people register it reliably and can rarely name it, which makes it hard to argue for and easy to cut.

I think this is the part that’s becoming more valuable, though not quite for the reason people usually give. Producing something that looks like a working interface has been getting cheaper for a long time and continues to. Design is worth no less for it. The difficulty has just moved. When making things is cheap, the expensive skill is choosing: deciding which of the ten acceptable versions ships, and being willing to throw away nine that would have been fine.4

Conclusion

So, a definition. A design engineer is the person who owns whether a product still agrees with itself. In a design file, everything agrees. In a component library, everything agrees. You only find out in the running product, where the pieces sit next to each other. And part of the job is knowing which patterns to break.

I don’t think that has to be a job title. If your team already has someone doing this work without a name for it, that’s the good outcome, and the label would just be paperwork. The title is only useful because it makes the work visible enough to plan for and to hire for.

I also don’t think anyone holds all of this at the same level. The people who describe this role well tend to be describing a team, not a person.5

Keeping a product coherent is the part that gets talked about. The harder half is deciding what’s worth being coherent about. Ask me again in two years and I’ll probably have rewritten all of this.

Footnotes

  1. Not a new title in mechanical engineering, where a design engineer is the one answerable for whether a part can actually be built. Thread in r/MechanicalEngineering

  2. Tolerance stack-up is a standard problem in mechanical design: the accumulated effect of the variation that each individual dimension is allowed. The version I’m describing is the worst case, where every part sits at its tolerance limit in the same direction at once. Tolerance analysis

  3. This observation isn’t mine. It came up on Syntax #1027.

  4. I keep a note in my digital garden collecting things other people have written about taste. The line that stuck with me most: “the question is no longer ‘can it be made?’ but ‘is it worth making?’”

  5. Vercel’s write-up on design engineering makes this explicit: no individual is expected to have every skill the team collectively brings. vercel.com/blog/design-engineering-at-vercel