Skip to content

Feature Request: no-unregistered-classes #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
donaldpipowitch opened this issue Apr 17, 2025 · 10 comments · May be fixed by #89
Open

Feature Request: no-unregistered-classes #86

donaldpipowitch opened this issue Apr 17, 2025 · 10 comments · May be fixed by #89
Labels
feature request New feature or request

Comments

@donaldpipowitch
Copy link

Hi!

Would it be possible to check for unused classes in a new linter rule? E.g. if I use something like --color-*: initial; and define my own color tokens that the linter errors on usages like bg-sky-600 or text-gray-950.

I imagine it looks for classes that follow the known utility patterns like text-*, bg-*, etc. and if * is a literal it checks if there is registered token for it. This isn't just useful for people who change tokens, but can also catch typos like bg-syk-600.

@schoero
Copy link
Owner

schoero commented Apr 17, 2025

So it would be more like a "no-invalid-classes" or "no-unregistered-classes" rule if I understand it correctly.

We already load the tailwind context for the "sort-classes" rule and the tailwind context knows all registered classes, so it should be possible to just ask tailwind if the class is valid, at least in theory.

@schoero schoero added the feature request New feature or request label Apr 17, 2025
@donaldpipowitch
Copy link
Author

donaldpipowitch commented Apr 18, 2025

"no-unregistered-classes" would be a great name for that!

Could something like py-2.2 also be covered? Afaik only .5 is allowed.

@schoero
Copy link
Owner

schoero commented Apr 24, 2025

I did some testing and the rule is pretty simple to implement. We can basically just ask tailwind what the css for a given class will be, and if it returns null, we know the class is not registered in tailwindcss. I still need to test some things and add an option to whitelist classes, but so far it looks really good.

Dynamic values only work for .25, .5 and .75. See tailwindlabs/tailwindcss#15702 (comment). With the current approach, these are already covered and values like py-2.2 will correctly report an error.

@schoero schoero changed the title Feature Request: no-unused-classes Feature Request: no-unregistered-classes Apr 24, 2025
@donaldpipowitch
Copy link
Author

This sounds amazing. I hope I can get you into our open source sponsoring round that we have at our company at the end of every year 🤩

@schoero
Copy link
Owner

schoero commented Apr 29, 2025

This might harder than I initially thought. The problem is that some valid tailwindcss classes like group or peer won't directly produce a css output and are therefore not detectable with this approach. I'm not sure yet how I can work around this without hardcoding some exceptions, which I definitely like to avoid.

I got normal classes working for tailwindcss v3 and v4 though.

You can beta test the other functionality by installing eslint-plugin-readable-tailwind@no-unregistered-classes if you like.

The documentation for the new rule is here

You can add group* and peer* classes to the ignore list to work around the issue for now.

@schoero schoero linked a pull request Apr 29, 2025 that will close this issue
@donaldpipowitch
Copy link
Author

You can beta test the other functionality by installing eslint-plugin-readable-tailwind@no-unregistered-classes if you like.

Wow, this seems to work great. We just started migrating from styled-components to Tailwind in a big project and this already catches a couple of dead/wrong classes. Kudos!

@schoero
Copy link
Owner

schoero commented Apr 30, 2025

Thank you for the feedback. I enabled the rule in some projects of mine for testing and it revealed some minor bugs for me too 😄. I can really see the usefulness of this rule.

If the group and peer classes are the only ones that don't produce an output I will just add them as exceptions but I'm a bit worried that there may be other ones and this becomes a nightmare to maintain.

So if you find any other false positives, please report them back.

@donaldpipowitch
Copy link
Author

So far I haven't seen false positives. Thanks!

@schoero
Copy link
Owner

schoero commented May 6, 2025

I have published a new version on the no-unregistered-classes tag, which includes a few fixes and now ignores the group and peerclasses by default.
I have also tested it with some larger repositories and couldn't find any false positives either. So the new rule is now ready in my opinion.

That said, I’m starting to think this rule doesn’t quite align with the original purpose of this ESLint plugin. The original idea was basically just the multiline rule to improve readability.

At the time, I used it alongside eslint-plugin-tailwindcss, which worked really well. Over time, I ran into problems with some of its rules, so I started to reimplement them in this plugin, but they always fit the "readability improvement" narrative and I could even improve some of the functionality.

This new rule can't really provide an autofix, which in my opinion is the biggest break with the original intention.

On the other hand, the approach I used in this rule also opens up great new possibilities for other rules. For example, I could add a no-conflicting-classes rule to warn about overriding classes like flex and block, which both set the display css property.

Long story short: I think it might be time to give the plugin a more general name and restructure it a bit.

@donaldpipowitch
Copy link
Author

Thank for being so open about this thought process. 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants