When Designers and Engineers Disagree (And Both Are Right)
Or: Why the Best Products Come from Arguments Nobody Wins
The Slack thread had forty-seven replies. Nai, one of our designers, had stopped typing and started walking — weaving through the open-plan desks on level 6 toward the engineering area, which is never a good sign. The air conditioning hummed the way it always does when a conversation is about to get interesting: just loud enough that people at neighbouring desks can pretend they’re not listening. Someone’s Thai iced tea sat untouched on a desk, condensation slowly working its way down the plastic cup.
This wasn’t a disagreement about whether something looked nice. This was two people, both excellent at their jobs, both absolutely certain they were protecting the user — and both right. That moment, the one where a designer and an engineer lock eyes across a design review and neither blinks, is the moment that determines whether your product team is genuinely collaborative or just politely dysfunctional.
As the architect Charles Eames once said, “The details are not the details. They make the design.” He understood something most product teams don’t: details matter enormously, but which details matter is the real question. And when a designer and an engineer disagree, they’re almost never arguing about whether details matter — they’re arguing about which detail matters more.
The Header That Started a War
Here’s the story. Our design team wanted the site header to change its background colour depending on whether the user was on a modern page or a legacy one. The logic was sound from a design perspective: each page has its own visual identity, its own mood, and the header should feel like it belongs to the page you’re on. Mismatched headers create a subtle but real sense that the product is stitched together from different eras — which, to be fair, it was.
Engineering pushed back. The argument was equally sound, but rooted in a completely different discipline: web performance. Specifically, Cumulative Layout Shift and contentful paint metrics. When you navigate between pages, you expect the header — the single most persistent element on the screen — to remain stable. A header that changes colour on navigation isn’t just a visual inconsistency; it’s a layout signal that tells you something fundamental has changed. Google’s Core Web Vitals penalise exactly this kind of visual instability. And users, even when they can’t articulate it, perceive a page where the chrome stays consistent as faster and more trustworthy than one where elements shift around.
Both sides were right. The designers were optimising for visual coherence within a page. The engineers were optimising for perceptual stability across pages. Neither concern was trivial. Neither was wrong.
How did it end? The header stayed consistent. Engineering won this one — partly because the CLS argument had measurable data behind it, and partly, if I’m being honest, because I was stubborn about it. That honesty matters: not every design-engineering disagreement resolves through elegant compromise. Sometimes one side wins. The question is whether the winning argument was principled and whether the losing side was heard.
But here’s the thing worth sitting with: did the right side win? Probably. The header consistency makes the product feel faster and more stable as users navigate. The designers’ concern about legacy pages looking stitched together was real — but the answer turned out to be fixing the legacy pages, not making the header pretend they didn’t exist. Sometimes the right resolution to a design-engineering disagreement isn’t a compromise at all — it’s recognising that both sides identified a real problem, but only one side proposed a solution to the right problem.
Why We Talk Past Each Other
You’ve been in these conversations. You know the dynamic. The designer presents a vision that makes your stomach drop because you can already see the fourteen edge cases it doesn’t account for. Or you’re the one watching an engineer casually propose “just a simple dropdown” that will absolutely destroy the interaction pattern your team spent three weeks refining.
The pattern is always the same. Designers protect the user’s experience. Engineers protect the system’s health. And the product suffers when either side wins absolutely.
What designers see that engineers often miss: spacing that feels wrong isn’t aesthetic fussiness — visual rhythm affects comprehension and trust. That animation isn’t decoration — it’s communication, guiding attention and signalling state changes. The ugly error state isn’t a nice-to-have — a beautiful happy path with a broken edge case teaches users your product is fragile. Inconsistency across components isn’t minor — every deviation is a micro-decision the user has to make.
What engineers see that designers often miss: what works for a hundred items shatters at ten thousand — the demo isn’t the product and doesn’t scale to the 99th percentile that we measure the server side response time sla on. Every custom component is something someone has to maintain, test, and keep compatible indefinitely. That beautiful unified experience might require coupling three services that currently deploy independently. And design tools don’t have network latency, memory constraints, or accessibility requirements baked in.
As the physicist Richard Feynman put it, “The first principle is that you must not fool yourself — and you are the easiest person to fool.” Both designers and engineers are susceptible to this. Designers can fool themselves that fidelity matters more than feasibility. Engineers can fool themselves that technical constraints are more rigid than they actually are. The magic happens when both sides are honest about what they’re actually optimising for — and whether that’s the right thing to optimise for right now.
Five Hundred Shades of Blue
A decade ago, Agoda’s design-engineering interface was a classic one-way handoff. Designers produced mockups. Engineers figured out what CSS to write. Nobody checked whether the blue in this designer’s mockup was the same blue as that designer’s mockup.
The result: at one point, the Agoda website had something like five hundred different shades of blue. Not because anyone was incompetent — because the system had no mechanism for consistency. Every designer was making independent colour choices. Every engineer was faithfully implementing those independent choices. The cumulative result was a visual experience that looked like it was designed by a committee that never met.
This is the natural outcome of one-way handoffs to engineers: code entropy. When anyone can add a shade of blue but nobody owns the palette, inconsistency isn’t a bug — it’s the inevitable thermodynamic outcome.
The first attempt at a design system was open to contributions from anyone. This sounds collaborative, but in practice, it succumbed to a similar entropy it was meant to prevent. Without governance, a democratised design system is just a more organised version of the chaos it replaced. Components proliferated. Variants multiplied. The system became so permissive that it stopped being a system. I’ve rarely seen collective code ownership work, too many owners always leads to no ownership at some tipping point (actual result may vary on this).
As the management thinker W. Edwards Deming observed, “A bad system will beat a good person every time.” We had good people in a bad system. The fix wasn’t better people — it was better infrastructure.
The Design System as Shared Infrastructure
What works today is ADS — Agoda’s Design System — and the key insight is in the team structure, not the component library. A group of engineers and designers worked together to raise the five-hundred-shades-of-blue problem as a systemic issue and propose a fundamentally different way of working. The result was a dedicated ADS team that builds and owns the design system.
Here’s the common mistake most companies make: treating the design system as a design thing that engineers adopt. This creates two sources of truth — a Figma component library and a coded component library — that inevitably drift apart. The design system becomes the very source of the inconsistency it was meant to prevent.
ADS is owned by a central team that comprises both designers and engineers. This isn’t a detail — it’s the whole game. When the design system team includes people who think in pixels and people who think in code, the system naturally evolves as shared infrastructure rather than a design artefact that engineering has to consume.
What this looks like in practice: designers compose pages from ADS components in Figma. Engineers compose pages from the same ADS components in React. Because both sides use the same building blocks, “pixel perfect” isn’t something engineers aim for — it’s something they get automatically by using the right component. The team uses Playwright component testing for visual regression — automated tests that catch when a rendered component drifts from its expected appearance. There are Figma-to-code parity checks that verify the Figma components and their coded counterparts stay in sync.
And then there’s the part that still slightly amazes me. We’ve built an MCP — Model Context Protocol — integration for ADS, which means coding agents can reference the design system directly. The actual workflow today often looks like this: an engineer takes a screenshot of the Figma design, pastes it into Cursor, and asks it to generate the React code. Cursor uses the ADS MCP to look up the correct components, their props, their variants — and generates code that uses the real design system components. The Figma MCP itself is still rubbish, so the screenshot-to-Cursor-to-MCP pipeline is the pragmatic workaround. First-pass success rate is around 40–50% — not perfect, but even when it’s wrong, it’s usually almost right. A few manual tweaks and you’re done. That’s a significant time saving over writing component composition from scratch.
Brad Frost — the creator of Atomic Design — has argued that “handoff” and “automation” are the two most damaging buzzwords in design systems, because they strip away the humanity and collaboration that actually make good products. Our model validates his point. We didn’t solve the handoff problem by automating it. We solved it by making the handoff unnecessary.
Design Is How Engineers Understand the Problem
Here’s where this connects to something bigger. Most “design-engineering collaboration” articles frame the relationship as a workflow problem — how do we move artefacts from one discipline to another with less friction? That framing is wrong. Design is how engineers understand the problem they’re solving.
In a Product Engineering model, everything is a problem you’re solving. The engineer’s job isn’t to implement a spec — it’s to solve a user problem using technology. But you can’t solve a problem you don’t understand. And a key understanding of user problems lives in the design discipline — in user research, in Jobs-to-be-Done analysis, in the empathy that comes from watching someone struggle with your product.
At Agoda, engineers get involved in design thinking exercises and the Jobs-to-be-Done framework. This isn’t about making engineers into designers. It’s about three things.
First, business acumen. When an engineer watches a user try to complete a booking and struggle with a particular flow, they understand the business impact viscerally. That’s different from reading a ticket that says “improve booking flow conversion.”
Second, empathy with the product. Engineers who understand why a design decision was made are better equipped to preserve the intent during implementation — and to push back when the intent is unclear or the design doesn’t actually serve the user.
Third, better engineering decisions. An engineer who understands the user’s job-to-be-done makes different technical choices than one who’s implementing a spec. They anticipate edge cases the designer didn’t think of. They suggest simpler solutions that achieve the same outcome. They know which corners to cut and which are load-bearing.
This is why the header story is instructive. If the designer and engineer had only argued about visual consistency versus CLS scores, it’s a stalemate. But when both sides ask “what problem are we solving for the user?”, the answer gets richer: users need to feel that the product is coherent and that it’s fast and stable. That’s not a design problem or an engineering problem — it’s a product problem that both disciplines illuminate from different angles.
Tactics for When You’re in the Room and It’s Getting Heated
You’re going to find yourself in these disagreements. Here’s what works.
Start with “What are we optimising for?” Before debating the solution, agree on the goal. Are we optimising for launch speed, user delight, system simplicity, or long-term maintainability? Often, the disagreement dissolves when both sides realise they’re optimising for different things — and neither was explicitly stated.
Quantify the trade-off. Put numbers on it. “This custom animation adds two days of engineering and one day of QA. Is that trade-off worth it for this feature?” Sometimes yes, sometimes no — but making it explicit prevents resentment.
Explore the spectrum, not the binary. Disagreements often present as “your design” versus “my technical constraint.” The productive move is to map the spectrum. “Here’s the full version — two weeks. Here’s a good-enough version — three days. Here’s the minimum — one day. Which point gives us the best value for the investment?”
Timebox the disagreement. If you can’t resolve it in thirty minutes, you don’t have enough information. The next step should be research — user testing, a technical spike, data analysis — not more arguing.
And the one I use most: the “two weeks from now” test. If we ship this version, will anyone — user, designer, engineer, stakeholder — be upset about this trade-off in two weeks? If not, ship it. If yes, invest more.
The Bottom Line
Design-engineering tension isn’t a bug in your process. It’s the feature that produces your best work — if you have the organisational muscle to use it. Kill the handoff. Build shared infrastructure. Get engineers into user research and designers into architecture discussions. Not to approve each other’s work, but to understand it. Celebrate when a designer changes direction based on engineering feedback. Celebrate when an engineer goes beyond the spec to get the details right. Build the buddy system that gives you both consistency and collaboration.
And when the disagreement hits — and it will — remember that you’re not arguing about who’s right. You’re arguing about which detail matters more. The answer is almost always “both, and here’s the third option neither of us saw yet.”
Now, if you’ll excuse me, I need to go review a Figma file. Apparently the designer buddy for one of my teams has forty-seven comments, and I have a feeling I know how this ends.