Skip to content

fix(deps): upgrade tailwindcss to v4 and eslint to v10 - #206

Merged
jplanckeel merged 1 commit into
BananaOps:mainfrom
TartanLeGrand:fix/web-tailwind4-eslint10
Oct 1, 2026
Merged

jplanckeel merged 1 commit into
BananaOps:mainfrom
TartanLeGrand:fix/web-tailwind4-eslint10

Conversation

@TartanLeGrand

Copy link
Copy Markdown
Contributor

Why

#204 (Snyk) bumps tailwindcss 3 to 4 and eslint 9 to 10 in package.json only:

  • package-lock.json is not updated, so npm ci fails on it (lockfile out of sync);
  • Tailwind 4 drops tailwind.config.js + the tailwindcss PostCSS plugin, so the build breaks without a migration;
  • ESLint 10 is refused by the installed eslint-plugin-react-hooks 5 (peer range stops at 9).

The advisory it targets (braces, uncontrolled recursion) only reaches us through Tailwind 3 (chokidar, micromatch) at build time, and braces has no patched release: dropping Tailwind 3 is the fix. urijs is not in the dependency tree.

This PR does the full upgrade and supersedes #204.

What

Tailwind 4, migrated with @tailwindcss/upgrade, then compared page by page with main:

  • configuration moved to @theme in src/index.css; PostCSS uses @tailwindcss/postcss (autoprefixer is built in);
  • templates renamed to the v4 utilities (shadow-sm to shadow-xs, rounded to rounded-sm, outline-none to outline-hidden, ...);
  • dark mode overrides of the legacy gray classes kept as plain CSS. Tailwind 3 also applied them to variants (dark:text-gray-300, dark:hover:bg-gray-800, ...) because they sat in @layer utilities; v4 does not, so the exact selector list v3 generated is written out;
  • FontAwesome CSS imported into Tailwind's base layer (config.autoAddCss = false): injected unlayered at runtime, it beats every v4 utility and icons sized with w-8 h-8 collapsed to 1em;
  • v3 absolute line heights and placeholder color restored;
  • two rewrites of the upgrade tool reverted: a color token argument a('outline', ...) turned into outline-solid (caught by tsc), and the active nav icon text-[#E8580A] swapped for icon-gradient-yellow, which turns yellow in dark mode.

ESLint 10 with @eslint/js 10 and eslint-plugin-react-hooks 7. Its recommended preset now bundles the React Compiler rules (33 new errors); the two classic rules are configured explicitly so the lint scope is unchanged. One new no-useless-assignment hit fixed in ThemeContext.tsx.

Checks

  • npm ci and npm audit: 0 vulnerabilities.
  • npm run build and npm run build:static: green.
  • tsc --noEmit: 122 errors, same as main. eslint .: 78 errors / 165 warnings, same as main.
  • Visual comparison of the static build against main: 11 pages (dashboard, timeline, calendar, catalog, drifts, RPA, locks, links, insights, docs, theme test) in light and dark mode, pixel diff. Remaining differences are the v4 default palette (OKLCH, slightly more saturated: banners, a few links and chart bars).

Notes

Supersedes #204

Replaces BananaOps#204, which bumps both majors in package.json only: the lockfile
is left out of sync (npm ci fails) and Tailwind 4 needs a migration.

Tailwind 4, migrated with @tailwindcss/upgrade then checked page by page
against main (light and dark screenshots of the static build):
- config moved from tailwind.config.js to @theme in index.css, PostCSS now
  uses @tailwindcss/postcss (autoprefixer is built in);
- templates renamed to the v4 utilities (shadow-sm to shadow-xs, rounded to
  rounded-sm, outline-none to outline-hidden...);
- dark mode overrides of the legacy gray classes kept as plain CSS, with
  the variant selectors (dark:, hover:, dark:hover:) Tailwind 3 used to
  generate for them listed explicitly;
- FontAwesome CSS imported into the base layer instead of injected at
  runtime, otherwise its unlayered height beats every sizing utility;
- v3 line heights and placeholder color restored for identical rendering;
- two rewrites of the upgrade tool reverted: a color token argument turned
  into outline-solid, and text-[#E8580A] swapped for a utility that changes
  color in dark mode.
The remaining visual difference is the v4 default palette (OKLCH).

ESLint 10 requires eslint-plugin-react-hooks 7, whose recommended preset
now includes the React Compiler rules; the two classic rules are kept so
the lint scope does not change. One no-useless-assignment hit fixed.
@jplanckeel
jplanckeel merged commit 6723448 into BananaOps:main Oct 1, 2026
1 of 2 checks passed
TartanLeGrand added a commit to TartanLeGrand/tracker that referenced this pull request Oct 2, 2026
main moved to Tailwind 4 (BananaOps#206): rounded becomes rounded-sm and
outline-none becomes outline-hidden in the user menu and the API key
dialog.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants