My Last Component Library
As I built my own little blog and its sibling online course site, I started fresh with components and set myself a goal: Never again!
My journey hasn’t just got me geeking out about the visual side of web design; I’ve also become fascinated by its underlying structure. My brief three-year stint studying engineering clearly left a lasting impression!
I believe beautiful design is about more than the surface (as millions of Dribbble designs might have you believe). Good software feels good. And, just like kicking the floors in a new build can reassure you, a solid foundation encourages commitment.
Striking out on my own felt like the ground had been taken away.
CSS Trends
At my old company (for which I’m still so grateful), we took pride in building our own frameworks and CSS libraries. We dabbled in Bootstrap and Tailwind, but always came back to authored CSS.
They were generous enough to let me pursue that approach. We went through many trends: SMACSS, BEM, SCSS mixin libraries and namespacing everything. We kept moving forward as the technology progressed — which, in the dark IE6 years, wasn’t very fast.
To put it bluntly, I’ve lost count of how many times we rewrote the button component.
So here I am, once again promising myself: “This is the last time I write the CSS for a button component.”
This time, it’s a necessity, not a whim. Starting with a clean slate is as exciting as it is daunting, so here we go.
My latest last component library
What’s different this time? Before, accessibility was always part of the mix, even if it sometimes took a bit of a fight. This time, I call the shots, and accessibility is the baseline.
From the ground up, accessibility has a seat at the table — there’s a mad mix of metaphors… sorry. That means tap areas, contrast and clarity, as well as honouring user preferences.
As it turns out, putting these anywhere other than the foundations would have been a bad idea.
This time, it was also time to let go of Sass. You’ve been good to me, thank you, but you’re still just CSS — and Sass has a problem now. CSS has become so capable that, rather than bridging a gap, Sass is playing catch-up, reworking features that have become native to CSS. Functions are now in CSS itself; mixins are coming…
What’s more, this frees you to create the tooling you need to make life easier. More on that later.
Atomic design
I leaned fully into Brad Frost’s Atomic Design and Token System.
For those unfamiliar with atomic design, it organises components from fundamental, indivisible atoms to small structures (molecules), then on to larger “organisms”, like a page header.
A token system formed the core of theming: everything, from colour ramps to a button’s border radius, could be controlled there.
Name spacing works around an old problem solved by modern CSS techniques, like CSS Layers.
At my old workplace, we had many discussions about component namespaces: c- for components, l- for layouts and u- for utilities. This time, I chose… none. That’s right! Namespaces are gone. A button is “button”.
Ramps and scales
The token system brought colour ramps and type scales. Before, we tweaked them so often that the scales became obsolete. This time, the ramps and scales are foundational: if a font size or colour didn’t feel right, I adjusted the scales or ramps.
I also embraced new techniques. I mentioned accessibility as the baseline; there’s another Baseline. My rule was to use “Widely Available” techniques, and reserve “Newly Available” ones for progressive enhancement.
This means future versions of the library will both grow and shrink. As “Newly Available” becomes “Widely Available”, I can drop older techniques. Of course, that’s not something to do blindly. Understanding CSS, its quirks and how to use your judgement are still hugely important.
I’ll expand on some of these approaches in future articles.
New tools
I mentioned tooling. This is where the component library takes things to the next level. I needed two main things: a UI for tweaking tokens and a way to sync variables between CSS and Figma.
I started by syncing to Figma. Tokens are stored in a JSON file, and a script I built prepares files for Figma. It was so cool to see changes in the library appear in Figma designs with just a few clicks.
Then came the token UI. It meant I could stop digging around in JSON files and use an interface instead.
I built a colour ramp system and a type scale system, both of which run alongside AXE to check for potential accessibility violations. Colour is built on OKLCH, which offers a wider gamut and handles lightness more evenly than, say, HSL or sRGB, regardless of hue. A yellow-600, for instance, is visually the same lightness as blue-600.
I built a tool that lets you dial in what you need for your colour ramps.
The ramp system lets you adjust a lightness curve, choose how saturated you want your colours to be, or tweak each ramp individually.
The typography tool lets you choose scales and design fluid sizes that adjust to screen size. “Floor” and “ceiling” limits help prevent text from breaking at 200% zoom.
Typography is difficult to get right. But this has gotten me really close.
I won’t go into the other tools this interface provides; suffice it to say, it’s made theming a dream. Lighthouse loves me.
I have so much more to say about this.
AI sidenote
Now, did I use AI? Of course. This would have been impossible without it. But what’s my take? It’s a machine, like a calculator or a dishwasher. It does what a machine does. That’s all it is to me: it’s not a person. And people have used machines since forever, so it would be rude not to.
A source of truth
A new Figma file is like a new jotter. It starts off nice and neat with good intentions.
The last piece of the puzzle was finishing the work in Figma. In November 2026, there’s no point in letting code and Figma fall out of sync. I remember constantly having to rework the Figma file we called our “source of truth”.
“Hey, my developer friend, what you’ve done there looks a bit different from Figma.”
“There’s a Figma?”
You know how it goes. With the token designer, though, the source of truth moves between the two disciplines. It makes much more sense to check how things look on the web as early as possible, before moving on to code or Figma. Again, things have to “feel” right.
And with the Component Library for Figma built too, I hope this really is my last button.
Okay, I’m going to stop now. I’ll write more about what I’ve learnt from this project, and I’m looking forward to sharing it with the world soon.