Skip to content

Instantly share code, notes, and snippets.

@Hugos68
Last active July 7, 2025 16:15
Show Gist options
  • Select an option

  • Save Hugos68/8a5e2ee2f53522a350ac70ae20c2dcfc to your computer and use it in GitHub Desktop.

Select an option

Save Hugos68/8a5e2ee2f53522a350ac70ae20c2dcfc to your computer and use it in GitHub Desktop.
Comparison of `tailwind-merge` vs `base:` variant

tailwind-merge vs base:

tailwind-merge

What is it?

tailwind-merge is a package that merges a string of tailwind utilities and merges them from left to right in specificity. This means that bg-red-500 bg-blue-500 would produce bg-blue-500. This works effectively when users want to override the classes by providing their own. This does have a runtime cost, which means everytime a user applies a class themselves tailwind-merge will have to figure out wether or not it should be applied based on the already applied classes.

Bundle Size

tailwind-merge is 7.40 KB Minified + GZipped.

base:

What is it?

base: is a way of specifiying styles with a lower specificity than "normal" styles using a combination of CSS Layering and Tailwind's new @custom-variant rule. This was made possible by the recent Tailwind V4 update which allows you to create custom variants.

This is what the base: utility looks like:

@custom-variant base {
	@layer base {
		@slot;
	}
}

It enables to write Tailwind classes like base:bg-red-500.

Let's say we have the following classes: bg-red-500 bg-blue-500, will it be red or blue?

Because the order tailwind compiles classes in is not reliable, either red or blue being the one that is finally applied by the browser, hence tailwinds warning.

image

This is ofcourse not something we as library authors want. If we provide a red background, and the user wants a blue background, the user's choice should always override ours.

Now let's use the previously mentioned base: utility and apply it like so: base:bg-red-500 bg-blue-500. This is what the new compiled output looks like:

image

Notice how the bg-red-500 is now wrapped in @layer base meaning it has a lower specificity and we can predict with confidence that the bg-blue-500 will be applied. This is exactly the behaviour we're after.

Bundle Size

Now let's introduce some styles that utilize the new base: variant. Here is a table of components and the bundle size in tailwind they cause:

Component Bundle Size Playground
Accordion 0.21 KB https://play.tailwindcss.com/ubpY3LSOuq
AppBar 0.24 KB https://play.tailwindcss.com/sXKUXWlyrh
FileUpload 0.27 KB https://play.tailwindcss.com/vw51cbLKFB

Out of this table we can conclude that on average a component might introduce around 0.25 KB worth of CSS, worth noting is that if a user consumes a component twice, the styling will only be included once, because Tailwind only compiles those styles once and if they're duplicate they'll be reused. So this means even if we were to have 30 components and someone would use every component in their app (which is extremely unlikely) we would only ship 7.5 KB. Which is very acceptable without any runtime cost.

Conclusion

Because tailwind-merge adds ~7 KB regardless of how much we use it and components only gradually increase bundle size by small amounts I would strongly lean towards using the base: approach. It also saves a dependency which is good for many reasons.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment