MathiasGilson/Tailwind-Styled-Component

What's the difference between this and Twin.macro? What are the pros and cons of using each?

lumenwrites opened this issue ยท 8 comments

This library looks amazing, and seems like it does exactly what I need - enabling me to use Tailwind with React without turning my JSX into an unreadable mess.

Since I'm new to Tailwind, I'm still trying to find the best way to use it. Can you help me figure out the difference between this library and Twin.macro? What are the pros and cons of using each?

Would like to know more about this too. My initial reaction is that Twin.Macro is a more complete package (supports more and more complex use cases), but also has more boilerplate when writing code. Then again, I am no expert.

Honnestly the main difference was the syntax of Twin.Macro that was different before and the inheritance that seems to be supported now. I didn't test the last version yet but Twin.Macro seems better maintained too...

@MathiasGilson I would like to add another question. ๐Ÿค”

I have been using tailwind-styled-components on Next 12 with SWR compiler without custom .babelrc without issue; However, I assume you did not make a port to work with Rust. So how is this working? ๐Ÿ˜…

It runs at runtime which is less than ideal

twin.macro doesn't allow you to use variables well AFAIK. This package is very simple, doesn't run in the browser and is much lighter.

Yes, I am also having lots of trouble using twin.macro, it took me a week to migrate and I hit all kinds of roadblocks, which were not very well documented regarding setup and being forced to use babel (which is another problem due to storybook and jest) instead of swc.

Sure, performance gains may be nice, if most things are done at compile-time, but I found myself not knowing how to do some things with ease. I had to do some exploration on the web, on their examples, and ask some questions on their discussions panel - since the front page of the README was not enough to get me going on simple use cases. I've managed to migrate without bugs in the end.

So from my experience, if you prefer readability and maintainability rather than performance, I would definitely stick with tailwind-styled-components. It can easily be interpolated with strings and used with regular tailwindcss. Everything works out of the box. You can still go with regular className="things", whereas twin.macro forces you into the ecosystem all the way by using tw for static props and css for dynamic ones, with hashmap hacks to deal with interpolation.

If you prefer the power of compile-time className object generation for better performance, integrated into a "bigger" ecosystem I'd suggest going with twin.macro instead (perhaps integration will be easier when they provide swc configurations for next.js). However, the learning curve is bigger than the one provided by this package.

@FranciscoKloganB @MathiasGilson Hello! Can you explain again what twin.macro does at compile time and why it has better performance?
Also as I understand twin.macro generates absolutely new classes like (Button-sc-16bkhqv-0 cWlMCy), it just takes rules from tailwind's classes. So It generates much more css code. tailwind-styled-components uses classes generated by tailwind so it's much more effective for big projects.

What I can tell is tailwind-styled-components is just an easy (and different) way to write your tailwind classes, but with the same results as you would expect when writing them in the className tag.

Example:

tailwind-styled-components tailwindcss
Shot 2023-04-10 at 17 38 57@2x Shot 2023-04-10 at 17 39 35@2x

Output HTML in both cases:

<section class="flex flex-col px-14 md:px-0 ..." ... />

Whilst with twin.macro you (a) need a styled-components library (styled-components, emotion, stitches) and (b) it transforms your tailwind classes into actual CSS with new CSS classes.

So, for the example above:

import tw from 'twin.macro';

export const Section = tw.section`
  flex
  flex-col
  px-14
  tablet-md:px-0
`;

CSS output

.Section-abc-123 {
  display: flex;
  flex-direction: column;
  padding-left: 14px;
  padding-right: 14px;
}

@media (min-width: 768px) {
  .Section-abc-123 {
    padding-left: 0;
    padding-right: 0;
  }
}

HTML output

<section class="Section-abc-123" ... />

Disclaimer: the properties above will depend on your tailwind configuration