Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,8 @@ AST visitors: `JSXAttribute`, `CallExpression`, `TaggedTemplateExpression`, `Var
dir so the `Could not stat` error names the package-local path (fail-loud, never silently reach
past the nearest config into an unrelated ancestor — that masked-typo non-determinism is exactly
why the legacy `string[]` heuristic was removed). Absolute entries pass through `resolve()`
untouched; mapping arrays stay CWD-relative. This makes editor (CWD = workspace root) and CLI (CWD
= package) runs agree in Pattern-B monorepos. Limitation: under `oxlint -c <config>` /
untouched; mapping arrays stay CWD-relative. This makes editor (CWD = workspace root) and CLI
(CWD = package) runs agree in Pattern-B monorepos. Limitation: under `oxlint -c <config>` /
`--disable-nested-config` oxlint suppresses nested discovery but the plugin still walks the FS, so
the nearest `.oxlintrc.json` may diverge from the config oxlint used — docs steer those setups to
absolute paths.
Expand Down
2 changes: 1 addition & 1 deletion bench/lib/timings.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// prints neither the summary nor the timings — pass `-f default` explicitly.
//
// The per-rule numbers cover rule creation, lifecycle hooks and visitor
// callbacks. They do NOT cover plugin import, `createOnce` initialization or
// callbacks, plus selector matching since oxlint 1.87 (oxc#27111). They do NOT cover plugin import, `createOnce` initialization or
// Rust<>JS transfer (oxc#26415), so the design-system load is charged to
// whichever rule's hook first touches it.

Expand Down
404 changes: 154 additions & 250 deletions bench/package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions bench/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
"devDependencies": {
"@shadcn/lint": "0.2.0",
"@tailwindcss/node": "4.3.3",
"eslint-plugin-better-tailwindcss": "4.7.0",
"oxlint": "1.85.0",
"eslint-plugin-better-tailwindcss": "4.9.0",
"oxlint": "1.87.0",
"oxlint-tailwindcss": "1.14.0",
"shadcn": "4.21.0",
"shadcn": "4.21.4",
"tailwindcss": "4.3.3",
"tw-animate-css": "1.4.0"
}
Expand Down
18 changes: 9 additions & 9 deletions bench/results/latest.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
},
"better-tailwindcss": {
"name": "eslint-plugin-better-tailwindcss",
"version": "4.7.0",
"version": "4.9.0",
"config": "btw-all"
}
},
"oxlint": "1.85.0",
"oxlint": "1.87.0",
"tailwindcss": "4.3.3"
},
"concerns": [
Expand Down Expand Up @@ -1570,8 +1570,8 @@
"tailwindcss/no-borrowed-component-styles": 1,
"tailwindcss/no-dark-without-light": 1
},
"warmMs": 1270,
"coldMs": 8633
"warmMs": 1286,
"coldMs": 9549
},
"recommended": {
"config": "otw-recommended",
Expand All @@ -1592,8 +1592,8 @@
"tailwindcss/enforce-negative-arbitrary-values": 1,
"tailwindcss/no-dark-without-light": 1
},
"warmMs": 1138,
"coldMs": 9409
"warmMs": 1200,
"coldMs": 10160
}
},
"shadcn": {
Expand All @@ -1610,7 +1610,7 @@
"shadcn/no-inline-styles": 33,
"shadcn/require-static-classes": 3
},
"warmMs": 1005
"warmMs": 988
}
},
"better-tailwindcss": {
Expand All @@ -1630,7 +1630,7 @@
"better-tailwindcss/enforce-consistent-variable-syntax": 4,
"better-tailwindcss/no-concatenated-classes": 1
},
"warmMs": 36481
"warmMs": 25408
},
"recommended": {
"config": "btw-recommended",
Expand All @@ -1643,7 +1643,7 @@
"better-tailwindcss/no-deprecated-classes": 11,
"better-tailwindcss/no-concatenated-classes": 1
},
"warmMs": 26340
"warmMs": 24897
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
"node": "^22.18.0 || ^24.11.0 || >=26.0.0",
"pnpm": ">=12.6.0"
},
"packageManager": "pnpm@12.6.0"
"packageManager": "pnpm@12.10.1"
}
11 changes: 6 additions & 5 deletions packages/docs/benchmark.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ writes; a weekly job checks that a fresh run still agrees with it.
[shadcn-ui/ui `apps/v4`](https://github.com/shadcn-ui/ui/tree/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4)
@ `98a1fe67`, 880 files
- **Versions**: oxlint-tailwindcss 1.14.0, @shadcn/lint 0.2.0, eslint-plugin-better-tailwindcss
4.7.0; oxlint 1.85.0, tailwindcss 4.3.3
4.9.0; oxlint 1.87.0, tailwindcss 4.3.3
- **Machine**: Apple M4 Pro, 12 cores, darwin 25.5.0, Node 24.19.0; median of 5 runs

<!-- /generated:bench-setup -->
Expand All @@ -35,11 +35,11 @@ them, like the other two.

| Tool | Rules | Warm run | Cold run | Diagnostics |
| -------------------------------- | ----------- | -------- | -------- | ----------- |
| oxlint-tailwindcss | all | 1.3 s | 8.6 s | 2,704 |
| oxlint-tailwindcss | recommended | 1.1 s | 9.4 s | 352 |
| oxlint-tailwindcss | all | 1.3 s | 9.5 s | 2,704 |
| oxlint-tailwindcss | recommended | 1.2 s | 10.2 s | 352 |
| @shadcn/lint | all | 1.0 s | — | 2,578 |
| eslint-plugin-better-tailwindcss | all | 36.5 s | — | 6,284 |
| eslint-plugin-better-tailwindcss | recommended | 26.3 s | — | 705 |
| eslint-plugin-better-tailwindcss | all | 25.4 s | — | 6,284 |
| eslint-plugin-better-tailwindcss | recommended | 24.9 s | — | 705 |

<!-- /generated:bench-speed -->

Expand Down Expand Up @@ -341,6 +341,7 @@ substituted, and `@supports` blocks apply, as they do in the browsers Tailwind v
`& | width`: `20px` → none

:::

<!-- /generated:bench-fix-changes -->

## Run it yourself
Expand Down
4 changes: 2 additions & 2 deletions packages/docs/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ below are the [benchmark](/benchmark)'s, generated from the same results file.

<!-- generated:comparison-summary -->

| Summary | oxlint-tailwindcss 1.14.0 | @shadcn/lint 0.2.0 | eslint-plugin-better-tailwindcss 4.7.0 |
| Summary | oxlint-tailwindcss 1.14.0 | @shadcn/lint 0.2.0 | eslint-plugin-better-tailwindcss 4.9.0 |
| --------------------------------------- | ------------------------- | ------------------ | -------------------------------------- |
| Seeded mistakes caught | 50/56 | 34/56 | 20/56 |
| False alarms on clean lines | 0/6 | 0/6 | 0/6 |
| Warm run, all rules | 1.3 s | 1.0 s | 36.5 s |
| Warm run, all rules | 1.3 s | 1.0 s | 25.4 s |
| Unknown-class reports Tailwind compiles | 0/77 | 0/34 | 0/97 |
| `--fix`: strings whose style changed | 0/670 | no autofix | 1/2,865 |

Expand Down
11 changes: 6 additions & 5 deletions packages/docs/es/benchmark.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ job semanal comprueba que una corrida nueva siga de acuerdo con él.
[shadcn-ui/ui `apps/v4`](https://github.com/shadcn-ui/ui/tree/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4)
@ `98a1fe67`, 880 archivos
- **Versiones**: oxlint-tailwindcss 1.14.0, @shadcn/lint 0.2.0, eslint-plugin-better-tailwindcss
4.7.0; oxlint 1.85.0, tailwindcss 4.3.3
4.9.0; oxlint 1.87.0, tailwindcss 4.3.3
- **Máquina**: Apple M4 Pro, 12 cores, darwin 25.5.0, Node 24.19.0; mediana de 5 corridas

<!-- /generated:bench-setup -->
Expand All @@ -37,11 +37,11 @@ las otras dos.

| Herramienta | Reglas | En caliente | En frío | Diagnósticos |
| -------------------------------- | ------------ | ----------- | ------- | ------------ |
| oxlint-tailwindcss | todas | 1,3 s | 8,6 s | 2704 |
| oxlint-tailwindcss | recomendadas | 1,1 s | 9,4 s | 352 |
| oxlint-tailwindcss | todas | 1,3 s | 9,5 s | 2704 |
| oxlint-tailwindcss | recomendadas | 1,2 s | 10,2 s | 352 |
| @shadcn/lint | todas | 1,0 s | — | 2578 |
| eslint-plugin-better-tailwindcss | todas | 36,5 s | — | 6284 |
| eslint-plugin-better-tailwindcss | recomendadas | 26,3 s | — | 705 |
| eslint-plugin-better-tailwindcss | todas | 25,4 s | — | 6284 |
| eslint-plugin-better-tailwindcss | recomendadas | 24,9 s | — | 705 |

<!-- /generated:bench-speed -->

Expand Down Expand Up @@ -347,6 +347,7 @@ lógicas y físicas se leen de izquierda a derecha, los valores del theme se sus
`& | width`: `20px` → ninguno

:::

<!-- /generated:bench-fix-changes -->

## Córrelo tú
Expand Down
4 changes: 2 additions & 2 deletions packages/docs/es/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ resultados.

<!-- generated:comparison-summary -->

| Resumen | oxlint-tailwindcss 1.14.0 | @shadcn/lint 0.2.0 | eslint-plugin-better-tailwindcss 4.7.0 |
| Resumen | oxlint-tailwindcss 1.14.0 | @shadcn/lint 0.2.0 | eslint-plugin-better-tailwindcss 4.9.0 |
| ---------------------------------------- | ------------------------- | ------------------ | -------------------------------------- |
| Errores sembrados atrapados | 50/56 | 34/56 | 20/56 |
| Falsas alarmas en líneas limpias | 0/6 | 0/6 | 0/6 |
| En caliente, todas las reglas | 1,3 s | 1,0 s | 36,5 s |
| En caliente, todas las reglas | 1,3 s | 1,0 s | 25,4 s |
| Clases desconocidas que Tailwind compila | 0/77 | 0/34 | 0/97 |
| `--fix`: strings cuyo estilo cambió | 0/670 | sin autofix | 1/2865 |

Expand Down
2 changes: 1 addition & 1 deletion packages/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"devDependencies": {
"oxlint-tailwindcss": "workspace:*",
"vitepress": "^2.0.0-alpha.20",
"vitest": "^5.0.2"
"vitest": "^5.0.3"
}
}
4 changes: 2 additions & 2 deletions packages/oxlint-tailwindcss/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@
"devDependencies": {
"@oxlint/plugins": "catalog:",
"@tailwindcss/typography": "^0.5.20",
"@types/node": "^26.6.2",
"@types/node": "^26.6.4",
"oxlint": "catalog:",
"tailwindcss-animate": "^1.0.7",
"tsdown": "^0.23.0",
"tw-animate-css": "^1.4.0",
"typescript": "^7.0.2",
"vitest": "^5.0.2"
"vitest": "^5.0.3"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ function componentSignatures(
if (signature.size < MIN_SHARED || !keys.some(isColorKey) || !keys.some(isSurfaceKey)) {
continue
}
const id = JSON.stringify([...signature].sort())
const id = JSON.stringify([...signature].sort(([a], [b]) => (a < b ? -1 : 1)))
if (seen.has(id)) continue
seen.add(id)
const file = relative(process.cwd(), path).split('\\').join('/')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
* `proseWrap: always` (.oxfmtrc.json), oxfmt reflows an opener that has text
* right under it into one paragraph — the title swallows the first body line,
* a literal `:::` is printed, and the unclosed container wraps the rest of the
* page. That shipped once on /setup and /monorepo (EN and ES).
* page. That shipped once on /setup and /monorepo (EN and ES). oxfmt 0.72
* formats markdown natively (oxc#27256) and keeps a container whole, but the
* blank lines stay the house style and the guard stays for older formatters.
*
* This guards every markdown file the docs site or npm renders: each `:::`
* line is a whole opener or closer, openers and closers sit between blank
Expand Down
Loading
Loading