David Luhr, Lead Developer at Tailwind Labs, shares how the team created a Figma kit for Tailwind UI, a set of fully responsive components that helps designers and developers collaborate more efficiently. Here, he shares what he learned—from organizing the project, to getting customer feedback, to the small polish details that made all the difference. Today, a starter pack of the kit is live on the Figma Community.
Tailwind UI is a collection of thoughtfully crafted, fully responsive HTML components built with Tailwind CSS, a utility-first CSS framework.
Since Tailwind UI launched in early access in spring 2020, customers have asked almost daily if and when Figma files would be available. By the fall, demand from customers became overwhelming, and I set out to create the official Figma kit for Tailwind UI. With over 400 fully-responsive code components, Tailwind UI's surface area rivals most design systems, so I had quite the challenge ahead of me.
For much of the next few months, I'd be heads down in Figma, building (and even rebuilding) over 1,400 components and 10,000 distinct elements, all while keeping quality and usability top of mind. Here's what I learned.
Building a commercial design kit requires the utmost attention to detail. This is in contrast to working files for designing new products and features, which are often messy, temporary, unpredictable workspaces whose sole purpose is to unlock new ideas and solutions as efficiently as possible.
When the design files are the final product, decisions at every scale define the user experience—from layer names to component structure to page layout. To build the best Figma kit possible, we had to flip the typical workflow, and have the final code product inform the design files as a pixel-perfect standard to match. Maintaining high quality at every level of a design system was our north star.
Let's start with layers themselves. I established naming conventions and labeled everything accordingly, making sure I was staying consistent throughout. In Figma, consistent naming also allows for overrides to carry over when swapping instances or changing variants of a component. For example, a "button" component has a simple text layer named "Text." If I change my button to a larger size variant, the custom text I create carries over. With more complex components, this saves a lot of time for users, who might customize icons, headings, paragraphs, link text, and more, then decide to swap their component for a different variation.
Now, how to organize these layers? With the latest auto layout features, combined with layout grids and layout constraints, you can create layers that mimic HTML markup pretty well. While I'd love an option to stack Figma's layers bottom-to-top to further match the stacking context of the web, you can get a good approximation. This is worth it for a couple reasons: there's shared understanding between designers and developers around what's possible in terms of layout in the browser, and there's similar architecture for customers to navigate in both design and code versions.
This also reveals opportunities to document patterns that otherwise might go unnoticed. For example, many components in Tailwind UI have consistent responsive padding and a centered, max-width container. By creating design file layers that match what's needed in HTML markup, developers can see this consistency and create a dedicated container to handle these repeated layout rules.
With well-structured components, variants can vastly simplify design systems and make components much more adaptable.
Instead of manually maintaining and arranging a collection of 80 unique badge components, for example, I created a single Badge with convenient variants for type, size, theme, and some optional secondary elements. While it takes some upfront work to create these variants, it makes the final component much simpler and more adaptable for users. Customers can drop in a single badge and quickly adapt it to their needs with an intuitive set of options.
When creating variants, it’s important that the same properties a developer might provide with a code component exist on a component in Figma, using the same terminology. Again, consistent naming conventions and structure for variants provide a predictable experience for design kit users. When building Tailwind UI's Figma kit, I found that across hundreds of final components, I could use the same variant names for the vast majority: type, size, theme, position, breakpoint, and state.
Variants are essentially self-documenting. Anyone can look at a component, see the distinct variations and how they map to settings in the variants panel. And wow, do they keep the final component count slimmed down. When the Tailwind UI Figma kit was complete, we had 1,430 components, with an average of seven variants. Without variants, this would be more than 10,000 components. Since we wanted to focus the kit on the final components found on the website, variants helped us keep the component count down much closer to the 400 or so code components that customers will be using in their work.
If you're recreating existing components or UIs, I highly recommend using screenshot overlays to speed up and improve the accuracy of your work.
When I mentioned pixel-perfect earlier, I wasn't saying that lightly. As I built each component in Tailwind UI's Figma kit, I made heavy use of the Dev Tools' "Screenshot Node" feature to create images that I overlaid with 50% opacity on top of my designs in Figma. This helped me double check my work at every level, and even revealed a few inconsistencies in our code components that we later fixed. More on that feedback loop later.
Code components on the website are each displayed in a responsive preview that users can adjust to see how each component adapts across Tailwind CSS's defined breakpoints. This creates a sort of showroom—allowing users to see each component in context—which we wanted to recreate in the Figma kit.
To do this, I built every component at a mobile and desktop breakpoint, while making them as flexible as possible with auto layout and layout grids.
To further replicate the website's user experience, each page of the Figma kit matches a page on the website. Every page has a dedicated heading that links to the corresponding page on the website. A page contains only the final components, complete with example backgrounds to show the component in context with the intended viewport size. These example backgrounds are components themselves, and are kept tidy in a locked group layer at the very bottom of the layer list. This allows users to instantly select the components without the example backgrounds, so they can quickly copy/paste them for their own use.
When the design files are a product in their own right, these little details of polish and consistency in how you present components go a long way.
With only the final components on each page, where do all the granular, building-block components go? To keep the main pages clean and focused, I created a dedicated “Parts” page that's home to every component outside of the "showroom" pages. The Parts page can grow to be a behemoth, but it's easy to maintain with auto layout layers and dedicated headings that back link to the respective pages in the kit. The majority of the time, users will reach for a final component and never need to look at the Parts page, but those who want to dig deeper have a complete inventory of well-organized components they can peruse and adapt to their own use cases.
Beyond the more granular decisions of layers, components, and pages, we learned how to best sequence a project of this scale, when to rethink our approach, and how to engage customers along the way.
Here are our main takeaways:
This project was rooted in designing components from existing code, which provided an interesting feedback loop. Originally, every Tailwind UI component began life in Figma with initial designs. Then, those were developed into code components, which were recreated as design components in Figma. We found some inconsistencies and bugs in the code components while building the kit, which we were able to immediately improve on the website (isn't it amazing how much you notice when you study every single component, line by line?). As the project came to a close, we had more confidence than ever in both our design files and our code components.
So, design informs development, which informs design, which informs development further—polishing everything with each loop. And, on that note, I better get back to Figma to add the latest batch of new components.
Now, you can check out a starter pack of the Tailwind UI kit on the Figma Community.