Design | 13 min read

The full stack design system

hero

UI methodologies like Atomic Design bring logic and structure to individual screens. Now it’s time to extend that thinking to every aspect of your product.

Here’s a little mystery. Why is it that – a bit like hangovers and pop music – most products somehow seem to get worse with age?

You’d think the opposite should be true: that having a great team spend many years iterating on a product should eventually result in some immaculately perfect finished product. Instead after ten years it’s suddenly harder to unlock your phone. Why?

The long, painful answer is ill-discipline. Projects grow over time. More people join, some earlier folks leave, and clarity of design vision deteriorates. The business decides to chase new markets, and new features get tacked on like Christmas decorations. Internal collaboration gets harder and sub-teams develop their own design philosophies. Requests flood in from a more diverse customer base. Competition needs to be kept at bay by adding in more stuff. Sprawl sets in. Before long it doesn’t feel safe to enter some screens alone after dark. Good products degrade. It happens to the best of us.

The shorter answer is most product teams don’t adhere to a solid underlying design system. Something that unifies and guides all aspects of the experience from the conceptual building blocks of the product, to the details of the UI, to how things are named.

So if you’re suffering from the nice-to-have problem of designing a successful, growing product, here’s how considering all aspects of your design as a single system can save you – before the rot sets in.

The TL;DR

Given that this is the internet and you’ve probably got animal videos to watch, I’ll cut to the chase:

  1. 50 years ago graphic designers figured out that it’s a good idea to come up with some shared underlying rules when designing a bunch of related things.
  2. Digital product designers realized this is also a good way to make sure your buttons always look the same. “Design Systems” emerged as a useful way to build consistent UIs.
  3. But most Design Systems are really just Pattern Libraries: a big box of UI Lego pieces that can be assembled in near-infinite ways. All the pieces may be consistent, but that doesn’t mean the assembled results will be.
  4. Your product is more than just a pile of reusable UI elements. It has structure and meaning. It’s not a generic web page, it’s the embodiment of a system of concepts.
  5. By embodying product concepts in Design Systems designers can go beyond consistent UIs towards creating consistent products.

That’s the nutshell version. If you already get it, godspeed.

Software with structural integrity

Making software isn’t like building a bridge. Construction workers have a clear end goal to aim for, mature methodologies and well-understood materials, and most of them dress better. The majority of industries are far more stable than software development. That’s good — most people generally prefer driving across bridges that weren’t designed using whiteboard markers and engineered by Googling for error messages.

Manhattan Bridge under construction, 1909

Manhattan Bridge under construction, 1909. © Irving Underhill/Library of Congress

Digital product design is still in its infancy. We’re figuring this shit out as we go. As soon as we do figure something out, things change again – the tech improves, your team grows, competition emerges – and that process that you finally figured out breaks again. Plans are obsolete almost as soon as you’ve made them.

Without a blueprint of some sort to rely on it’s not surprising that so much software eventually buckles under its own weight.

So clearly we need something to set and keep us on course. Something to make the difficult parts of product development easier, make the slow parts faster, and to power us away from the enormous Pit Of Complexity that all products seem to get drawn into over time.

Enter Design Systems.

A brief history of design systems

Design Systems of one flavor or another have been around for quite a while. Simply put, a design system is useful for when you need to design not just one thing, but a whole set of things that you want to feel like a coherent family. If you come up with a template and always stick to it, you’ll get that coherence for free.

So instead of designing one subway sign you might come up with a set of graphic standards that allow you to design a whole set of signs and symbols that work together in concert. Also, can we bring back ring binders please? Old school cool.

New York City Transit Authority Graphics Standards Manual by Massimo Vignelli and Bob Noorda, 1970

New York City Transit Authority Graphics Standards Manual by Massimo Vignelli and Bob Noorda, 1970 source.

Or instead of designing a logo for an organization you might develop a visual system for representing that organization in all sorts of different contexts. Space exploration and classic graphic design, what’s not to love?

The NASA Graphics Standards Manual by Richard Danne and Bruce Blackburn, 1975

The NASA Graphics Standards Manual by Richard Danne and Bruce Blackburn, 1975 source.

CSS frameworks like Twitter Bootstrap dragged these ideas into the world of web development, providing reusable code snippets to easily build consistent UI elements like buttons and dropdowns. Wonderful, even if every website in the world basically looked identical for a while there.


Twitter Bootstrap, originally created by Mark Otto and Jacob Thornton, 2011

Brad Frost’s influential Atomic Design methodology put forward a more structural approach. Rather than a jumble of “atomic” elements scattered across a screen (e.g. a label, an input, a button), Atomic Design suggests that a small collection of UI elements should be thought of as a meaningful component, (e.g. a page footer, a login form). Put a pin in this idea, we’ll come back to it in a bit.

Brad Frost’s Atomic Design methodology, 2013

Brad Frost’s Atomic Design methodology, 2013

Finally, Google’s Material Design guidelines pushed the concept further, bringing deeper formal rationality, a bold aesthetic and resources and guidelines for building UI elements across a range of platforms. (I worked at Google and wrote the first set of guidelines for the Android Wear platform.)

Material Design by Google, 2014

Material Design by Google, 2014

Today, many larger companies have built their own custom, in-house design systems in an attempt to stave off the inevitable creep of inconsistency. Airbnb, Salesforce and Uber have built comprehensive systems that keep their own product UIs in check.

The limitations of pattern libraries

Maybe none of this is news to you. Maybe you’ve already got someone maintaining a nice little pattern library on your own team. (If you’re not sure who, just look for the person who can’t stop making Lego analogies.)

So can’t you just check the box and move on? Or is there a difference between a pattern library and a design system?

I mean, sure. But yes there is.

Most Pattern Libraries take the form of a web page that lists the different styles of all your UI elements: all the different sized headings, all the button styles, all the dropdowns that are used to build your UI. If all the designers and engineers on your team agree to only ever use these elements, your UI automatically stays consistent. It also allows you to tweak those styles down the road if you want to make a design change across your app. Not bad at all.


Intercom’s old, now-retired pattern library. Need some buttons? We got ‘em.

But there are a few problems with pattern libraries. Yes, they allow you to keep all of the smallest elements consistent. But they don’t have an opinion about how they should be put together. They don’t know anything about your product or the concepts behind it.

To return to our Lego analogy, simply having a limited pattern library of bricks to choose from doesn’t preclude me from building some really crazy shit.


Impressive, but not exactly coherent design – and that’s just the curtains. Source

Now think about those branded Lego kits you can buy. Each piece is much more opinionated. It knows what it’s going to get used for. There are still generic pieces involved, but when you put them together in a certain way they form something specific, like the leg of an AT-AT Walker. This is a design system.

(Caveat: those highly-prescribed branded kits are actually kind of boring and there’s no Lego better than a giant bucket of bricks and an imagination. Coherence is strictly for grown-ups.)

From Atomic Design to full stack design systems

This approach is not unlike the Atomic Design approach I mentioned earlier. Atomic Design will tell you to take some of your basic elements (label, input, button), stick them together, and call it a molecule. Then you can reuse that molecule again and again. Further, you can stick some molecules together to form a reusable organism.

The problem with every real-world example of a system like this that I’ve encountered is that they remain wilfully unaware of the product being built.

When you’re creating a bespoke Design System for a specific product, you have the opportunity to not just group common UI elements together, but to actually represent your core product concepts at many levels. I call this a Full Stack Design System.

Here’s what a Full Stack Design System might consist of:

  • A shared conceptual model of your product. This is the diagram you’d draw on a whiteboard to explain how your product works at a system level. What are the main objects in your product? How do they interact?
  • Shared language that everyone on your team uses to refer to your objects. Remember, words matter. If designers, engineers, and support people all use the same word to describe the same thing, so much organisational fogginess goes away. Elizabeth, our Content Strategy Lead here at Intercom, calls this using “the same language from code to customer”.
  • Shared design resources to quickly create mockups that accurately reflect our design systems. This often takes the form of a single Sketch file that everyone has access to. The file contains a Symbol for each object, and often multiple variations for displaying the same object at different sizes or in different contexts.
  • Shared code components that allow engineers to build these components and their variations, often with a single line of code. There should be a 1:1 mapping of the objects in Sketch and in our codebase.

Most importantly, there’s a unifying thread through all of these levels. A ‘Conversation’ in Intercom – one of our core objects – is the same, very specific thing whether it’s being sketched, described, designed or coded. If we want to change that object in some way, we can consistently change it across all levels. Teams are locked in and ambiguity disappears. In this way the sum of the system becomes much greater than the parts.

Here are examples of possible objects in products you know:

  • Facebook: Friend, Post, Message, Event, Page, Group.
  • Airbnb: Listing, Host, Guest, Trip, Experience.
  • Slack: Team, Member, Channel, Message, Reaction, Thread.
  • Intercom: Customer, Teammate, Message, Conversation, Article.

In each case, the objects don’t just describe a UI widget. They mean something very specific in the context of the product.

A Full Stack Design System extends the component-based ideas of Atomic Design to be specific to our product and directly relevant to everyone involved in making it.

A real-life example

To illustrate, let’s look at how we use the Conversation object when building Intercom.

First, we have an overview of the Conversation object in Build, an internal website that explains what each object is and how it interacts with the wider system:


Each object listed in Build has a nifty link that opens that object directly in our Designers’ shared Sketch file:

And another that opens the code snippet used by engineers to implement the object:

Here’s how we describe a Conversation in our publicly-available Glossary:

Our support teams and help doc authors consistently use the same language too:

At all levels of this stack – system model, user interface, implementation, documentation – we aim to capture the structure of our product in a consistent, meaningful way.

Why this works for Intercom

This idea is central to our design success at Intercom. We’re still a fairly small company, yet we’re building multiple products that are used in many different and powerful ways. It would be very easy for us to slip into that The Pit of Complexity. Yet we aspire to swim against the tide and actually make our products more simple and elegant, even as we add to what they can do.

Our strategy for achieving this is to use this small set of core objects that we can chain together into specific workflows. Every time we build something new at Intercom we ask ourselves how we can solve the problem using the materials we already have. New concepts naturally creep in as needed, but they are introduced consciously and we’re diligent about merging concepts whenever we have the opportunity.

The product stays lean and precise despite growing in capability. We can polish the hell out of our core objects so that they get better over time, and those improvements show up in many places across all of our products. Reuse allows us to move faster.

And most importantly, our users don’t have hundreds of concepts to keep in their heads all the time. When they adopt a new Intercom product, it already feels familiar because it’s made up of the same stuff.

The system works

So that’s how to keep your product out of The Pit. Think of what you’re designing not as a series of screens but as a system of objects, and then realize those objects at every level: conception, design, build, marketing, support.

I’ll be honest: I don’t even know if this is going to fully work. I’ve tried, and I honestly can’t think of any products that are both powerfully flexible and elegantly simple – suggestions welcome! Maybe it’s impossible and The Pit awaits us all. But that doesn’t seem like a great note to end a blog post.

What’s more, I don’t want to believe it’s true. This very challenge is what’s uniquely interesting to me about doing large-scale design work at a growing product-oriented company.

The early signs are promising. In all types of complex systems, from codebases to architecture, clarity comes from understanding first the whole as a series of modules, then zooming in to think of each module individually. John Gall wrote in his eponymous law that:

A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system.

Complex systems can be designed, but to do so you must first sketch the outline. Only then can you start filling in the detail.

Similarly, to evolve and improve a complex system you must keep the overall system in mind at all times. We already know the alternatives don’t work: tacking on new ideas piecemeal, resisting the need to grow the product, allowing many competing approaches to co-exist. We need a technique for holding both the micro and the macro in our tiny human skulls at the same time. Christopher Alexander, who wrote the book on designing with systems, wrote that:

Nowadays, the process of growth and development almost never seems to manage to create this subtle balance between the importance of the individual parts, and the coherence of the environment as a whole. One or the other always dominates.

Growing a product is an eternal balancing act. Applying a Design Systems approach to every level of your product – not just the UI – will help you to maintain control over that balance and prevent any one force from dominating too much.

Intercom world tour 2017 banner ad