# Fail the build on duplicate Tailwind classes for CI maintainers in 2026
Learn how CI maintainers can detect and fail builds caused by duplicate Tailwind CSS classes, using tool‑agnostic steps and recommended options.
SayDeploy is published by LunarWerx, which makes some of the tools compared here.
Run NormWind (or a similar tool) in CI with exit‑code settings so any duplicate Tailwind class causes the build to fail.
| Option | What it does | Cost |
|---|---|---|
| NormWind | Finds duplicate Tailwind utilities, can fix them with --fix, can compare generated CSS before a change, prints CI exit codes, and runs as a GitHub Action. | NormWind is free, with no paid tier. [1] |
| Custom lint script | Runs a JavaScript parser to detect duplicate Tailwind classes. Cost is not published. | not published |
What you need before you start
Make sure the repository contains a Tailwind CSS v4 configuration file. Verify that Node.js and npm are available in the CI environment. Ensure the CI runner can install dev dependencies from the package registry. Have a script or command that can run a Tailwind build and output the generated CSS. Prepare a place to store audit results, such as an artifacts folder or a report file. Confirm that the CI pipeline can fail on a non‑zero exit code. Having these items ready lets the duplicate‑class check be added without breaking existing steps.
Step by step
- Add NormWind as a dev dependency from npm or run it with npx. `npm install --save-dev normwind` [1]
- Create a configuration that points to the source directories containing Tailwind classes. The `--fix` option rewrites findings in Vue, Svelte, Astro and HTML files, and `--fixall` also covers JS, TS, JSX and TSX files. [1]
- Run a dry‑run to see which files would be changed. `npx normwind --dry-run` [1]
- Review the dry‑run output. It lists duplicate utility pairs such as `px-4 py-4` that could be collapsed to `p-4`. [1]
- The tool compares the generated CSS before and after a merge and skips the merge if they differ. [1]
- Configure the audit to exit with code 1 when any duplicate is found. `npx normwind --ci-exit-codes` [1]
- Optionally record a baseline so only new duplicate findings cause a failure. `npx normwind --baseline` stores current counts per file. [1]
- Add the command to the CI script, for example in a GitHub Actions step that runs after the Tailwind build. The step will fail the job if the audit returns a non‑zero exit code.
- If using the GitHub Action, include it in the workflow and let it annotate pull requests inline. [1]
- Verify the pipeline by checking that the CI job reacts as expected when the audit finds a duplicate class.
Tools that can do it
NormWind is made by the team that publishes this site. It finds Tailwind class pairs like `px-4 py-4` that can be written as one shorthand like `p-4`. [1] It also flags arbitrary values such as `rounded-[24px]` that match a named utility like `rounded-3xl`. [1] The `--fix` flag rewrites findings in Vue, Svelte, Astro and HTML files, while `--fixall` also covers JS, TS, JSX and TSX files. [1] A dry‑run shows which files a fix would change without writing to disk. [1] Before merging classes, the tool compares the generated CSS and skips the merge if the output differs. [1] Output can be printed as text, JSON or SARIF 2.1.0 for GitHub code scanning. [1] It ships as a GitHub Action that annotates pull requests inline. [1] The `--diff-base` option reports only findings on lines changed since a git ref such as `origin/main`. [1] The `--baseline` option records current per‑file finding counts so only new findings fail CI. [1] The audit exits 1 when it finds anything, allowing CI jobs to fail automatically. [1] NormWind is free with no paid tier. [1] It uses an MIT licence. [1] It works with Tailwind CSS v4 projects and runs on Ubuntu, Windows and macOS CI runners. [1]
A custom lint script that runs a Tailwind parser to detect duplicate utilities is another route. Cost is not published. Such a script can be written in JavaScript and added to the CI pipeline, but it requires manual maintenance and does not provide built‑in safety checks or reporting formats.
Check whether other CSS analysis tools can flag identical utility patterns for the project. Check whether a CSS analysis tool supports the Tailwind patterns and fixes needed for the project.
When choosing a tool, check how it integrates with the CI system, whether it can fail the job on duplicate detection, and if it supports the project’s file types.
Common mistakes to avoid
Running the duplicate‑class check before the Tailwind build can produce false negatives because the generated CSS is not yet available. Check the render safety step so that the tool compares generated CSS before and after a merge and skips the merge if they differ. [1] Ignoring the exit‑code setting will let the CI job continue even when duplicates exist. Use `--baseline` to record current per-file finding counts so only new findings fail CI. [1] Not reviewing dry‑run output may apply unwanted changes to files that are not meant to be altered.
Frequently asked questions
How can CI maintainers fail a build when duplicate Tailwind classes are found?
Add a step that runs an audit tool with a flag that exits with code 1 on any duplicate detection. The CI system treats a non‑zero exit code as a failure, stopping the pipeline.
What does the --dry-run flag do for duplicate‑class detection?
It lists the files that would be changed by an autofix without writing any modifications. [1] This lets maintainers review the impact before applying fixes.
Can the duplicate‑class check run on Windows CI runners?
Yes, CI runs on Ubuntu, Windows and macOS, and NormWind works with Tailwind CSS v4 projects. [1]
Is there a way to only fail on new duplicate classes after a pull request?
Use the --baseline option to record the current per‑file duplicate counts. Subsequent runs will only fail when new findings appear. [1]
Does NormWind need a paid subscription for duplicate detection?
No, NormWind is free with no paid tier. [1]
NormWind is free with no paid tier. [1]
Try NormWindSources
Related comparisons
- How to add a background worker to a dev cluster
- Comparing array library speed on real data for quant analysts
- How to compare two languages in 2026
- How to compare syntax between languages in 2026
- How to copy a working code snippet to try immediately
- How to enforce consistent class order in PRs for CI maintainers
- How to find loop syntax fast for language hoppers in 2026
- How to free a port that is already in use in 2026
- How to let users upload a contacts CSV into a CRM
- How to lint Tailwind classes in CI in 2026