When the same combination of Tailwind utilities appears in 3+ places, extract it to a component or @apply directive. Duplicated utility strings mean a design change (like spacing or color) requires finding and updating every copy — miss one and you have an inconsistent UI.
Duplicated Tailwind utility strings create silent UI inconsistency. When a design change requires updating spacing, colors, or sizing, every copy must be found and changed. Miss one copy and you have an inconsistent UI that erodes user trust. With 3+ copies, the probability of missing one approaches certainty.
BeforeMerge scans your pull requests against this rule and 4+ others. Get actionable feedback before code ships.
Tailwind's utility-first approach is powerful, but without discipline it leads to the same long class string being duplicated across dozens of files. When you need to change the padding, border radius, or color scheme of a repeated pattern, you must find and update every copy.
With 2 copies, this is manageable. With 3+ copies scattered across different files, you will miss at least one during a design update. The result is an inconsistent UI where some cards have the old spacing and others have the new spacing — subtle enough that it passes code review but visible enough that users notice.
Extraction at the right level (component for reusable UI, @apply for utility combinations) keeps the design consistent and changes in one place.
When the same combination of 3+ Tailwind utilities appears in 3 or more places, extract it. Prefer extracting to a React component. Use @apply only when a component is overkill (e.g., a recurring text style).
// File 1: user-card.tsx
<div className="rounded-lg border border-gray-200 bg-white p-4 shadow-sm hover:shadow-md transition-shadow">
...
</div>
// File 2: project-card.tsx
<div className="rounded-lg border border-gray-200 bg-white p-4 shadow-sm hover:shadow-md transition-shadow">
...
</div>
// File 3: team-card.tsx
<div className="rounded-lg border border-gray-200 bg-white p-4 shadow-sm hover:shadow-md transition-shadow">
...
</div>// components/ui/card.tsx — single source of truth
export function Card({ children, className }: CardProps) {
return (
<div className={cn(
"rounded-lg border border-gray-200 bg-white p-4 shadow-sm hover:shadow-md transition-shadow",
className
)}>
{children}
</div>
);
}
// File 1: user-card.tsx
<Card>...</Card>
// File 2: project-card.tsx
<Card>...</Card>
// File 3: team-card.tsx
<Card>...</Card>Look for long className strings that appear in multiple files. During code review, ask: "Have I seen this class combination before?"
Automated detection is difficult, but you can search for common patterns:
grep -rn 'rounded-lg border' --include="*.tsx" | wc -lIf the count is 3+, it is time to extract.
@apply class