English
Rules
The 27 rules in oxlint-tailwindcss, grouped by what they enforce. Click into any rule for examples and option reference.
Correctness
These rules catch problems that would generate invalid or unexpected CSS.
- no-unknown-classes — disallow class names the design system doesn't know about.
- no-conflicting-classes — flag classes that fight over the same CSS property.
- no-contradicting-variants —
flex hover:flexis redundant (only on literal class lists on native elements, notcn/twMergefragments). - no-dark-without-light — a
dark:colour should have a light-mode pair (only on literal class lists on native elements, notcn/twMergefragments). - no-duplicate-classes — same class twice is dead weight.
- no-dynamic-classes —
bg-${color}-500is built at runtime, so Tailwind generates no CSS for it.
Modernization
- no-deprecated-classes —
flex-grow→grow, etc. - enforce-canonical —
-m-0→m-0,start-2→inset-s-2, etc. - no-unnecessary-arbitrary-value —
w-[100%]→w-fullwhen the named class emits identical CSS. - prefer-theme-tokens —
border-(--border)→border-borderwhen a named utility maps to the same theme variable. - prefer-scale-token —
p-[10px]→p-2.5,w-[200px]→w-50when the token is the same VALUE (report-only; the CSS differs textually). - enforce-negative-arbitrary-values —
-top-[5px]→top-[-5px].
Consistency
- enforce-sort-order — sort classes in the official Tailwind order.
- consistent-variant-order —
dark:hover:vshover:dark:. - enforce-consistent-important-position — prefix
!flexvs suffixflex!. - enforce-consistent-line-wrapping — one class per line vs all on one.
- enforce-consistent-variable-syntax —
bg-(--x)vsbg-[var(--x)]. - enforce-logical —
ml-4→ms-4for RTL support. - enforce-physical —
ms-4→ml-4for LTR-only projects. - enforce-shorthand —
mt-2 mr-2 mb-2 ml-2→m-2. - no-unnecessary-whitespace — collapse runs of spaces.
Design-system guardrails
- no-arbitrary-value — disallow
w-[3.14rem]and friends. - no-borrowed-component-styles — a plain element that rebuilds one of your components from its classes (experimental).
- no-default-palette — disallow
bg-red-500when your theme has colors of its own. - no-hardcoded-colors — disallow
bg-[#fff], prefer theme tokens. - no-restricted-classes — ban specific classes or regex patterns.
- max-class-count — cap how many classes a single class string can stack.
Per-rule pages
Each rule's page covers:
- What it does, in one paragraph.
- Options with their default values and a description per option.
- Correct / incorrect examples.
- When to disable it — the use cases where this rule is the wrong fit.
- For DS-dependent rules: whether
entryPointis required (always yes in v1) and what happens when it's missing.
Defaults reference
A quick lookup table for what each rule does when you turn it on without overriding meta.defaultOptions.
DS-dependent rules
These rules require settings.tailwindcss.entryPoint to be set; they emit a fatal designSystemUnavailable diagnostic when it isn't.
| Rule | Default options |
|---|---|
enforce-canonical | { reportNonEquivalent: false } |
enforce-sort-order | { mode: 'default' } |
no-borrowed-component-styles | { components: [] } |
no-conflicting-classes | { reportRedundant: true } |
no-default-palette | { allow: [] } |
no-unknown-classes | { allowlist: [], ignorePrefixes: [] } |
no-unnecessary-arbitrary-value | {} |
prefer-scale-token | {} |
prefer-theme-tokens | {} |
DS-optional rules
These work with nothing configured — their fallback is deterministic on its own — and get more accurate when an entryPoint is available. None of them can emit designSystemUnavailable. Each also accepts a rule-level entryPoint that overrides the shared setting.
| Rule | Default options | What the design system adds |
|---|---|---|
consistent-variant-order | {} (same order with or without a DS) | What the project's own variants are: pseudo-element, barrier or breakpoint |
enforce-consistent-line-wrapping | { printWidth: 80, group: 'newLine', wrapStrings: 'never' } | The project prefix, so wrapLines: 'all' grouping treats it as transparent |
enforce-logical | { allowlist: [], direction: 'both', sizing: false } | Confirms the suggested class exists and that your Tailwind has the 4.2 utilities (block axis, sizes, inset-s); without a DS the block axis and sizes are only suggested |
enforce-physical | { allowlist: [], direction: 'both', sizing: false } | Confirms the suggested class exists |
enforce-shorthand | {} | Verifies each merge against the emitted CSS |
no-arbitrary-value | { allow: [], allowVariables: 'none' } | With allowVariables: 'runtime', which CSS variables your stylesheet defines |
no-contradicting-variants | {} | What each variant's selector does |
no-dark-without-light | { variants: ['dark'] } | Tells colours from the rest, and groups the base by declared CSS property |
no-deprecated-classes | {} | Derives the rename list instead of using the built-in table |
no-dynamic-classes | {} | Your project's own utilities and variants count as Tailwind's |
no-hardcoded-colors | { allow: [] } | Names your theme's colors in the message |
DS-independent rules
| Rule | Default options |
|---|---|
enforce-consistent-important-position | { position: 'suffix' } |
enforce-consistent-variable-syntax | { syntax: 'shorthand' } |
enforce-negative-arbitrary-values | (no options) |
max-class-count | { max: 20 } |
no-duplicate-classes | (no options) |
no-restricted-classes | { classes: [], patterns: [] } |
no-unnecessary-whitespace | (no options) |