Why I Built a Utility-First CSS Framework — and Eventually Moved On
In 2017, I built my own utility-first CSS framework. Not because it was trendy, and not because I wanted to launch “the next big thing”, but simply because I was tired of fighting CSS in real client work. The framework was called Abrusco, and for a long time it quietly did exactly what I needed it to do.
By coincidence, Abrusco’s first commit landed about two weeks before Tailwind’s. Same general idea, same direction, very different outcomes. This is not a regret story. It’s more a reflection on what I was trying to solve at the time, why it mattered to me, and why letting Abrusco go eventually felt like the right decision.
The Problem I Was Trying to Solve
Anyone who has worked with CSS long enough knows how this usually goes. A project starts clean, well-structured, and easy to reason about. There’s a style guide, a system, maybe even a sense of pride. Then reality arrives. Clients ask for small visual tweaks. Deadlines get tighter. Quick fixes sneak in. Over time, the neat architecture slowly turns into layers of overrides and exceptions that nobody loves, but everyone depends on.
Utility-first CSS felt like a more honest response to that reality than most architectural approaches I had tried before. It’s often far healthier to change mr-2 to mr-4 on a single element than to introduce another special-case selector that bends the cascade a little further out of shape. Around that time I came across Tachyons, Basscss, and a few talks exploring this idea, and it clicked hard enough that I wanted a solution I could fully shape around my own workflow.
So I built one.
What Abrusco Was (and Wasn’t)
Abrusco was never meant to be Tailwind before Tailwind. It was deliberately simpler and more pragmatic. I wanted a CSS-first tool, without a mandatory compiler or complex setup. One stylesheet you could drop into a project and start working immediately. Utility classes would handle most layout and spacing problems—roughly 80 to 90 percent of what I needed—while anything truly project-specific, like animations or complex visual effects, would still live in plain CSS.
Because there was no compilation step, I leaned heavily on CSS variables. Colors, spacing, scales—everything was designed to be adjustable at runtime. Some of the solutions were small but meaningful. One example I used a lot was padding that automatically compensated for border width, so adding a border wouldn’t subtly break visual rhythm. These details mattered to me because they made everyday work calmer and more predictable.
Abrusco wasn’t a theoretical exercise. I shipped real projects with it, and it served me well. Later on, I even released a small CLI setup using PostCSS plugins for imports, minification, and purging, but the core idea stayed the same: you could always just include the CSS file and get moving.
Letting It Go
At the same time, Tailwind was growing. It arrived with a very similar philosophy, but also with something I didn’t have: the time and focus to polish documentation, build momentum, and grow a large community around it. The underlying idea was strong, but Tailwind turned it into a platform. That kind of execution matters.
Watching Tailwind evolve never felt discouraging. If anything, it felt validating.
Eventually, the question became less about whether Abrusco could continue, and more about whether it should. Turning it into a fully polished, community-ready framework would have required a level of ongoing maintenance, documentation, and promotion that simply didn’t fit my priorities anymore. Meanwhile, Tailwind kept improving, and over time even adopted directions I personally liked more, especially as it moved closer to CSS again rather than further away from it.
At some point, pushing Abrusco forward would have been about competition for its own sake, not about solving my problems better. That was the moment I decided to move on and focus my energy elsewhere—on products, client work, and ideas that felt more aligned with where I wanted to go.
Looking Back
Abrusco didn’t become a global framework, and it never built a large community. But it shaped how I think about CSS, about tools, and about building things in general. It proved to me that I wasn’t just following trends, but independently working through the same problems others were beginning to articulate.
And honestly, that’s enough.
Abrusco still exists if you’re curious:
- GitHub: github.com/lemmon/abrusco
- Homepage: abrusco.com
Sometimes a tool doesn’t need to conquer the world to be meaningful. Sometimes it just needs to solve your problems at the right moment, help you grow, and then quietly step aside. Abrusco did exactly that for me.
- Tartare-Style Burger, Done the Hard Way (So It Stays Simple) Feb 15, 2026
- Why I Built a Utility-First CSS Framework — and Eventually Moved On Dec 19, 2025
- Blank Bookmarks Slate Sep 24, 2024
- JavaScript Search Query Snippet May 30, 2024
- Vercel Open Graph Card With No Framework Mar 13, 2024