The react-perf rules and react/jsx-props-no-spreading fire heavily on modern React codebases without pointing at real defects. Proposing they be disabled by default in the React preset.
react-perf/jsx-no-new-object-as-prop / jsx-no-new-function-as-prop
These rules predate the React Compiler. Their whole purpose is to stop inline objects and functions from breaking referential equality and causing re-renders — which is exactly what the compiler now memoises automatically.
Worse, they push in the opposite direction to the compiler: satisfying them means hand-rolling useMemo/useCallback, and manual memoisation can make the compiler bail on the component entirely rather than optimise it. So following the rule can measurably reduce optimisation.
They also collide with animation libraries, where prop objects are the API:
<m.div
animate={{ opacity: 1, rotate: 0, scale: 1 }}
initial={{ opacity: 0, rotate: -180, scale: 0.95 }}
transition={{ damping: 20, stiffness: 200, type: "spring" }}
/>
Every one of those three props is a violation. In one app in this org these two rules alone produced 211 of 1027 problems (~21%), essentially all of them Motion props, with no genuine performance finding among them.
react/jsx-props-no-spreading
{...props} is the standard composition pattern for Radix / shadcn-style primitives — a wrapper forwards the underlying element's full prop surface:
const Tabs = ({ className, ref, ...properties }: TabsProperties) => (
<TabsPrimitive.Root className={cn("flex flex-col gap-2", className)} ref={ref} {...properties} />
);
Complying means enumerating every prop of every primitive by hand and re-doing it whenever the upstream library changes. Same app: 49 violations, all in UI primitives.
Suggested change
Default these off in the React preset, with a comment explaining why, and let consumers opt back in:
// The React Compiler memoises component output, so these flag library prop
// objects (Motion animate/initial/transition) with no benefit — and satisfying
// them via manual memoisation can stop the compiler optimising the component.
"react-perf/jsx-no-new-object-as-prop": "off",
"react-perf/jsx-no-new-function-as-prop": "off",
"react-perf/jsx-no-new-array-as-prop": "off",
"react-perf/jsx-no-jsx-as-prop": "off",
// Radix/shadcn-style primitives compose by forwarding the full prop surface.
"react/jsx-props-no-spreading": "off",
Worth also considering whether react-x/no-unstable-context-value and react/jsx-no-constructed-context-values belong in the same group for compiler-enabled projects.
Happy to open a PR if the direction looks right.
The
react-perfrules andreact/jsx-props-no-spreadingfire heavily on modern React codebases without pointing at real defects. Proposing they be disabled by default in the React preset.react-perf/jsx-no-new-object-as-prop/jsx-no-new-function-as-propThese rules predate the React Compiler. Their whole purpose is to stop inline objects and functions from breaking referential equality and causing re-renders — which is exactly what the compiler now memoises automatically.
Worse, they push in the opposite direction to the compiler: satisfying them means hand-rolling
useMemo/useCallback, and manual memoisation can make the compiler bail on the component entirely rather than optimise it. So following the rule can measurably reduce optimisation.They also collide with animation libraries, where prop objects are the API:
Every one of those three props is a violation. In one app in this org these two rules alone produced 211 of 1027 problems (~21%), essentially all of them Motion props, with no genuine performance finding among them.
react/jsx-props-no-spreading{...props}is the standard composition pattern for Radix / shadcn-style primitives — a wrapper forwards the underlying element's full prop surface:Complying means enumerating every prop of every primitive by hand and re-doing it whenever the upstream library changes. Same app: 49 violations, all in UI primitives.
Suggested change
Default these off in the React preset, with a comment explaining why, and let consumers opt back in:
Worth also considering whether
react-x/no-unstable-context-valueandreact/jsx-no-constructed-context-valuesbelong in the same group for compiler-enabled projects.Happy to open a PR if the direction looks right.