Building an Enterprise Design System

Optimizing for designer-developer collaboration

Background

When I joined Ninja Van over a year ago, one of the products I was assigned to design for was our internal parcel management system called (rather simply) Operator. Operator is the digital backbone that powers nearly 15,000,000 deliveries we carry out every month, and has the honor of being the first ever “product” built in Ninja Van.

Over the years, it has seen an evolution from a simple web interface with a handful of pages to a full-fledged digital product that has dozens of full-time engineers working on it. It has seen two major rehauls, with a third coming up. Even the technology framework powering it has evolved over the years from AngularJS to React.

As all of this was built without a design system in place, you can imagine what it looks like today.

Pages from Operator

The Problem

As I took on the role of designer for this product, a couple of issues quickly presented themselves:

  1. Because there was no UI library, whenever I had to come up with a new feature for Operator, I had to prototype components from scratch

  2. Existing pages are wildly inconsistent and there are multiple UI variations even though similar functions were repeated across pages

  3. Every iteration required lots of communication with the developers to ensure that designs get built according to spec


It was by chance through working on a different product that I discovered Shopify’s Polaris design system. It was a revelation. All my problems would be solved by having a design system! But first, I needed to convince some people.

Getting Buy-In

The first was my product manager. While we have a great working relationship, there were definitely differences in our priorities. He wanted to get features shipped as quickly as possible, but here I was, wanting to slow down and spend time making sure all our buttons looked the same.

Being a firm believer of letting users speak for themselves, I conducted a few simple tests. For a new feature I was designing, I made a few different mockups – some with consistency in placement and usage of components, some without. The results spoke for themselves — in the consistent designs, users spent less time figuring out where the page elements were, and were faster in figuring out how to use the various functions without prior training.

Convincing the developers was considerably easier. Like designers, they understood the benefits a design system would bring to their workflow. The only things that stood in the way were time and a multitude of decisions to be made.

Choosing a library

As Operator was in the process of being migrated to ReactJS, we had to pick a compatible component library built on the same framework. On top of those components, we would then build our own customizations.

Various React Component Libraries

We picked Ant Design after some deliberation as their powerful ready-built tables worked really well for our enterprise use-cases. Because Operator has tables on almost every page, having ready-built tables will save our developers a lot of time.

Examples of Ant Design's Built-in Tables

Building the Design System

In order to even know what my design system has to accommodate, the first thing I needed to do was to carry out an audit of all the existing pages. From my experience with the existing pages, too much flexibility in a design system can easily spell disaster in implementation, especially over time. Hence, I needed to know exactly what functionality the design system needs to account for so that the design system can cover these use-cases without having to be too flexible.

Design Audit in Progress

The first thing I started off with was to determine a set of design principles for the design system. This was important because these principles would answer the design questions that might come up when building the system — for example, what kinds of typefaces to use, how much padding is sufficient etc.

I consulted our users, product managers, and stakeholders to determine what was most valuable to them. I asked them to tell me in 1-2 sentences what would make Operator a successful product. From their answers, I was able to come up with these design principles.

(The book Design Systems by Alla Kholmatova was also tremendously helpful in trying to articulate the principles and to make sure that they were well-considered and useful to future designers evolving the library.)

Next up was colors and typography. Because this formed the basis of the design system, I wanted the level of flexibility allowed to be relatively low – for text and colors, as many use cases as possible should be taken into account beforehand so that there will not be any necessary variation across pages.

In additional to a neutral scale for text elements and a primary and secondary color, we also needed a functional palette to signify special conditions, which was a crucial use case for Operator.

Taking inspiration from Brad Frost’s Atomic Design, I then moved on to build the ‘atoms’ of the design system. These include buttons, checkboxes, toggles, fields etc. In addition, I decided on what components to build first based on a selection of the most-used pages on Operator so that I would not be overwhelmed by questions about how extensive the library needed to be.

I then moved on to the ‘molecules’, which includes setting guidelines for margins and spacing between elements, as well as larger components that consist a variety of ‘atoms’ like cards and modals.

Building a Sketch symbol library

In making sure that other designers are able to easily adhere to the design system, I built a library of sketch symbols enabled by plugins that they would be able to easily re-use in different pages. This also helps me to be more productive when building new features or pages in the product moving forward, ensuring that I am able to quickly prototype using the symbol library.

Gif showing how easily a button can be customized
Sketch symbol library

Ensuring a Single Source of Truth

Prior to building this design system, one of the main problems we faced was that the design team and the engineering team had different libraries of their own, even though they both referenced the same style guide. Over time, the small inconsistencies evolved into larger differences, leading us to where we were.

In building this design system, we wanted to avoid the same mistakes. One of the tools we used was Storybooks (link). Storybooks basically pulls out the code from various pages representing the components, acting like a sandbox in which anyone (designers included) can interact and inspect these components.

This helped us implement a process in which the design team was able to audit and highlight inconsistencies in the way components have been designed compared to how they were built. While maintaining the Storybook does create some overhead for engineers, the pay-off is definitely worthwhile.

The Results

Old pages on left, new pages on right

Key Achievements

  • Coordinated with engineers to create a unified library (code+design) and how it should be documented across design & engineering

  • Ensured that the system was flexible enough and provided guidelines to ensure that other designers can use it

  • With the use of various sketch plugins, created a library that was easy to re-use with very little additional effort

Key Challenges

  • Determining the amount of flexibility required
    While the design system is meant to be an ever-evolving library, it needs to have enough rail guards in place to ensure that future iterations by different designers do not lead to inconsistencies with existing components

  • Coordination with engineers to ensure a single source of truth
    At Ninja Van, we have only ever had design style guides; a design system on the other hand, needs to be represented by code as well. It is important to convince engineers that the additional overhead of documenting their code somewhere available for the team to review is worthwhile in the long run.