English
no-arbitrary-value
oxlint rule that reports Tailwind CSS arbitrary values like w-[200px] or bg-[#ff0000], so values come from your theme; an allow list covers exceptions.
At a glance
| Autofix | Editor suggestions | Design system | Options |
|---|---|---|---|
| No | No | Optional — used when entryPoint is set | allow, allowVariables, entryPoint |
What this rule does
Flags any Tailwind utility that uses an arbitrary value — the escape hatch — so your team is forced to either reach for a design token or extend the theme instead of one-off literals. Anything the parser recognizes as an arbitrary value qualifies: dimensions (w-[200px], text-[14px]), colors (bg-[#ff0000]), arbitrary calc expressions (p-[calc(1rem+2px)]), gradients, and the same inside variants (hover:w-[200px]) or with the ! modifier (!w-[200px], w-[200px]!).
Both spellings count. bg-(--brand) is Tailwind v4 sugar for bg-[var(--brand)] — the same arbitrary value, written two ways — and only the bracket form used to be reported. That made enforce-consistent-variable-syntax a laundry service: with its default shorthand setting, its autofix rewrote the reported form into the unreported one and the violation disappeared with the code unchanged in substance.
DS-optional — no entryPoint is needed: whether a class is an arbitrary value is a syntactic check, cheap on large repos. With one configured, the report also names the fix — the closest steps and tokens of your theme, with their values, and the file to add a token to:
text
"w-[203px]" uses an arbitrary value. Closest in your theme: w-50.5 (202px) or w-51 (204px).
If none fits, add a token to src/styles.css.An exact step or token is offered alone (h-[26px] → h-6.5 (26px)); otherwise the nearest one below and above. A value that isn't a length (a colour, a calc()) gets just the file. The design system is loaded on the first violation, never for a clean file; allowVariables: 'runtime' uses it too, to know which CSS variables your stylesheet defines. There is no autofix: replacing an arbitrary value with a token requires human judgement, so the rule only reports.
Arbitrary variants ([&>svg]:w-4) are not arbitrary values and are left alone. The rule looks at the value side of the utility, not the selector prefix.
Options
allow
string[], default [].
A list of utility prefixes where arbitrary values are tolerated. The match is a literal String.prototype.startsWith against the utility's bare form (after stripping ! and any variants), so entries like "grid-cols-" permit grid-cols-[18rem_1fr] without unlocking grid-rows-[...]. Common candidates: container queries (@container), grid templates (grid-cols-, grid-rows-), and truly bespoke transforms (bg-[url().
jsonc
{
"tailwindcss/no-arbitrary-value": ["error", {
"allow": ["grid-cols-", "grid-rows-", "bg-[url("]
}]
}Tip: start with [] to see where your codebase actually needs escapes, then promote the legitimate ones into allow rather than disabling the rule wholesale.
allowVariables
'none' | 'runtime' | 'all', default 'none'.
What to do with a value that is nothing but a CSS variable — w-(--sidebar-width), h-[var(--radix-select-trigger-height)], text-(length:--size), with or without a fallback or an opacity modifier:
'none'reports them, like any arbitrary value.'runtime'allows the variables no CSS in your design system defines — the ones JavaScript or an inlinestylesets at runtime, like Radix's--radix-*or a sidebar's--sidebar-width, for which no token exists. A variable your stylesheet defines (--primary) is still reported: a named utility exists for it (seeprefer-theme-tokens). This mode reads the design system; without anentryPointnothing can be proven undefined, so references are reported.'all'allows every pure variable reference.
A value that does more than read a variable — w-[calc(var(--x)*2)] — is an arbitrary value in every mode.
jsonc
{ "tailwindcss/no-arbitrary-value": ["warn", { "allowVariables": "runtime" }] }entryPoint
string, optional. Per-rule override of settings.tailwindcss.entryPoint, read only by allowVariables: 'runtime'.
Examples
✗ Incorrect
tsx
// One-off dimension instead of a spacing token
<div className="w-[200px] p-[10px]" />
// Hex literal instead of a theme color
<div className="bg-[#ff0000] text-white" />
// Variant doesn't change the verdict
<div className="hover:w-[200px]" />
// `!` modifier doesn't either
<div className="!w-[200px]" />
// The v4 shorthand is the same arbitrary value
<div className="bg-(--brand) border-(length:--stroke)" />✓ Correct
tsx
// Use spacing tokens
<div className="w-64 p-2.5" />
// Use a theme color you declared in @theme
<div className="bg-brand text-white" />
// Arbitrary variants are fine — they target selectors, not values
<div className="[&>svg]:w-4" />
// Allowed via `allow: ["grid-cols-"]`
// options: { "allow": ["grid-cols-"] }
<div className="grid grid-cols-[18rem_1fr]" />Interactions with other rules
no-hardcoded-colors: a strict subset focused on color utilities (bg-[#ff0],text-[rgb(...)]). Enable that one if you want the granular color-only message; enable both for layered enforcement. They'll both fire on the same class, which is usually desired during migration.no-unnecessary-arbitrary-value: this rule prohibits arbitrary values outright;no-unnecessary-arbitrary-valueis gentler — it only flags arbitraries that have an exact named equivalent (w-[100%]→w-full). Both can coexist: the gentler rule autofixes the trivial cases and this rule catches what's left.prefer-theme-tokens: similar intent, but DS-dependent.prefer-theme-tokensactually consults your@themeand suggests the matching token. Pair them: this rule is your stop-gap when no token exists yet.enforce-consistent-variable-syntax: converts betweenbg-[var(--x)]andbg-(--x). Since both forms report here, running it — in either direction — cannot move a class out of this rule's reach.
When to disable it
- Prototyping / spike branches where speed beats discipline. Re-enable before merging.
- Files that genuinely need an arbitrary value (one-off marketing pages, dynamic CSS-in-JS shims). Prefer
allowwith a tight prefix list, or disable per-line via// oxlint-disable-next-line tailwindcss/no-arbitrary-value. - Libraries that ship Tailwind utilities consumers re-skin: the arbitrary form is sometimes the cleanest contract. Document the decision and disable the rule in that package.