Can’t stop employees from accessing sensitive systems from untrusted / personal devices?

How We Cut UI Development Time in Half with Figma and Token Studio

Alan-Thomas.jpg

Alan Thomas

Follow Smallstep

We’re Smallstep, a comprehensive device identity solution for companies who want to lock down access to sensitive and critical infrastructure like Wi-Fi, VPN, ZTNA, and SaaS apps, to only company-owned devices. If this sounds like what your team needs, you should talk to us or try what we have to offer for free.

Over the past 5 years, our small and steadily growing team has tackled some of the toughest challenges in the PKI and cryptography ecosystem. We began as a purely open-source company with tools like step-ca and step-cli but have since achieved product-market fit for an enterprise product and are now focused on scaling. Optimizing workflows for efficiency and stability became essential as we grew, starting with UI development. Here’s to sharing our process in the hopes that it helps another small team like ours.

A - Z of our UI Development process, involving Figma + Token Studio + Style Dictionary + Tailwind + Radix UI + Storybook

We started off our initial UI development setup with Material UI. This helped us rapidly develop our initial product and achieve some level of design consistency.

However, as we progressed, two limitations became glaringly apparent: Developers have to manually translate specs into code, often relying on guesswork that can lead to design drift.

We realized that to build at scale, we had to move beyond based design systems focused solely on achieving design consistency. We needed to evolve to a workflow-oriented approach —one that automates updates, bridges communication gaps between designers and developers, and eliminates the manual grunt work of styling for developers to boost productivity and development speed.

The solution we’ve settled on uses the Tokens Studio plugin, which transforms design tokens like colors, typography, and spacing from Figma into JSON files, syncing them to our GitHub UI Kit repository. Style Dictionary then transforms these JSON files into a custom Tailwind config which UI developers then use to style components.

There’s more to it, but you’d have to keep reading to find out.

This guide is for teams like ours—small but ambitious—looking to automate design workflows, cut down UI development time, and eliminate the headaches of manual styling.

Assembling Our UI Toolkit

Building a token-based design system requires finding the right tools for your company. Here’s what we use and why.

Figma + Token Studio

Token definitions in Figma

Figma is where all design tokens—colors, typography, spacing—are defined. When a token is added or updated, the Token Studio plugin kicks off a pull request in GitHub, updating JSON files in our UI kit repository.

design-tokens-github.png

Style Dictionary

The Style Dictionary API transforms JSON tokens into platform-specific style definitions (iOS, Android, CSS, JS, HTML), for consistent design across platforms without duplicating effort.

The Tokens Studio plugin exports design tokens (like colors, typography, and spacing) from Figma as JSON files into our UI kit repository on GitHub. Style Dictionary processes these JSON files to generate a custom Tailwind theme configuration, creating utility classes that align directly with our design tokens. This theme configuratoin is then published as part of our Step-UI npm package, which engineers can easily install and import into projects.

const theme = require('@smallstep-sdk/step-ui/theme')

When tokens are updated in Figma, these changes automatically propagate to every component, page, or project using the Step-UI package. Developers don’t need to manually adjust styles—changes are reflected as soon as the app or website is rebuilt. Moreover, developers work directly with mnemonic token names (like primary-color or heading-font) instead of raw CSS rules, significantly speeding up development and reducing the risk of errors.

Radix UI Primitives

Notion board showcasing how components designs are co-ordinated

Our frontend is React-based, and we use the Radix UI Primitives library as the foundation for building UI components. This library provides unstyled, accessible React components that we customize to fit our specific requirements.

By using these pre-built components, developers can focus on solving real engineering challenges and implementing business logic, rather than recreating UI boilerplate or managing accessibility for basic elements like forms.

Radix components are styled with Tailwind utility classes generated from our design tokens. These styled components are then published on Storybook and packaged into our Step-UI npm package, which developers can install and use across different projects. Each component is independently versioned, allowing us to add new elements without disrupting existing code, ensuring flexibility and scalability.

Storybook

Storybook acts as the single source of truth for our UI components. Each component is built as a “story,” allowing developers to preview and test it in isolation. This process simplifies refinement and fixes, preventing broader regressions while providing clear guidance on component usage and behavior in various scenarios.

Storybook component example synced with Figma for UI consistency

We integrate Figma in Storybook to display Figma designs alongside their corresponding component implementation in Storybook. This provides a feedback loop that enables designers and developers to collaboratively refine components, identify inconsistencies, and prevent design drift.

We also run visual regression tests on individual UI components (buttons, cards, modals, etc.) documented in Storybook using Chromatic to ensure that updates don’t unintentionally alter their appearance. As updates to components are pushed, Chromatic compares the new visual state of the components to a baseline and highlights any differences. This process gives designers a direct role in reviewing and approving visual updates, ensuring that the UI remains consistent with the design system or intended visual style.

Additionally, we’re experimenting with a Figma plugin that will pull Storybook data directly into Figma, so designers can review component implementations without leaving their design environment.

Getting Everyone on Board the Design System Train

Finding the right tools is only half the battle. Success depends on getting buy-in from key stakeholders — executives, product teams, engineers, and designers — each of whom has unique priorities. Tailoring the design system’s value to each of these groups is key. Here’s how we did it:

Winning Over the Executives

For executives, design systems can seem secondary to immediate business goals. Framing the initiative as an investment in speed and scalability helped us secure leadership support. By emphasizing that a strong design system reduces bottlenecks and accelerates development over the long term, we aligned the project with their big-picture vision.

For example, our CEO saw the design system as a way to strengthen brand identity across platforms. By showcasing how a unified design language could improve our product’s visual appeal and user experience, we gained full support and the resources we needed to implement the system effectively.

Convincing Product Managers

Product Managers often thrive on flexibility, so introducing a unified design system required a mindset shift. To help product managers see the value, we focused on the speed and efficiency of the model.

While a token-based design system might introduce constraints, these limitations ultimately lead to faster feature rollouts. Instead of designing every detail from scratch, product managers will gain a toolkit for quickly building and iterating on ideas. Once they saw how quickly we could iterate on new ideas without breaking existing UI, they were sold.

Aligning with Engineers

For engineers, the appeal of a design system lies in its ability to eliminate repetitive tasks. Standardised tokens and components meant less time spent writing custom CSS and more time spent solving real engineering challenges.

To ensure long-term success, we encouraged engineers to view the design system as an enabler of quality and scalability rather than a constraint. They’d get tokens that auto-update, and no longer have to pick between sixteen slightly different shades of blue. While there was an initial lift involved in updating legacy pages, the benefits of a unified system—faster development, fewer errors, and a cleaner codebase—quickly became evident.

Getting Designers Excited

For our design team, the token-based system offered confidence that their designs would be implemented as intended. With a centralized source of truth in Figma, designers could define tokens and components without worrying about inconsistencies creeping in during development.

While working within the guidelines of a design system might seem limiting at first, our team saw how it enabled a cohesive user experience and reduced the need for constant design oversight.

Laying the Groundwork for Success

Beyond getting the right tools and getting buy-in, implementing such a huge process shift requires setting expectations and laying down few ground rules to make it stick. Here's what we advise:

Follow a Flexible, Incremental Strategy

Transitioning to a new design system requires an incremental approach. When we began adapting our SaaS app to the new design system, we focused on high-impact areas first—like the device identity flow for enterprise Wi-Fi—while deprioritizing less critical areas, such as the Certificate Manager flow. By starting small, we kept the process manageable and avoided overwhelming the team.

Our strategy was simple: “update as you go.” Whenever a feature required a design change, we took the opportunity to refresh those elements according to the new token-based design system. This incremental approach allowed us to make progress without disrupting workflows or creating a backlog of updates.

We also made sure that every new page adhered to the updated system, so that anything newly built was automatically aligned with our latest standards. This helped us keep momentum without needing to pause active development for a large-scale overhaul.

Tolerate Temporary Inconsistencies

Let's be real: your app won't look perfectly consistent during this transition. Some pages will rock the new hotness while others look like they're from a different era. And you know what? That's fine.

Take our SSH configuration pages - they're still running the old design. We could have delayed shipping our new system until everything was perfect, but perfect is the enemy of deployed. Even Google took years to update some of their assets to their Material Design framework.

The key is knowing where to be inconsistent. New features? They get the new system. Critical user flows? Upgrade those first. That dusty admin page that three people use once a year? It can wait.

Make the Right Path the Easy Path

An effective design system doesn’t just guide developers toward the right choices—it also makes it difficult to fall back on outdated methods. By structuring our system to prioritize new components and phasing out legacy elements incrementally, we’ve minimized the temptation to revert to old habits.

For example, instead of developers digging through old CSS files to style new pages, they now use prebuilt components directly from the system. These components handle accessibility and design guidelines by default, ensuring that the final product meets both user and technical requirements.

Over time, this approach has made it nearly impossible to “do things the wrong way.” The token-based design system isn’t just a tool—it’s an integral part of how we build and scale our product.

Building for the Future

This wasn't just about making things pretty - it was about building a foundation that could scale. In summary, here’s what we achieved with our token based design system:

  1. Designers and Developers Work Better Together: No more translation errors between design and development. When designers define tokens in Figma, those exact values show up in the code. It's like having a universal translator for design decisions.
  2. Efficiency is Built In: Remember those days of manually updating styles across your app? Gone. Changes flow automatically from Figma through GitHub to your development environment. Designers can focus on creating a strong visual identity while developers build features without playing "spot the difference" with design specs.
  3. Accessibility is a Priority: By building on Radix, we got rock-solid accessibility for free. Every component meets standards out of the box, no extra work required.

The result? We ship UI changes faster (maybe not exactly 50% faster 😊), our design team and developers actually like working together, and our app gets more consistent every day. Oh, and if our designer asks for a new shade of blue? That'll take about 5 minutes now.