Gigahatch. Software. Simplified.

UnoCSS: A true TailwindCSS alternative

Pub­lished: November 27, 2022

There are already many alternatives to the popular CSS framework TailwindCSS, like WindiCSS, Twind or Tachyons. In this blog post, I would like to introduce you to another option. A relatively new library called UnoCSS. By the end of this post, I hope you will consider replacing TailwindCSS with UnoCSS in your next project.

What is UnoCSS?

UnoCSS describes itself as an Atomic CSS engine. Atomic CSS is a CSS architecture where each class just does a single thing. An example of an Atomic CSS class would be the classes you see in TailwindCSS. For example:

.bg-white {
	background-color: rgb(255 255 255);
}
.border {
	border-width: 1px;
}

If you have used Tailwind or something similar before, you probably already know how using classes like these is useful for styling your HTML quickly and in a maintainable way.

Compared to TailwindCSS, UnoCSS itself does not contain any classes like these. It is more like a meta framework that allows you to build Atomic CSS frameworks like TailwindCSS. For example, to implement the above bg-white class in UnoCSS, we could create the following config:

{
  rules: [
    ['bg-white', { "background-color": 'rgb(255 255 255)' }],
  ]
}

You can now do class="bg-white" in your code and UnoCSS will output the above bg-white class to your CSS.

Obviously, we wouldn’t want to do this for bg-white, bg-black, bg-red, etc., that would be very tedious. Luckily, UnoCSS also allows us to create dynamic rules. To implement this logic using a dynamic rule we could do the following:

{
  rules: [
    [/^bg-(.+)$/, match => ({ "background-color": match[1] })]
  ]
}

This only supports the named CSS colors, but as this is just Javascript code, we could theoretically expand this to also include a map between our custom colors and CSS color codes.

But all of this seems like a lot of work, just to reimplement something TailwindCSS already has. Luckily, we can just reuse someone else’s work. That is where UnoCSS’s presets come in. Presets are a bundle of rules and other config values that you can include in your own UnoCSS config. And luckily for us, someone already created a UnoCSS preset implementing all of the TailwindCSS functionality in UnoCSS. It is called @unocss/preset-wind and it is already included in the main unocss NPM package. We can use it in our config by importing

import { presetWind } from 'unocss';

and adding the following line to our config:

presets: [presetWind()],

Now we can use “nearly” all of the functionality of TailwindCSS and WindiCSS, because this preset is actually a combination of TailwindCSS and WindiCSS. It even implements the theme configuration from TailwindCSS (even if not quite completely yet).

UnoCSS also has other officially supported presets, like the @unocss/preset-uno one, that also includes classes from Bootstrap and Tachyons, or the @unocss/preset-attributify preset, that allows you to specify classes directly as attributes on the HTML elements. As you can see from this last example, presets can do a lot more than just add new atomic classes.

There are also lots of community-maintained presets implementing TailwindCSS plugins or other neat things. For a list of all the official and some of the community-maintained presets, visit https://github.com/unocss/unocss#presets.

Why UnoCSS instead of TailwindCSS?

You may be asking yourself, this sounds great, but TailwindCSS can already do all of this, so why should I switch to a different library?

As I see it, UnoCSS has two major advantages over TailwindCSS. First, performance. UnoCSS is a lot faster than TailwindCSS and WindiCSS, as you can see in the benchmark taken from the UnoCSS documentation below.

10/21/2021, 2:17:45 PM
1656 utilities | x50 runs

none                            8.75 ms /    0.00 ms 
unocss       v0.0.0            13.72 ms /    4.97 ms (x1.00)
windicss     v3.1.9           980.41 ms /  971.66 ms (x195.36)
tailwindcss  v3.0.0-alpha.1  1258.54 ms / 1249.79 ms (x251.28)

This is due to UnoCSS not parsing the files to an AST like TailwindCSS does. Because UnoCSS is implemented as a Vite plugin, it doesn’t have to spawn a separate file watcher for all your source files. Instead, it just transforms the files that Vite gives it.

Secondly, UnoCSS is a lot more flexible than TailwindCSS. Because it is an engine instead of a full, opinionated CSS framework, you can decide which features you want to use. Maybe you have to style lots of text in a certain project, so you could consider installing the @unocss/preset-tagify preset, allowing you to do things like:

<text-red> red text </text-red>
I'm feeling <i-line-md-emoji-grin /> today!

which compiles to:

<span class="text-red"> red text </span>
I'm feeling <span class="i-line-md-emoji-grin"></span> today!

This is just one of the possibilities UnoCSS enables and as the community grows and creates more presets, you will be able to use more features too.

Of course, UnoCSS is not perfect and has some downsides at the moment. The most glaring of which is the lacking documentation. Even just installing UnoCSS in your Sveltekit project is a bit difficult. That’s why we are posting an article about how to setup Sveltekit + UnoCSS soon.

It is very difficult to use UnoCSS without first having experience with TailwindCSS, because the documentation that does exist, expects you to already know certain concepts and conventions.

Also, even though UnoCSS supports nearly all TailwindCSS features, some crazy edge cases may not always work properly. And the theme configuration is not quite feature complete and it definitely has no documentation :D.

Lastly, the VSCode extension is not up to par with the one for TailwindCSS. The autocomplete doesn’t always work correctly and isn’t as good as TailwindCSS’s and it sometimes detects class names outside of your HTML.

Despite the issues, UnoCSS is a worthy alternative to TailwindCSS, especially if you care about the improved development experience that comes with better performance of the dev server or if you can use the added flexibility.

If after reading all of this you want to try it out for yourself, you can head over to the UnoCSS Github and download it now.