In 2016, Slack was two years old and already used by millions of people. Our codebase had grown rapidly, and like many companies that focused on product/market fit, our code was built in a way that favored time-to-market over maintainability, consistency, or reusability.
We never encountered a single breaking point in our user interface, but rather a slowly cascading series of inconsistencies, quirks, and discrepancies. Our internal product teams were growing to match the momentum of the business, and with that scale came drift in our component parts.
What does a button look like in Slack? How do you build it? What words do you put in it? It was up to individual teams to make these decisions.
A group of engineers, designers, and writers began to centralize these standards, documenting the bits and pieces, small and large, that make up Slack.
We named it Slack Kit.
It’s an evolving internal resource containing everything from typography to accessibility patterns. It helps us keep the product as consistent and accessible as possible, while speeding up design and engineering efforts. And with the release of our new client, it’s now used throughout Slack.
It’s a system that grew retrospectively, taking advantage of lessons learned from early feature implementations to inform the patterns we wanted to codify. This post is about how we built it.
In those early days, ownership of standards or best practices between design and engineering were often unclear or anecdotal. We didn’t even have a straight answer to a question as simple as, “What color should I use?”
The first cross-functional group began to clarify these standards by answering that question. Carving off little bits of our weeks, we pruned the set to just 16 colors, working together to ensure that the final set fulfilled the varied use cases throughout our products and — most importantly — met our criteria for accessibility. As we couldn’t feature-flag this change, we replaced every color variable inside Slack in one massive merge, then documented and shared the new library internally.
This first exercise in standardization created a space for those building the product to communicate with each other across teams and disciplines. Designers began to understand the ways in which variables can codify standards. Engineers learned the reasons designers need components to look and behave a particular way.
Starting from the ground-up forced us to focus on an area that solved a real problem for our team, rather than choosing something overly-broad.
A crucial turning point in Slack Kit’s success arrived when Slack’s Desktop Engineering team made the decision to modernize its codebase with React. While recognizing that most product engineers and designers would have to continue to focus on feature development, a few of us began to support the effort full-time.
We began codifying other foundations like typography, motion, and spacing, but ran into problems early on. Many of our existing components were built on top of a legacy code stack based on assumptions in our product that were no longer relevant (e.g., a member dropdown built for teams of 1,000 people would break down when trying to load data for a 100,000 person team).
We had to rebuild each of these components without slowing down Slack’s overall development progress. It was a bit like taking a car engine apart piece by piece, and cleaning, repairing, and replacing each part while it accelerated down the highway.
While doing this work, we could also reevaluate each of these component parts. Knowing that dropdowns would need to support future magnitudes of scale, we built support for asynchronous data fetching. We codified how the dropdown menu should behave, and ensured that it was fully accessible. Our first multi-select took almost two months to build, but subsequent feature implementations took just hours.
The scarcity of dedicated resources meant that the design system would rely on other engineering teams to help build the library’s components. The Slack Kit team focused on process, establishing clear guidelines for additions to the library. All Slack Kit components would be “carrier-grade”:
- Robust: Components should look great, representing the high standards we set for our product design.
- Accessible: Components should work for all of our users, regardless of how they navigate and interact with our software.
- Flexible: Components should support a variety of use cases within our product, while supporting future extensibility.
- Reliable: Components should be well-tested, dependable, and immediately responsive to user interaction.
While relying on contributors from other product teams within Slack to help build the library meant slower progress, it guaranteed that the system was serving the needs of its eventual consumers. We made ourselves readily available to Slack’s product development teams, connecting threads between parallel efforts. In a fast-growing organization, Slack Kit became a hub for discussion of the fundamentals of our interface. And with each new component, the value of the system grew as patterns were reinforced.
Requiring teams to proactively reach out to us in order to prepare for upcoming initiatives was not always an elegant or efficient process. At times, we’d build a component and then later refactor it as requirements became clearer. We remained humble and supportive, and discovered that a small team can have a tremendous impact with a culture built around process, communication, and collaboration.
It took a long time for Slack Kit to reach the point where it was useful for our various product teams. When we started the process and looked to other design systems for inspiration, they were intimidating in their completeness. But just one component, thoroughly documented, was immediately valuable, and created a virtuous cycle for the system.
Since then, we’ve built off that foundation. Our designers and frontend engineers have created over 40 components for Slack Kit, in use throughout the desktop client and our various web surface areas. We’re bringing this same process to Slack’s various mobile apps, codifying components and design principles for iOS and Android respectively.
Slack Kit helps us improve the overall customer experience, as we’re able to rapidly build new foundational features into Slack. We released Dark Mode for the Slack desktop client today, built with relatively low effort on top of the color system that Slack Kit established. In the coming weeks, we’ll share more about building Dark Mode and how Slack Kit helped make it possible.
A design system must adapt to the changing needs of the product. It must be opinionated, prescribing solutions that can scale for yet-unknown use cases. It has to document these solutions, and ensure that they’re useful for a variety of audiences. And most importantly, it must embrace the tension between infrastructure and invention, helping others to navigate that difficult middle.
If any of this sounds interesting to you, perhaps you’d like to work with us.