Tom Genoni / Design Technologist
June 7, 2020

Design System Principles

Here’s what I’ve learned.
White Sands National Monument

The following list of principles and action items emerged while working on Thumbprint, from it’s kickoff in late 2017 into the mature, multi-platform design system it is today.

General

Design Systems is a business

You’re shipping a product to users and supporting it on many fronts with planning, communication, documentation, diplomacy, roadmaps, promotion, maintenance, adoption, and measuring value. Making all this happen requires a dedicated team with diverse skills working in unison to bring your product to customers. Design systems often flame out by failing to appreciate the complexity and full-time attention that’s needed. This ain’t a side project.

📌

Use designer and developer surveys early to uncover areas of high friction for early planning and again later to gauge satisfaction levels. The feedback helps plan your roadmap and establishes your willingness to listen.

Simplify

It’s been said that “complexity is the enemy of execution” and that is certainly applicable here. Increasing options in a design system exponentially increases permutations, assets, development times, maintenance costs, and the likelihood of bugs. Start with as few options as possible, until it hurts. It’s much easier to expand them later than to remove ones already released.

📌

Do you need 27 colors? 7 types of buttons? 4 font weights? If so, do your designers and developers have easy access to usage rules for all this? Probably not. With Thumbprint we started by cutting our options to an absolute minimum and slowly expanded over time.

Designers & developers must work in tandem

Like styles guides, design systems are often mistakenly thought of as the domain of Design. But code is not a by-product. The process of creating components should be a feedback loop between designer and developer, moving as a unit, with each inspiring adjustments. This promotes a shared language, better understanding of each side’s concerns, and helps ensure teams have their tools available at the same time.

📌

Encourage designers and developers to do API reviews early and often. This will flesh out edge cases and result in more thoughtful component than the waterfall process could produce.

Don’t build everything at once

It’s tempting to want to clean house and redesign everything. But proceeding in deliberate phases will result in a healthier system long-term, for example, creating those early components will generate learnings to guide future decisions. It will also validate your process: the nuts of bolts of how components get made, who should be involved in that process, and how you socialize your efforts externally. Building a successful design system is a long and windy marathon, not a sprint.

📌

Start with elements having the broadest scope—icons, color, type—to sharpen your process and get high visibility wins. Start global, then local.

Don’t build too soon

Another pitfall is the risk you’ll build components you don’t actually need. This leads to unused design and code assets and needless complexity. Be sure you have enough existing use cases before committing to build. Your goal is deliver tools that match your teams needs, not to a Bootstrap-style library of components they might use in the future.

📌

It’s common in user flows to have a progress bar component. But does your system need it? If you build it now are you confident it will meet the needs of future implementations? Resist the desire to deliver components for the sake of “completeness.”

Don’t build too many options

Avoiding building too soon also applies to the components themselves. Their options and variations should map to actual use cases, not ones you think may be helpful in the future.

📌

If your button component supports icons on the left should it also support them on the right? Unless there’s reason don’t add the option.

Ship good, not great

On the other hand, you don’t want to delay releasing components and documentation until all the evidence is in. If you want your design system to gain traction sometimes you have make do with limited data. You simply can’t wait for perfection.

📌

The early development of Thumbprint was also the early development of a new brand for Thumbprint. We knew some of our components wouldn’t solve every use case. But we accepted this fact and made space to revisit them later on.

Remove friction, add friction (“Pit of Success”)

Among the goals of your system is to speed the process of building products. This means designers and developers should have quick access to the building blocks they need. It also means it should be harder to break out of the system by introducing entirely new elements or customizing existing ones. By making it “easy to do the right things and annoying (but not impossible) to do the wrong things,” we create what has been called a Pit of Success.

📌

Your button has blue and red background options. Can a developer enable a purple background? The ease (or lack thereof) of modifying a component should be a core philosophy of your design system that’s reflected in your design assets, code assets, and documentation.

Avoid being cops

It’s understandable that designers and developers may initially view a design system as a threat to their autonomy. To dispel this notion, communicate regularly that a primary function of a design systems is to watch for emerging trends and, where appropriate, elevate them into the system, and not there to create road blocks.

📌

Hold presentations for existing employees and when onboarding new ones to make this point clear.

Encourage external help

Some number of designers and developers will have an interest in contributing to the design system. Identify and recruit them as resources to help test ideas, make small updates, or even build new components. This demystifies the process and can convert them as advocates for the system.

📌

Detail how people can contribute. For designers this can mean helping with audits or feedback on UI, for developers a list of smaller tasks that make “good first projects” along with a checklist for building new components from scratch. Just make sure they have the time so work doesn’t stall.

Allow for variation

Reusing existing assets should always be the first consideration. But acknowledging the necessity of, and making space for, one-off experimentation is essential. When a developer receives a design that doesn't map to existing components they should feel empowered to first find out why. Sometimes the design diversion is unintentional, in others it’s desired. Providing a safe way to reconcile those questions unblocks teams and alerts us to consider if it should be part of the system.

📌

Set up a process for resolving questions. There will be a lot of them, sometimes with no obvious answer. Be ready for judgement calls. At Thumbtack we had a dedicated Slack channel To address uncertainties and it was a source of pride that we responded as quickly as possible.

Create a shared language

When building for one platform it’s relatively easy for designers and developers to talk about components using the same words. A “dropdown” as a design asset can be called a “dropdown” in a code component. But what is a “dropdown” on Android? What are the conventions for common interactions and do they change from platform to platform? Try to maintain consistency but accept that you may have to rename components down the road.

📌

Modals are tricky. On the web these are readily understood. But on native there’s a wide variety of them built into the platforms. There are no easy answers here—naming is indeed hard.

Over communicate

Because design systems are a relatively new concept it’s common for people to have misconceptions. Since you’ll be interacting with a wide variety of teams with varying degrees of design system fluency—designers, developers, writers, illustrators, project managers—you can ease their concerns by being transparent and continually sharing your work.

📌

Present at company meetings. Hold working sessions. Send out a email summary of your progress to your company. At Thumbtack we included shipped work, updates to ongoing projects, and thanks to external contributors.

Technical

Don’t be too DRY

The concept of DRY in software development, which means “don’t repeat yourself,” is a long-standing principle that encourages a “single...representation within a system.” Though generally good advice, if followed blindly it can lead to unnecessary abstractions, all for the sake of avoiding duplication. Consider whether a reduction in a number of lines of code helps readability and maintenance.

📌

For our Atomic library we intentionally didn’t use Sass loops. This meant the source code was as close as possible to its final CSS, allowing anyone to understand it right away.

Limit technical complexity

Like any significant software project, the code that houses your components and documentation will likely become complex. You’ll be doing yourself and your coworkers a favor but avoiding over-optimizing for certain use cases as they are likely to change.

📌

When we were converting Thumbprint’s design tokens to support multiple platforms we initially built thorny transformations. But we found that since these were rarely changed they would be far easier to maintain and parse if we simply added them manually.

Build & document as one process

A common problem with any documentation is content that’s out of date. Let’s say a developer makes a change to source code but neglects to update the wiki. Mismatches and mistakes like this can undermine trust or worse, things can break. When deciding on your technical infrastructure try to link those environments as closely as possible.

📌

At Thumbtack, the easiest (and really only) way to develop components was to render them on their corresponding documentation page. We used Gatsby with mdx for this. By combing them this way most problems could be caught during development. And our review process helped us maintain our documentation’s “single voice.”

Update & migration ownership

As your design system releases new features those changes need make their way into the products. But who is on the hook for that if the duties of the Design System team ends with publishing? Introducing large changes is scary so don’t let ownership be ambiguous. Establish a process to prevent products from getting multiple releases behind.

📌

We decided that the Design Systems team would handle any updates and migrations on the Web. For iOS and Android we identified engineers who had the context to merge in updates for their respective platforms.

Resources