
Hacker News · Mar 2, 2026 · Collected from RSS
Article URL: https://dev.to/wintercounter/boss-css-i-created-another-css-in-js-lib-and-here-is-why-23kc Comments URL: https://news.ycombinator.com/item?id=47223115 Points: 6 # Comments: 0
Boss-CSS is a polymorphic "CSS-in-JS" library supporting multiple different ways of applying CSS to your codebase, with or without runtime. Before I get into the details there are a few things I want to clarify. I'm not a content creator or writer, and I don't want to be. For this reason, this will be one single, detailed, long ass post. I'll try to explain and justify the choices I made inspired by my past experiences. It'll also serve as some sort of initial documentation. In case you want to read about the library itself and skip its history, jump here: Boss CSS History I'm coding mostly for web for 22 years now, and for 17 professionally. I've used several different ways to do CSS, using all kinds of frameworks, methodologies, different styling solutions, compilers and architectures. We always change for the better, trying to overcome the problems our previous solution suffered from. But this doesn't mean the new solution performs better in all areas, always leaving a gap behind. My first stop was using raw CSS. To solve organization issues, I started to split files into multiple chunks. To simplify selector usage, I've started to use LESS and SASS with support for nesting. To solve issues with naming and avoid selector collision, I was using methodologies like Atomic CSS and BEM. To simplify usage in the codebase and enable tree-shaking, I started to use CSS Modules. To improve DX, I started to use CSS-in-JS based solutions. To solve runtime performance issues, I started to use build-time static extraction. I started to use Tailwind, because it's lightweight and framework agnostic. All the solutions are coming with their own strengths and flaws, which would deserve their own articles. Around 8 years ago, I chose Grommet as the UI layer for a project. I immediately fell in love with their Box component, but I still ended up writing custom style objects for specific needs. A few years later, on another project, I ended up creating my own Box component. At the end it got quite complex and still, it didn't give me full CSS support, which again required me to write custom style objects and custom class names in CSS files. This was the time when CCSS and YouEye were born. It fundamentally changed how I wrote and used CSS. I'm still using them in production today, but (as it should) they started to reveal their own weaknesses over time. My relationship with Tailwind The last couple of years it became unavoidable to work with Tailwind on a project. I'm using it both in personal and professional projects. It's a classic love-hate relationship. I always loved the idea of utility classes and Atomic CSS. In fact, I've created my first utility class based CSS framework on top of SASS 11 years ago. It was generating utility classes based on configuration, then it was purging the final CSS based on usage. The final results were actually pretty close to Tailwind's AOT compiler. However, I have some problems using Tailwind: I always end up in situations where I have to keep maintaining a separate styling solution for custom needs. Tailwind is only a subset of CSS and it won't cover every area. The naming of selectors: I wouldn't be able to count on my 2 hands how many times I've Googled the term tailwind line-height, because of course, it's leading and I keep forgetting that. What's font-size in CSS, it's text-[size] in Tailwind. These minor differences are driving me crazy, and in some cases it's seriously interrupting my flow. Dynamic cases: whether Tailwind or CSS Modules, I always disliked merging class names using 3rd-party utilities, and by hand using conditions. States and pseudo elements: I hate using hover 5 times just to style my hover state. Breakpoints: I always hated mobile-first approaches, especially nowadays when it doesn't really make sense anymore. Please note that at the time of writing this, we only had Tailwind v2 available. It came a long way since then, solving many problems, especially around custom CSS. I understand those who are in favor of Tailwind over native CSS. It actually solves a lot of quirks and issues coming with native CSS. I believe it's a much better choice for those who started web development in the last couple of years or have a more backend-heavy background and feel uncomfortable writing CSS directly. However, I spent a lot of years learning, understanding and overcoming these problems. In most cases, I simply want to write CSS, and Tailwind just doesn't give me that. Today I actually never intended to write another CSS-in-JS library. But over the years I had so many thoughts about what I'd do differently, how I'd solve certain problems. Sometimes I had sleepless nights thinking about styling in different ways. Over time, these thoughts piled up and I've started to connect the dots in my mind. Last year, during such a night, I've decided to get up and test a few things in an online playground. It was the moment when I decided to start this new project, because I felt like I could offer something new. The biggest question for me: which solution made me the happiest, the most productive, and had the best possible balance in terms of both DX and UX? For me it was prop-based CSS-in-JS with static and dynamic extraction. Since working remotely I've joined several short-term projects either as a developer or consultant. I've seen dozens of cases where projects had their own Box component, each of them suffering from different flaws. This was also a fueling factor, because I know it could be better, I did use better in the past. Boss was born When I first started to work on this new library, my goal was to create a solution that's tooling independent. YouEye and many existing tools are mostly relying on custom Babel plugins by parsing and modifying AST at build time. I moved away from Babel years ago due to performance reasons, first to ESBuild then to SWC. I wanted a way that works regardless of the stack a project is using. Tailwind introduced such a way: parse on your own. Initially, I simply wanted to have prop-based CSS-in-JS that's extracted as Atomic CSS, while having a lightweight runtime that doesn't emit or manipulate stylesheets. I also wanted to make sure that it's fairly easy to extend its functionality, which led me to an event-based solution for its overall architecture. Soon I realized that this deep control enables me to add support for different syntaxes and extraction strategies, so users can decide which combination suits their project best. This is the reason for the name Boss, it lets you be in control. I spent a lot of my free time working on the library. Unfortunately, I don't really have much time next to my family and work, which led to very slow progress. At the beginning of 2024 I also had some personal issues, which forced me to pause every personal project. This slow progress definitely caused some fragmentation in my code. However, I spent so much time working on this and I truly believe it offers something new, I simply don't want it to go to waste. For the above reasons I decided to bring the project into shape for an early Alpha release. I did, it was 90% ready. However after 3 months of sleepless nights and grinding next to work and the fam, I hit a rough burnout phase. Only some minor bugfixes, documentation, website, playground and such were left. I spent so much time away from the project that I ended giving it up. Last year I slowly moved over to vibe-coding. Today, I mostly just review and instruct the agent's work. I decided to "revive" the project in the middle of boredom. This time with AI only, taking care of all the missing parts. Well, from this point I quickly got into the rabbit hole, asking the AI to add features I previously planned to implement in a future version, features I didn't even want to implement. It only took ~4 weeks of some free time to finish all this. Not the best quality of results, but it works enough. My hope is that it'll gain some traction in the community, which would force me to find a way to work on it more seriously. I hope to get some help to shape its rough edges, and help to build reliable documentation. In case those things don't happen, I still wanted to put it out there and hopefully inspire fellow developers with some ideas my solution brings to the table. Honestly, I'm not even sure if the lib has relevance nowadays in this AI era. Boss CSS When building Boss, I tried to bring the best parts of different styling solutions I used over the years. While that is subjective, I believe I achieved that for the most part. It's just CSS I often see libraries and frameworks coming with custom props, custom namings for some cases, like the p and m prop only for margin and padding, but nothing else, or consolidating font-* and text-* properties under a single prefix. These add extra learning curves, and can disrupt the flow of those coming with a heavy native CSS background. Parity with CSS naming and syntax was one of the most important goals for me. I wanted to be able to write CSS as it is as much as possible, without having to translate it in my head to some custom syntax. Class name based styling is basically almost inline styles by look. If you know CSS, you know 98% of Boss. Multiple syntax support I'm going to showcase all the different syntaxes supported out of the box. Why support multiple syntax? Because it lets you mix-n-match according to your own preferences, and your own specific needs/use cases. Prop based styling <$$ color="red"> Enter fullscreen mode Exit fullscreen mode Prop-based styling is the default for me for a long time now. I simply love it more than anything else. It comes with great flexibility, handles dynamic cases very well, is highly customizable for different design system needs, and can be perfectly typed. Read more in the Docs: JSX usage. Class name based styling <div className="color:red"> Enter fullscreen mode Exit fullscreen mode Using class names is really convenient, but when i