We need to have a chat? I think we should refactor

Jon Atkins
8 min readNov 15, 2023

It can be a tough conversation to have but reworking your design system can be what’s best for everyone.

Facing up

Its a familiar experience that lots of us have shared — migrations to merging, refreshes and refactors. First, it was Photoshop to Sketch, then Sketch to Figma (for the most part) and now, if you are a Figma user, it's improving the usability of your component libraries firstly with Auto Layout and now with updates to the Properties panel for closer design/code parity.

When I first joined Productboard I was curious to discover the current state of the libraries. Firstly in Figma, although Component Properties would not be available for another couple of months, Auto Layout had been since the end of 2020. However because our design system had been created 2 years prior, even this had not been incorporated into the components. As you can imagine, we had thousands of variants without Auto Layout that would need to be managed individually 😱 This was overwhelming and enough to raise the anxiety levels of many, let alone my own OCD jitters.

Limited props = 100s of unnecessary variants

We needed to this get under control. How can we expect designers to trust and use our components correctly if even we can not trust or understand them? And it wasn’t just our Core component library; libraries such as Iconography, Illustration and Brand were in a similar condition.

And what about in React?

It was déjà vu for the codebase. Our engineering team was aware of that our React repo had multiple instances of the same component, but used in various parts of the product. This was mainly due to contributions from engineers who needed to move at pace after the rapid growth of the product during COVID. And why did they contribute in this way? A big part of it was because designers were creating similar components or did not know what was correct, hence all these other iterations. As our ultimate source of truth, we needed to do some thorough housekeeping here by merging multiple instances of the same component, doing health checks on what we then had, and finally deprecating a lot of legacy code not necessary.

Having too much makes it hard for discoverability and to support

Process of refactoring

Having the Component Properties update made the decision to refactor even more of a no-brainer. During the last 2 months of 2022, I began to plan how best to approach this task. I wanted to gather more information from the design team first to find out the major concerns with the libraries and more importantly what to tackle first. We can make assumptions about which components should be reworked and released first, but are these actually that vital to the usability of the product for customers? A primary Button for example may be the most widely used, but is it more important than say a form element or a menu that is more complex?

After a designer survey and general audit of components collected, it was decided that our more detailed component patterns were in more need of rescuing. This began in Q1 2023 as I re-crafted the Card, Modal and Menu components.

Introducing new properties

The audit provided me with most instances of individual components used across the product, and just how much variety and discrepancy we had. By combining all the similarities in each I was then able to create a master foundational component for each of these larger patterns, for all subsequent variants to be created from.

Unifying the core parts of a larger pattern for a consistent outcome

Because there are hundreds of unique Modals, for example, I used the Component Properties to toggle various attributes and then applied boolean and text properties where appropriate. Another big part of the refactor was including workable slots to nest other components from the library. We did already have a legacy version of slots used in the core library, but this had become unusable as Auto Layout had not been added to all other components, meaning the resizing wouldn’t work in our new larger patterns.

Tease me

Making these changes is all well and good — it improves many facets of the component health after all and trims down the volume of variants to support — but I needed to make sure that the process we were following was understood by designers as they are our customers. If the adoption rate was to increase to the levels hoped for, I wanted to provide explorations of how components were being crafted and then follow-up demonstrations on how to use them.

Clear guidance will increase curiosity, improving adoption

Quick teaser videos are a great way to share what was being created and how. Not only does this give designers an opportunity to provide feedback on these developments, but it gives them a good insight into system thinking and how I approach creating a component that can have multiple usages in many, many ways. Up-skilling where you can!

Component demonstrations have an impact when it comes to their usage. Designers can have the component in their designs, but what’s the point when it is not being used as intended? For elements like a Button or Avatar, there isn’t much to misinterpret, but for a Menu in Productboard’s application, there is, so helpful guidance and video tutorials benefit the whole team, saving time in support requests.

Providing a greater level of detail

Once a component was refactored, typically we have;

  • Reduced the number of component variants exponentially
  • Applied the improved Figma functionality
  • Addressed any accessibility concerns
  • Tokenised correctly

but in addition to this is information about discoverability. Because we had a 2-year legacy of component contributions to libraries, we had accumulated many types of similar components and it was confusing to know which ones were correct.

Provide as much useful detail as possible for components

We needed to archive all these in Figma and merge their usages in code with our refactored component variants. This as you can imagine is quite time-consuming when we are dealing with many usages across different domains. As part of the update, components now received the correct configuration details for better discovery and links out to Storybook and our Nucleus documentation (More on our documentation for another article).

Announcements

We now have the component ready in design and fully tested in code, along with the relevant documentation on how to use it properly. Announcing a new component would be relatively straightforward but because we were replacing old with new, I needed to provide a softer landing for designers to experiment with these updates and replace any old instances in current designs.

*It’s worth mentioning we did not request designers swap every instance of a component in legacy designs, only current flows and screens that were deemed necessary to change.

Release plan

To keep track of what status each component was in and what we had finalised for each, a release list was created in Notion and embedded in our docs site for visibility. Plans can change depending on the business needs so we needed to be reactive to this and plan accordingly.

An announcement message explaining the updates and how to provide feedback

Tiering structure

Although the process of creating a component in our design system is consistent, (naming conventions, styling consistencies) the complexity of them varies considerably. A Button has even more usages arguably than a Modal, but has far fewer props to configure and limited customisation. Swapping a Button like-for-like should therefore be an easy process for designers, whereas a Modal requires more time for discoverability and understanding.

We gave a 4-week maximum limit for changes to be implemented in designs

Placing each component into a three-tier level release system gave the appropriate timeframe between announcement and deprecation for designers to make their amends. However, once a deprecation date had arrived, the old component was placed in an archive library that was still accessible should additional time be needed. During this timeframe window, I encouraged more feedback on the design, code and documentation contribution so the Nucleus team could amend before the final feedback loop closed.

Results

Looking at the analytical data we have seen an increase of core components from 31 to 42 (+35%) which seems like we are adding even more to support. But in fact, we were either taking these away from domains as they were being used in multiple parts of the product and we could now maintain them correctly, or there was a need for a new component addition to the library such as Date Picker or Pagination that wasn’t supported previously.

The biggest wins for us were the decrease of variants supported in Figma, down from 3192 to 879 (-72%), and the amount of code deprecation from the React repo. With all this removal of legacy design & code, our parity between both has increased to over 84% (from the time of writing this) This is what really matters as both design and engineering can be confident when working with our components, reinforcing React as our source of truth.

Survey and key takeaways

Each quarter we provide product teams with a design system survey, based on our performance over the last 3 months. Sentiment questions on satisfaction and usability and open-ended questions on challenges and improvements are asked to gather insights that help us understand the pros and cons we are currently working with

Asking specific questions helps gain a more honest answer. Further explanation can be asked later

From these results, we are able to provide some key takeaways for the teams so they know exactly what the Nucleus team is going to take action on. Examples of these were further explanations of slot usage, complexities with the UI selection framework and library housekeeping improvements. For visibility, all this data is collated into a quarterly newsletter I add to our docs site, with further information on component usage, what’s on the roadmap and feedback summarisation (helpfully summarised by ChatGPT).

Our lessons for the Nucleus team

Refactoring will feel (and probably rightly so) a daunting task, especially if you are working with an established component library. You can make this smoother however by being transparent about the job at hand and how long it may take. There is no perfect way of doing it, but making a solid plan of attack will help guide your team on its progress, providing a process to follow.

Giving your users visibility on this process is vital. It is one of the biggest things I have learnt whilst at Productboard — demonstrate, explain and teach its changes, usage and benefits to the product and therefore your customers.

I was lucky to have a team that had bought into the process and what it meant for the design system. Not all teams will so try to be calm and pragmatic when it comes to questions and back, it will almost always be coming from a good place 😃

Huge thanks to Luděk Vepřek, Roman Fausek, Igor Kulka and Aliaksandr Drankou for all your amazing work in achieving these huge improvements👏

--

--