Work

Portfolio

Contact

Evolving our design system

Using code-based design to help incrementally evolve our design systems.

The Challenge

When I joined Hasura as Design Director, I faced a challenging landscape.
Our design system was burdened with technical debt, and two previous attempts at revamping it had fallen short.

It was clear we needed a fresh approach.

Hasura's design system was at a crossroads. We couldn't afford another failed attempt.

So, what did we do?
We got smart. We got strategic. And we got our hands dirty with code.

Our Approach: Small Steps, Big Impact

I knew from experience that sweeping changes often lead to resistance and failure.

Instead, we opted for an incremental approach. Here's how we did it:

  1. Piggyback on existing projects: We leveraged ongoing initiatives, like our Tailwind implementation sprint, to introduce improvements.
  2. Meet the challenge head-on: We worked directly with the development team, illustrating solutions through code.
  3. Embrace code-based design: This approach helped us move fast and communicate ideas effectively.

We also made sure to show value for each of the places where we worked on applying updates to the system.

Initial design system: Based on the original designs with minor touch ups that were implemented when moving to Tailwind in production.
Future-facing system: Which includes a few more difficult design changes (for instance, the font). Some areas would need to be attacked as we addressed technical debt, but we wanted to keep a guide of mirrored components so we could pick those off when possible.

Tools of the Trade

Our secret weapons? Tailwind CSS and AlpineJS.

Why these?

Tailwind's CDN allowed us to craft components quickly, without any build step.
AlpineJS handled interactions smoothly.

Together, they kept our design velocity high - barely slowing down our process to produce code-based artifacts.

What about Figma? Sketch?

We still used these internally, had lightweight systems built around them as well.
The main meat-and-potatoes of our work came from being able to meet our development team where they lived in code though.

Storybook: Syncing our Design with Development

Storybook became our go-to source for the source-of-truth for our components.
And the nice thing - if our team contributed changes to the components, it allowed the team to see changes across the app in real-time.

Tailwind's "flat" class system made these contributions more manageable, reducing cascading effects that plagued our previous SASS-based system.

Anything outside of Storybook (production) - we kept our own code-based style guide of assets and examples which we kept in-sync with Storybook's classes and styles.

After: You can see one of the shifts between our system before and after here. The above is with our incrementally enhanced design system where we have implemented overall styling shifts, but also major changes to the page layout and structuring.
Before: This is the layout we started with before updating to the new design system.

The Results: V2 and Beyond

Throughout Hasura V2's development, we successfully evolved our components multiple times.

We maintained a set of coded components, collaborating with developers to transform them into proper React components for Storybook.

When it came time for Hasura V3, we were ready.
We kept the familiar "feel" of the application but elevated it to new levels of polish and professionalism.

Using the learnings from our V2 systems we were able to build out a design system experience in Hasura V3 which was a large refactor for the codebase of our platform.

Room for Improvement: Closing the Loop

No process is perfect. Our main challenge?
Syncing changes from development back to design.

We experimented with UXPin as a potential solution.
While promising, it had some limitations. I believe there was still room for improvement for us here, to get this motion down.

A presentation about our design process and design system.

Key Takeaways

  • Start small: Incremental changes are more likely to succeed than sweeping overhauls.
  • Collaborate: Work closely with your development team.
  • Code is key: Use code-based design to communicate ideas effectively.
  • Leverage existing tools: Tailwind, AlpineJS, and Storybook can be powerful allies.
  • Keep evolving: A design system is never "done" - it should grow with your product.

Index