Our great sponsors
-
twin.macro
🦹♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components, solid-styled-components, stitches and goober) at build time.
-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
-
WorkOS
The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.
There are many opinions on how to deal with such cases. Some recommend using the @apply directive for your components’ base styles. Others argue that you should already consider all the possible variants of your component and use JavaScript logic to apply proper classes based e.g. on the component’s props.
One of the more promising alternatives is twin.macro - a Babel macro that processes Tailwind classes to generate JS objects understandable by various CSS-in-JS libraries. The developer experience (DX) of using it is amazing as you not only get all of Tailwind’s features without much change to your code, but you also get much more flexibility - all that on top of the traditional benefits of CSS-in-JS. Here’s an example code:
While not too long, css`@apply is a lot to repeat for every class you want to “compile”. That’s why using Vite and some Rollup plugins (Vite uses Rollup under the hood) I was able to shorten it into this:
One of the more promising alternatives is twin.macro - a Babel macro that processes Tailwind classes to generate JS objects understandable by various CSS-in-JS libraries. The developer experience (DX) of using it is amazing as you not only get all of Tailwind’s features without much change to your code, but you also get much more flexibility - all that on top of the traditional benefits of CSS-in-JS. Here’s an example code:
Vanilla-extract allows you to utilize TypeScript as your CSS preprocessor, just like Sass. On top of that, it comes with Sprinkles - an atomic CSS framework that allows you to reproduce Tailwind’s utility classes.
Now, I’d like to mention one more Tailwind alternative that might be worth your attention - especially in regards to class composition - UnoCSS.
While not too long, css`@apply is a lot to repeat for every class you want to “compile”. That’s why using Vite and some Rollup plugins (Vite uses Rollup under the hood) I was able to shorten it into this:
After exploring all the above alternatives (and more), I’ve decided to implement my own, custom solution. For that, I’ve turned to Linaria - a true zero-runtime CSS-in-JS library.
The above config is what I used to get the shorthand and Liniaria working in Vite. To give you an overview of how it works - the twis first replaced with css\@apply and then the css template literal tag is auto-imported where necessary. I’ve only used this setup with Vite and Astro (Vite-based) so I don’t know how hard it’d be to get it working in other bundlers (though pure Rollup should work as well).