Ask
27
@ripped_it_out ·

We ripped Tailwind out and put it back six months later

Five devs, a mid sized product, roughly 200 components. The argument for removing it was one I still think was reasonable: nobody could read the markup, review diffs were unreadable, and two people flatly refused to work in it.

So we spent about seven weeks moving to CSS modules with a token layer. It went fine. The markup got readable. Reviews got better.

Then over the next few months the thing we had actually removed became obvious. Nobody deleted any CSS. Ever. The stylesheet grew every sprint because deleting a rule meant proving no other component used it, and nobody has time to prove that, so every rule stayed forever. Six months in we had more dead CSS than we had ever had classes.

We went back. Not because the readability complaint was wrong, it was not, but because we traded a problem people complain about for a problem nobody notices until it is enormous.

13 answers Share
Report

Answering anonymously, a moderator will review it first.

  • @design_system_of_1 · 2w ago · 2 replies

    Different angle. Neither of these is the problem you have. With five devs and nobody owning design you will get an inconsistent product either way, because the constraint is that nobody is deciding what a button looks like.

    We had the same churn and what fixed it was 30 tokens and a rule that colours and spacing come from tokens only. After that the class-versus-module argument got boring, which is what you want from it.

    17
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report
    • @tokens_not_classes · 2w ago

      Agreed. The framework argument is usually a proxy for "we have no design authority" and it cannot be won on those terms.

      1
      Share
      Reply

      Answering anonymously, a moderator will review it first.

      Report
  • @junior_last_year · 2w ago · 2 replies

    Seven weeks. Seven whole weeks. I need to know if anyone stopped to ask what that was in salary.

    20
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report
    • @ripped_it_out · 2w ago

      We did, afterwards, which is the wrong order. It was not a good number.

      1
      Share
      Reply

      Answering anonymously, a moderator will review it first.

      Report
  • @greppable · 2w ago · 4 replies

    The dead CSS thing is the whole argument and it almost never comes up, because it is invisible on any given day. Nobody opens a PR that says "this stylesheet is now 40kb of rules for components that no longer exist".

    Deletion safety is the actual feature. If the styles live in the markup, deleting the component deletes the styles, and that happens automatically because it is the same delete.

    28
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report
    • @css_modules_guy · 2w ago · 3 replies

      This is true and also solvable with tooling. Unused class detection is not exotic. We run it in CI and it fails the build.

      16
      Share
      Reply

      Answering anonymously, a moderator will review it first.

      Report
      • @greppable · 2w ago

        It is solvable, yes. The question is whether it stays solved after the person who set it up leaves. Everything that depends on a CI step somebody has to care about eventually gets a skip flag on it.

        12
        Share
        Reply

        Answering anonymously, a moderator will review it first.

        Report
      • @ripped_it_out · 2w ago

        We tried exactly this and it was defeated within a month by dynamic class names. Which is on us, but it is also what real code looks like.

        9
        Share
        Reply

        Answering anonymously, a moderator will review it first.

        Report
  • @five_devs · 2w ago · 3 replies

    The part I want to poke at is the two people who refused. Did that resolve, or did you just impose it on them the second time round?

    Asking because we are in a version of this argument now and the technical case is not really the blocker.

    22
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report
    • @ripped_it_out · 2w ago · 2 replies

      One of them left, unrelated. The other one is now fine with it and I think the honest reason is that we agreed a hard rule: anything over about a dozen classes gets extracted into a component, no discussion. Most of what people hate is the 40 class div, and that is a code review problem rather than a framework problem.

      19
      Share
      Reply

      Answering anonymously, a moderator will review it first.

      Report
      • @five_devs · 2w ago

        That is a genuinely useful answer, thank you. The rule is the part I was missing.

        1
        Share
        Reply

        Answering anonymously, a moderator will review it first.

        Report
  • @css_modules_guy · 2w ago

    For balance, since I am apparently the modules defender here. It is completely fine at this size, and the dead CSS problem is real but it is a discipline problem rather than an inevitability. Plenty of large codebases manage it.

    I would not do a seven week migration in either direction though. That is the actual lesson.

    1
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report
  • @legacy_owner · 2w ago

    Inherited a codebase that did this migration and stopped halfway. Both systems, live, four years. Please finish whatever you start.

    1
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report