Dan Dean / Project:

Splice Design System

In Systems > Tools I explored how systems make it possible to derive value from tools, and how tools alone rarely lead to an organization's success. The work I did on Splice's design system is a good example of this in practice.

Before my time at Splice there had been a few attempts at building a design system. In the last attempt styles had been audited and SCSS modules were created to encapsulate them. A backlog captured everything to be migrated. These styles were copied to a standalone repo and npm module to make them consumable by any application. There was even a sort of storybook-like preview site to show these styles decoupled from an application.

What Splice had at that point was a collection of tools, but nothing tying those tools to processes, nothing driving individual contributors to adopt them or participate in their development, nothing connecting their development to their visual origins within the design team. These things had the potential to help solve some software challenges associated with building user interfaces, but they did not add up to a system. What was lacking was a broader view of the challenge at hand, and without that broader view success was elusive.

Aside: I Wasn't Hired to Build a Design System

I was hired into Splice's Search & Recommendations team. I started on a Monday and the following Friday the team was dissolved as part of a broader engineering reorganization.

😬

My first project on my new team was to build the new "Pack Card" implementation, and the task was surprisingly difficult. CSS was everywhere: leaking out of global stylesheets associated with an embedded legacy AngularJS app, sprinkles of Bootstrap, a collection of SCSS selectors in a "splice-styles" directory, and in individual CSS files associated with specific Angular components.

Splice's current design system was motivated by the situation I found myself in. There was no obvious entrypoint into how to build Pack Cards in a coherent way. I could have just crammed some CSS together and picked up the next ticket - nobody would have batted an eye – but stapling yet more onto an incoherent system is something I have a hard time bringing myself to do.

I took this as an opportunity to not just solve the immediate need of shipping the "Pack Card" redesign, but to explore the problem space and prove out a solution to Splice's systemic challenges for designing and delivering user interfaces. The problem wasn't how to build the Pack Cards, it was to figure out how to make it less painful to build at Splice in general.

Design System Tunnel Vision

In many organizations the "design system" describes a set of artifacts which are owned by either of the Design or Engineering teams. The owner is primarily concerned with their own team's needs – other teams must extract what they can from that to inform their own work.

For instance, if the design system is wholly-owned by the Design Team, then the artifacts are often a set of PDFs (or PSDs, or Figmas) describing in great detail every aspect of how things should be implemented, be it brand colors, font families, font sizes, design patterns, or anything else all the way to conventions around language and tone.

In that context, the engineering team takes these specifications and builds implementations which reflect them. The code implementations may or may not encapsulate the design system in a set of tools to reduce work. The focus here is first and foremost on the specification, so let's call this approach the "Design Specification" approach to Design Systems.

On the other hand, if the design system is wholly-owned by the Engineering Team, then the artifacts are usually some sort of component library (maybe a some React or Swift components, maybe some CSS specified in BEM, etc). The focus is on engineering efficiency, and ensuring that engineers can implement designs consistently without having to constantly rebuild things, and without having to have designers watch over their every move. Let's call this approach the "Component Library" approach to Design Systems.

Both of these approaches provide value to an organization. They reduce variance, they limit duplicated effort, they improve communication across teams. They're also both incredibly limited: they reenforce Design and Engineering silos instead of fostering continuous dialog and collaboration; they speak to one team's needs at the expense of the other's. And on the negative side, they often work as leverage for telling the other team "no" without providing a way for that team to feed requirements into it.

Design System as Organizational Process

What if instead of describing a set of artifacts, we took "Design System" to mean the system by which design goes from concept to delivery, including a continuous feedback loop between Design and Engineering which facilitates product evolution? This changes everything about how both teams approach their work.

"Design System" is now a higher-level concept which encompasses all of the artifacts previously identified, but also describes how those artifacts relate to each other, each individual's role in driving their evolution across each layer, and how to affect change on those artifacts in a coherent and collaborative way.

This approach to a Design System is more comprehensive and spans more of the organization, and consists of multiple complimentary "layers".

Design System Layers

Layer One: The Pattern Library

The Pattern Library is a set of technology-agnostic Design and Functional Specifications which describe repeatable patterns (colors, fonts, sizes, buttons, forms, cards, etc) spanning the "atomic design" nomenclature. Primarily owned by the Design Team.

The pattern library will describe design patterns broadly, going into detail about how they are applied differently based on context. A carousel design pattern might specify the overall look and feel, along with the kind of content it can contain, how "previous" and "next" behaviors work, how it behaves in mouse vs touch contexts, and how it may change based on context, such as if it's on web, iOS, or Android.

The pattern library usually exists "pre-implementation" in something like Notion and/or Figma, where general discussion and exploration of the pattern can take place, and where individuals can be directed for their own education about what currently exists and why.

That "why" is critical because the pattern library helps us constrain the number of design patterns, and this improves communication with the customer. For example, if we have a Video Card design pattern, that card is the design language within our product which our customers see over and over again, and for which they will gain an understanding and set of expectations. If any product team needs to show a video they will be able to rely on those expectations for interacting with the customer. If they go their own way and make arbitrary decisions about how to display a video, then they're going to have a much harder time communicating with the customer. This is why constraining design patterns is good.

The pattern library helps us inspect the natural inclination to assume our use cases are unique. When new use cases arise they can be held up against the pattern library either be thoughtfully rolled into existing design patterns, or become new design patterns if they truly are unique.

Layer Two: Component Libraries

Component Libraries are concrete implementations of the Pattern Library in specific technologies (React, Angular, Flutter, Swift, Webflow, etc). Primarily owned by Engineering Teams. There should be nothing in a component library which doesn't also exist in the pattern library.

Component libraries are the bridge between the pattern library and an organization's various products. They contain functional implementations of design patterns which can be assembled to realize product features efficiently. When an engineer is tasked with building a feature, this should be their first stop, and when they come up against the edges of a particular library's capabilities, they will contribute back to it to more fully realize a component as a fully fleshed-out design pattern.

Component libraries are the layer at which engineers participate in the design system feedback loop to bring engineering knowledge back to the pattern library. Engineers will have deep experience in their particular stack, and they can use that to evolve a design pattern to be more fit for purpose, rather than bolted on. For example, the engineer may raise up requirements around assistive devices (ie, alt text, focus, etc), or contextual UI expectations associated with a particular device (ie, native iOS select interfaces, etc).

This is also an opportunity to push back on design pattern creep. If a feature's design specification looks a whole lot like another component in function, if not form, an engineer should be encouraged to bring that back to the pattern library rather than just implementing anything they're handed. This brings us to...

Layer Three: The Feedback Loop

Pattern and Component Libraries are both points within the design → engineering → design feedback loop. The Feedback Loop is what makes it possible to gain the most value out of a Design System because it allows designers and engineers to participate in the evolution and refinement of the artifacts coming out of the system.

In a well-functioning feedback loop designers and engineers are learning from each other, gaining empathy for each other's concerns, and related work outside of their local silos. The same is true between engineers across stacks as well – if iOS and Web engineers are both contributing feedback to the same design patterns they will have more opportunities to understand how those design patterns apply across different technology contexts.

One mechanism for facilitating the feedback loop is to have a regular (optional) cross-disciplinary Design System Office Hours where engineers and designers can bring questions, solicit input, and help others.

Layer Four: Accountability

Individuals will always prioritize what they are accountable for – this is often the thing which kills an organization's design system aspirations.

Design systems produce capabilities, not features. They slow down the delivery of the current feature (the team has to first identify and extract the capabilities), but they make all subsequent features vastly easier to deliver because the team now has a set of capabilities to draw from. If a team is only ever accountable for the delivery of the current feature, then the incentives just do not exist to build a design system. This is where the organization's leadership comes in.

Design and Engineering management must build participation in, and contribution to, the Design System into their evaluation frameworks. Not just "what features did you deliver", but "what capabilities". During the review cycle designers and engineers should be able to point to an array of others who have been able to deliver on top of their own work within the design system, and they should be celebrated for it.

From Proof of Concept Component Library to Organizational Directive

Getting from that first desire to make it easier to build things like Pack Cards, to transforming the way Splice approached the idea of a design system, and software delivery in general, was not a straight line. I honestly kind of fumbled into it with a lot of luck and good timing.

I produced that first component library proof of concept in collaboration with my peers. It worked great, but it was still just a singular tool, not a system. A few months later the engineering reorganization continued as a new CTO and Director of Engineering were brought on. Their primary focus was on making it possible for Splice to more predictably deliver software, and unlike many new leaders, they opened the table to any and all ideas for how to achieve these goals. This ended up being the opportunity we needed.

Design System RFC

An RFC was written up, senior leadership approved, and individual contributors were largely on board. Myself and then Design Director Jay Schaul were tasked with leading the initiative and helping people from each of our respective domains begin the process of starting to think and work in this way.

Three key choices ended up being effective leverage for getting the organizational process up and running, acting as an onramp for individuals from across the organization into this new process:

  1. On the design side, Jay created the working framework for the Pattern Library which consisted of an organized area of Figma, where existing work was brought into the pattern library structure, and a "proposal" area of Notion, where design patterns could be proposed using a starter template with standard areas to be fleshed out by contributors.
  2. On the engineering side, I created an Angular library where components and reusable CSS could live and be consumable from any of our web-based applications, ported our nascent SCSS modules into it, moved our Pack Cards into it, and stood up an instance of Storybook to make it possible to view everything in the component library and to operate as a component development environment decoupled from the applications.
  3. Jay and I started optional bi-weekly design system check-in meetings (aka, design system office hours).

Progress, Setbacks, and Bus Factors

Much progress has been made: we're able to build features faster and more consistently, to reuse code across client applications, and to release those features across clients without significant additional effort.

But we're far from done. We have yet to fold in our mobile team, and as of late it feels like our feedback loop is fraying at the edges. The work now is to operate on the system to address its shortcomings. Much like we evolve design patterns, we will evolve our Design System to account for new organizational requirements without having to start from scratch.

Someone once said to me that for a process or system be sustainable it must not depend on the presence of any particular individual. No employee is forever. We need to continue to build the organizational muscle memory to make our Design System process more resilient to staffing changes, and less reliant on specific individuals reiterating and reenforcing the underlying principles. If we can achieve this, then Splice's Design System will truly be a success.

Acknowledgements

Splice's design system is built from the contributions and work of many others across the organization. Notable contributors are Jay Schaul, Kim Goulbourne, Leigh Caplan, Andrew Cornett, Lara Warman, Florida Elago, Jessica Eldredge, Matt Claypotch, Sue Lockwood, and more.