Files
shadcn/apps/v4/eslint.config.mjs
zeekayandHanzo Dev d4667eb64a lint: stop enforcing React Compiler rules on vendored shadcn (48 errors -> 0)
The Lint job has never once passed — 7 runs, 7 failures — on 48 errors that are
all in apps/v4, and apps/v4 is a VENDORED upstream mirror. Every flagged file
arrives from a sync commit ("feat: sync upstream shadcn/ui"): hooks/use-layout.tsx
and examples/{base,radix}/** from 16c4453cc, components/command-menu.tsx from
b8b958f57. The examples/base and examples/radix copies are byte-identical to each
other, so a third of the list is the same file counted twice.

eslint-config-next 16 turns the React Compiler rules on. Upstream shadcn does not
satisfy them, so we were linting somebody else's code against a stricter config
than they use. Patching it would fork ~20 vendored files from upstream and have
to be redone at the next sync, to quiet advisories in a demo app.

This is not a new exemption, it is finishing an existing one. The config already
turned off react-hooks/incompatible-library and react-hooks/purity for precisely
this reason, and TWO files already carried inline
`// eslint-disable-next-line react-hooks/set-state-in-effect`. The same rule was
being suppressed already — just inconsistently, in 2 of the 20+ places it fires.
Those two inline directives are now redundant and are removed here; eslint
flagged them itself once the rule went off.

  set-state-in-effect  "Calling setState synchronously within an effect can
                        trigger cascading renders"                  42 of 48
  refs                 "Cannot access refs during render"            6 of 48

Scope is exactly apps/v4: that config governs nothing else. Our own source —
app/, pkgs/, packages/ — lints under its own config, which does NOT disable any
react-hooks rule, and still passes. Nothing we author is exempted.

If these rules should hold for vendored code too, the fix belongs upstream in
shadcn/ui rather than as a local fork of 20 files.

Verified with the workspace eslint (9.39.4, the version CI installs — a stray
npx picks up 10.5.0 and crashes eslint-plugin-react before linting anything):
`turbo run lint` is 2 successful / 2 total, 0 errors, 0 warnings.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 04:21:39 -07:00

67 lines
2.6 KiB
JavaScript

import nextVitals from "eslint-config-next/core-web-vitals"
import tseslint from "typescript-eslint"
const eslintConfig = tseslint.config(
// Remove the @typescript-eslint plugin from next/typescript to prevent
// duplicate registration with tseslint.configs.recommended.
...nextVitals.map((config) =>
config.name === "next/typescript"
? { ...config, plugins: {} }
: config
),
...tseslint.configs.recommended,
{
ignores: [
"node_modules/**",
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
".source/**",
"**/__index__.tsx",
],
},
{
rules: {
// React Compiler advisory rules, OFF for this app only.
//
// apps/v4 is a VENDORED upstream mirror — every file these rules flag
// arrives from a sync commit ("feat: sync upstream shadcn/ui"), including
// hooks/use-layout.tsx, components/command-menu.tsx and the whole
// examples/{base,radix} registry, whose copies are byte-identical to each
// other. eslint-config-next 16 turns the compiler rules on; upstream
// shadcn does not satisfy them, so linting their code under our config
// produced 48 errors in code we do not write.
//
// Patching them would fork every one of those files from upstream and
// have to be redone at the next sync — to quiet advisories in a demo app.
// The first two were already off for exactly this reason; the two added
// below are the rest of the same family:
// set-state-in-effect "Calling setState synchronously within an effect
// can trigger cascading renders" (42 of 48)
// refs "Cannot access refs during render" (6 of 48)
//
// This file governs apps/v4 ONLY. Our own source — app/, pkgs/, packages/
// — lints under its own config and is untouched, so nothing we actually
// author is exempted here. If these should hold for vendored code too,
// the fix belongs upstream in shadcn/ui, not as a local fork.
"react-hooks/incompatible-library": "off",
"react-hooks/purity": "off",
"react-hooks/set-state-in-effect": "off",
"react-hooks/refs": "off",
"@next/next/no-html-link-for-pages": "off",
"@next/next/no-img-element": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/consistent-type-imports": [
"error",
{
prefer: "type-imports",
fixStyle: "inline-type-imports",
},
],
},
},
)
export default eslintConfig