Skip to content

no-unnecessary-whitespace ​

oxlint rule that collapses repeated spaces and trims leading and trailing whitespace in Tailwind CSS class strings, with an autofix.

At a glance ​

AutofixEditor suggestionsDesign systemOptions
YesNoNot usedNone

What this rule does ​

Normalizes whitespace inside Tailwind class strings: runs of spaces or tabs collapse to one space, leading and trailing whitespace gets trimmed (with one carve-out at template-expression boundaries — see below), and the rule autofixes everything in a single pass.

DS-independent — works without settings.tailwindcss.entryPoint. Pure whitespace transform.

The rule is multiline-aware: it deliberately preserves \n + the indentation that follows each newline. That's the format enforce-consistent-line-wrapping produces with classesPerLine, and collapsing it back would set up an unfixable cycle between the two rules (issue #14). This includes the indented closing backtick of the block convention (a \n + spaces before the closing `) — that trailing indentation is intentional formatting and is never trimmed (issue #109). Inside one line, tabs and double spaces still collapse normally.

Template literals get one extra rule: a single trailing space before an expression (`flex ${x}`) or a single leading space after one (`${x} flex`) is preserved — those are intentional spaces that prevent classes from being smashed together at runtime.

Options ​

This rule has no options. The behavior is "collapse runs to single spaces, preserve intentional newlines and template-boundary spaces" — there's no useful axis to configure.

Examples ​

✗ Incorrect ​

tsx
// Leading + trailing + internal double spaces
<div className="  flex   items-center  " />
//              ~~~~~~~~~~~~~~~~~~~~~~~~  → "flex items-center"

// Internal double space
<div className="flex  items-center" />
//              ~~~~~~~~~~~~~~~~~~  → "flex items-center"

// Tab as separator inside a single line
const className = `flex	items-center`
//                 ~~~~~~~~~~~~~~~~~  → "flex items-center"

✓ Correct ​

tsx
// Single spaces
<div className="flex items-center" />

// Template literal: boundary spaces preserved
<div className={`flex ${x}`} />
<div className={`${x} flex`} />

// Multiline (e.g. from enforce-consistent-line-wrapping): preserved
const className = `bg-red-500 text-white
                   hover:bg-red-600 focus:ring-2`

// Block convention: the indented closing backtick is preserved (#109)
const className = `
  bg-red-500 text-white
  hover:bg-red-600 focus:ring-2
`

Interactions with other rules ​

  • enforce-consistent-line-wrapping: designed to coexist. This rule preserves the \n + indent that wrapping inserts; without that, the two would fight on every autofix pass.
  • enforce-sort-order and every other class-rewriting rule: those rebuild the string via rebuildClassString, which always emits canonical single-space separators — running them first makes no-unnecessary-whitespace a no-op.
  • All extractor-driven rules: the cleaned-up string is what every other rule sees on the next pass, so running this rule early in a fix cycle keeps downstream errors readable.

When to disable it ​

  • You rely on a formatter like prettier or oxfmt to handle whitespace globally. They cover the same ground, and disabling the lint rule removes redundant work.
  • Class strings that intentionally use unusual whitespace (very rare — almost always a bug in extractor configuration rather than intent).

Released under the MIT License.