Skip to content

React Review Audit #446

Description

@react-doctor
10 errors, ⚠️ 228 warnings 81 score
Copy as prompt
Fix the following React Review diagnostics in my codebase.

## Errors (10)

1. [error] jsx-key — packages/scan/src/web/views/notifications/collapsed-event.tsx:165
   Missing "key" prop for element in iterator.

2. [error] no-mutable-in-deps — packages/scan/src/web/views/notifications/popover.tsx:73
   "triggerRef.current" in deps — refs are mutable and don't trigger re-renders, so React won't re-run this effect when it changes. Read the ref inside the effect body instead

3. [error] effect-needs-cleanup — packages/scan/src/web/views/notifications/notifications.tsx:227
   useEffect schedules `setTimeout(...)` but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls clearTimeout(...)

4. [error] effect-needs-cleanup — packages/scan/src/web/views/notifications/slowdown-history.tsx:27
   useEffect schedules `setTimeout(...)` but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls clearTimeout(...)

5. [error] effect-needs-cleanup — packages/scan/src/web/views/notifications/slowdown-history.tsx:339
   useEffect schedules `setTimeout(...)` but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls clearTimeout(...)

6. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
   Async client component "B" — client components cannot be async

7. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
   Async client component "Pa" — client components cannot be async

8. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
   Async client component "Ul" — client components cannot be async

9. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
   Async client component "Jl" — client components cannot be async

10. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
   Async client component "Tc" — client components cannot be async

## Warnings (228)

11. [warning] no-cascading-set-state — kitchen-sink/src/examples/sierpinski/index.tsx:27
   3 setState calls in a single useEffect — consider using useReducer or deriving state

12. [warning] click-events-have-key-events — kitchen-sink/src/examples/e2e-fixture/index.tsx:46
   Enforce a clickable non-interactive element has at least one keyboard event listener.

13. [warning] no-static-element-interactions — kitchen-sink/src/examples/e2e-fixture/index.tsx:46
   Static HTML elements with event handlers require a role.

14. [warning] no-react19-deprecated-apis — kitchen-sink/src/examples/e2e-fixture/index.tsx:1
   useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`

15. [warning] no-uncontrolled-input — kitchen-sink/src/examples/todo-list/index.tsx:92
   <input value={...}> with no `onChange` or `readOnly` — React renders this as a silently read-only field

16. [warning] rerender-functional-setstate — kitchen-sink/src/examples/todo-list/index.tsx:88
   setIndex(index + ...) — use functional update to avoid stale closures

17. [warning] iframe-has-title — kitchen-sink/src/main.tsx:39
   Missing `title` attribute for the `iframe` element.

18. [warning] design-no-default-tailwind-palette — kitchen-sink/src/main.tsx:19
   border-gray-950 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

19. [warning] design-no-bold-heading — kitchen-sink/src/main.tsx:20
   font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)

20. [warning] design-no-default-tailwind-palette — kitchen-sink/src/main.tsx:24
   border-gray-950 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

21. [warning] design-no-default-tailwind-palette — kitchen-sink/src/main.tsx:29
   border-gray-950 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

22. [warning] js-batch-dom-css — packages/extension/src/inject/notification.ts:36
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

23. [warning] js-batch-dom-css — packages/extension/src/inject/notification.ts:130
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

24. [warning] js-set-map-lookups — packages/scan/src/core/index.ts:299
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

25. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:172
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

26. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:176
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

27. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:177
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

28. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:178
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

29. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:179
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

30. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:195
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

31. [warning] no-pure-black-background — packages/scan/src/web/toolbar.tsx:22
   Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

32. [warning] no-pure-black-background — packages/scan/src/web/toolbar.tsx:27
   Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

33. [warning] no-giant-component — packages/scan/src/web/views/inspector/components-tree/index.tsx:386
   Component "ComponentsTree" is 792 lines — consider breaking it into smaller focused components

34. [warning] design-no-redundant-size-axes — packages/scan/src/web/views/inspector/components-tree/index.tsx:1072
   w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

35. [warning] design-no-redundant-size-axes — packages/scan/src/web/views/inspector/components-tree/index.tsx:1086
   w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

36. [warning] design-no-redundant-size-axes — packages/scan/src/web/views/inspector/components-tree/index.tsx:1102
   w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

37. [warning] async-await-in-loop — packages/scan/src/new-outlines/index.ts:153
   await inside a while-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

38. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:304
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

39. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:305
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

40. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:306
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

41. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:307
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

42. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:318
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

43. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:381
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

44. [warning] client-passive-event-listeners — packages/scan/src/new-outlines/index.ts:407
   "scroll" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault())

45. [warning] rerender-transitions-scroll — packages/scan/src/new-outlines/index.ts:411
   setState in a "scroll" handler triggers re-renders at scroll/pointer frequency — wrap in startTransition (mark as non-urgent), use useDeferredValue, or stash in a ref + rAF throttle

46. [warning] js-flatmap-filter — packages/scan/src/web/views/inspector/timeline/utils.ts:148
   .map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass

47. [warning] no-cascading-set-state — packages/scan/src/web/views/notifications/collapsed-event.tsx:36
   11 setState calls in a single useEffect — consider using useReducer or deriving state

48. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1357
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

49. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1394
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

50. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1446
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

51. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1865
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

52. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1888
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

53. [warning] js-tosorted-immutable — packages/scan/src/polyfills.ts:4
   [...array].sort() — use array.toSorted() for immutable sorting (ES2023)

54. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:5
   Unknown property found

55. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:5
   Unknown property found

56. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:5
   Unknown property found

57. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:18
   Unknown property found

58. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:18
   Unknown property found

59. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:18
   Unknown property found

60. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:23
   Unknown property found

61. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:23
   Unknown property found

62. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:23
   Unknown property found

63. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:27
   Unknown property found

64. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:27
   Unknown property found

65. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:27
   Unknown property found

66. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:31
   Unknown property found

67. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:31
   Unknown property found

68. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:31
   Unknown property found

69. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:36
   Unknown property found

70. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:36
   Unknown property found

71. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:36
   Unknown property found

72. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:45
   Unknown property found

73. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:45
   Unknown property found

74. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:45
   Unknown property found

75. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:51
   Unknown property found

76. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:51
   Unknown property found

77. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:51
   Unknown property found

78. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:56
   Unknown property found

79. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:56
   Unknown property found

80. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:56
   Unknown property found

81. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:60
   Unknown property found

82. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:60
   Unknown property found

83. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:60
   Unknown property found

84. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:64
   Unknown property found

85. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:64
   Unknown property found

86. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:64
   Unknown property found

87. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:72
   Unknown property found

88. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:72
   Unknown property found

89. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:72
   Unknown property found

90. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:78
   Unknown property found

91. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:78
   Unknown property found

92. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:78
   Unknown property found

93. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:84
   Unknown property found

94. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:84
   Unknown property found

95. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:84
   Unknown property found

96. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:89
   Unknown property found

97. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:89
   Unknown property found

98. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:89
   Unknown property found

99. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:94
   Unknown property found

100. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:94
   Unknown property found

101. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:94
   Unknown property found

102. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:99
   Unknown property found

103. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:99
   Unknown property found

104. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:99
   Unknown property found

105. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:104
   Unknown property found

106. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:104
   Unknown property found

107. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:104
   Unknown property found

108. [warning] js-cache-property-access — packages/scan/src/web/views/inspector/whats-changed/use-change-store.ts:123
   aggregatedChanges.contextChanges.set is read 3 times inside this loop — hoist into a const at the top of the loop body

109. [warning] js-cache-property-access — packages/scan/src/web/views/inspector/whats-changed/use-change-store.ts:128
   change.contextType.toString is read 3 times inside this loop — hoist into a const at the top of the loop body

110. [warning] design-no-default-tailwind-palette — packages/scan/src/web/views/inspector/diff-value.tsx:55
   text-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

111. [warning] design-no-default-tailwind-palette — packages/scan/src/web/views/inspector/diff-value.tsx:81
   text-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

112. [warning] design-no-default-tailwind-palette — packages/scan/src/web/views/inspector/diff-value.tsx:118
   text-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

113. [warning] no-array-index-as-key — packages/scan/src/web/views/inspector/diff-value.tsx:143
   Array index "index" used as key — causes bugs when list is reordered or filtered

114. [warning] js-flatmap-filter — packages/scan/src/core/notifications/event-tracking.ts:290
   .map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass

115. [warning] no-giant-component — packages/scan/src/web/views/inspector/overlay/index.tsx:48
   Component "ScanOverlay" is 684 lines — consider breaking it into smaller focused components

116. [warning] no-cascading-set-state — packages/scan/src/web/views/inspector/what-changed.tsx:36
   3 setState calls in a single useEffect — consider using useReducer or deriving state

117. [warning] js-combine-iterations — packages/scan/src/web/views/inspector/what-changed.tsx:49
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

118. [warning] no-render-in-render — packages/scan/src/web/views/inspector/what-changed.tsx:323
   Inline render function "renderName()" — extract to a separate component for proper reconciliation

119. [warning] no-array-index-as-key — packages/scan/src/web/views/inspector/what-changed.tsx:452
   Array index "i" used as key — causes bugs when list is reordered or filtered

120. [warning] js-batch-dom-css — packages/scan/src/web/views/inspector/flash-overlay.ts:64
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

121. [warning] js-batch-dom-css — packages/scan/src/web/views/inspector/flash-overlay.ts:68
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

122. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:18
   Unknown property found

123. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:19
   Unknown property found

124. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:20
   Unknown property found

125. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:78
   Unknown property found

126. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:79
   Unknown property found

127. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:80
   Unknown property found

128. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:123
   Unknown property found

129. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:124
   Unknown property found

130. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:125
   Unknown property found

131. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:143
   Unknown property found

132. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:144
   Unknown property found

133. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:145
   Unknown property found

134. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:165
   Unknown property found

135. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:166
   Unknown property found

136. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:167
   Unknown property found

137. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:192
   Unknown property found

138. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:193
   Unknown property found

139. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:194
   Unknown property found

140. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:213
   Unknown property found

141. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:214
   Unknown property found

142. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:215
   Unknown property found

143. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:237
   Unknown property found

144. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:238
   Unknown property found

145. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:239
   Unknown property found

146. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:265
   Unknown property found

147. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:266
   Unknown property found

148. [warning] no-unknown-property — packages/scan/src/web/views/notifications/icons.tsx:267
   Unknown property found

149. [warning] rerender-memo-with-default-value — packages/scan/src/web/views/notifications/icons.tsx:55
   Default prop value [] creates a new array reference every render — extract to a module-level constant

150. [warning] no-unknown-property — packages/scan/src/web/widget/resize-handle.tsx:349
   Unknown property found

151. [warning] no-giant-component — packages/scan/src/web/widget/resize-handle.tsx:26
   Component "ResizeHandle" is 353 lines — consider breaking it into smaller focused components

152. [warning] rerender-lazy-state-init — packages/scan/src/web/views/notifications/render-explanation.tsx:16
   useState(getIsProduction()) calls initializer on every render — use useState(() => getIsProduction()) for lazy initialization

153. [warning] no-cascading-set-state — packages/scan/src/web/views/notifications/popover.tsx:75
   4 setState calls in a single useEffect — consider using useReducer or deriving state

154. [warning] no-permanent-will-change — packages/scan/src/web/views/notifications/popover.tsx:167
   Permanent will-change wastes GPU memory — apply only during active animation and remove after

155. [warning] rerender-lazy-state-init — packages/scan/src/web/views/notifications/render-bar-chart.tsx:67
   useState(getIsProduction()) calls initializer on every render — use useState(() => getIsProduction()) for lazy initialization

156. [warning] no-giant-component — packages/scan/src/web/views/notifications/render-bar-chart.tsx:184
   Component "RenderBar" is 345 lines — consider breaking it into smaller focused components

157. [warning] rendering-hydration-mismatch-time — packages/scan/src/web/views/notifications/render-bar-chart.tsx:261
   Date.now() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

158. [warning] rendering-hydration-mismatch-time — packages/scan/src/web/views/notifications/render-bar-chart.tsx:365
   Date.now() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

159. [warning] no-array-index-as-key — packages/scan/src/web/views/notifications/render-bar-chart.tsx:502
   Array index "i" used as key — causes bugs when list is reordered or filtered

160. [warning] js-combine-iterations — packages/scan/src/web/views/toolbar/index.tsx:194
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

161. [warning] js-combine-iterations — packages/scan/src/web/views/notifications/notifications.tsx:34
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

162. [warning] js-combine-iterations — packages/scan/src/web/views/notifications/notifications.tsx:43
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

163. [warning] js-combine-iterations — packages/scan/src/web/views/notifications/notifications.tsx:51
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

164. [warning] rendering-hydration-mismatch-time — packages/scan/src/web/views/notifications/notifications.tsx:441
   Date.now() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

165. [warning] rendering-hydration-mismatch-time — packages/scan/src/web/views/notifications/notifications.tsx:464
   Date.now() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

166. [warning] no-giant-component — packages/scan/src/web/widget/index.tsx:44
   Component "Widget" is 715 lines — consider breaking it into smaller focused components

167. [warning] rerender-state-only-in-handlers — packages/scan/src/web/widget/index.tsx:653
   useState "_" is updated but never read in the component's return — use useRef so updates don't trigger re-renders

168. [warning] js-batch-dom-css — packages/scan/src/web/widget/index.tsx:574
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

169. [warning] js-batch-dom-css — packages/scan/src/web/widget/index.tsx:606
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

170. [warning] js-batch-dom-css — packages/scan/src/web/widget/index.tsx:607
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

171. [warning] rendering-hydration-no-flicker — packages/scan/src/web/widget/index.tsx:654
   useEffect(setState, []) on mount causes a flash — consider useSyncExternalStore or suppressHydrationWarning

172. [warning] no-cascading-set-state — packages/scan/src/web/views/notifications/slowdown-history.tsx:27
   3 setState calls in a single useEffect — consider using useReducer or deriving state

173. [warning] no-cascading-set-state — packages/scan/src/web/views/notifications/slowdown-history.tsx:59
   3 setState calls in a single useEffect — consider using useReducer or deriving state

174. [warning] async-await-in-loop — packages/scan/tsup.config.ts:20
   await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

175. [warning] async-parallel — packages/scan/tsup.config.ts:144
   3 sequential await statements that appear independent — use Promise.all() for parallel execution

176. [warning] server-fetch-without-revalidate — packages/website/app/api/waitlist/route.ts:38
   fetch("https://app.loops.so/api/v1/contacts/create") in a Server Component / route handler defaults to forever-caching — pass { next: { revalidate: <seconds> } } / { next: { tags: [...] } } / { cache: "no-store" } so stale data doesn't quietly persist

177. [warning] no-unknown-property — packages/website/app/replay/page.tsx:183
   Unknown property found

178. [warning] click-events-have-key-events — packages/website/app/replay/page.tsx:136
   Enforce a clickable non-interactive element has at least one keyboard event listener.

179. [warning] click-events-have-key-events — packages/website/app/replay/page.tsx:162
   Enforce a clickable non-interactive element has at least one keyboard event listener.

180. [warning] click-events-have-key-events — packages/website/app/replay/page.tsx:172
   Enforce a clickable non-interactive element has at least one keyboard event listener.

181. [warning] no-static-element-interactions — packages/website/app/replay/page.tsx:136
   Static HTML elements with event handlers require a role.

182. [warning] no-static-element-interactions — packages/website/app/replay/page.tsx:162
   Static HTML elements with event handlers require a role.

183. [warning] no-static-element-interactions — packages/website/app/replay/page.tsx:172
   Static HTML elements with event handlers require a role.

184. [warning] nextjs-missing-metadata — packages/website/app/replay/page.tsx:1
   Page without metadata or generateMetadata export — hurts SEO

185. [warning] prefer-useReducer — packages/website/app/replay/page.tsx:5
   Component "ReplayPage" has 6 useState calls — consider useReducer for related state

186. [warning] design-no-default-tailwind-palette — packages/website/app/replay/page.tsx:86
   border-gray-200 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

187. [warning] design-no-default-tailwind-palette — packages/website/app/replay/page.tsx:86
   text-gray-900 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

188. [warning] design-no-default-tailwind-palette — packages/website/app/replay/page.tsx:86
   placeholder-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

189. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:99
   w-5 h-5 → use the shorthand size-5 (Tailwind v3.4+)

190. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:111
   w-5 h-5 → use the shorthand size-5 (Tailwind v3.4+)

191. [warning] no-inline-bounce-easing — packages/website/app/replay/page.tsx:115
   animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration

192. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:123
   w-5 h-5 → use the shorthand size-5 (Tailwind v3.4+)

193. [warning] design-no-default-tailwind-palette — packages/website/app/replay/page.tsx:132
   text-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

194. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:148
   w-16 h-16 → use the shorthand size-16 (Tailwind v3.4+)

195. [warning] design-no-default-tailwind-palette — packages/website/app/replay/page.tsx:149
   text-gray-900 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

196. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:149
   w-7 h-7 → use the shorthand size-7 (Tailwind v3.4+)

197. [warning] no-pure-black-background — packages/website/app/replay/page.tsx:201
   Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

198. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:205
   w-7 h-7 → use the shorthand size-7 (Tailwind v3.4+)

199. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:207
   w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

200. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:215
   w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)

201. [warning] design-no-redundant-size-axes — packages/website/app/replay/page.tsx:217
   w-5 h-5 → use the shorthand size-5 (Tailwind v3.4+)

202. [warning] no-pure-black-background — packages/website/app/replay/page.tsx:222
   Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

203. [warning] nextjs-missing-metadata — packages/website/app/page.tsx:1
   Page without metadata or generateMetadata export — hurts SEO

204. [warning] design-no-redundant-size-axes — packages/website/app/page.tsx:36
   w-[18px] h-[18px] → use the shorthand size-[18px] (Tailwind v3.4+)

205. [warning] design-no-redundant-size-axes — packages/website/app/page.tsx:45
   w-[18px] h-[18px] → use the shorthand size-[18px] (Tailwind v3.4+)

206. [warning] no-danger — packages/website/components/install-guide.tsx:260
   Do not use `dangerouslySetInnerHTML` prop

207. [warning] no-danger — packages/website/components/install-guide.tsx:284
   Do not use `dangerouslySetInnerHTML` prop

208. [warning] rendering-svg-precision — packages/website/components/icons/icon-discord.tsx:15
   SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference

209. [warning] design-no-redundant-size-axes — packages/website/components/header.tsx:43
   w-6 h-6 → use the shorthand size-6 (Tailwind v3.4+)

210. [warning] js-tosorted-immutable — packages/website/public/auto.global.js:2
   [...array].sort() — use array.toSorted() for immutable sorting (ES2023)

211. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

212. [warning] client-passive-event-listeners — packages/website/public/auto.global.js:2
   "scroll" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault())

213. [warning] client-passive-event-listeners — packages/website/public/auto.global.js:2
   "scroll" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault())

214. [warning] js-cache-property-access — packages/website/public/auto.global.js:2
   t.contextChanges.set is read 3 times inside this loop — hoist into a const at the top of the loop body

215. [warning] js-cache-property-access — packages/website/public/auto.global.js:2
   n.contextType.toString is read 3 times inside this loop — hoist into a const at the top of the loop body

216. [warning] js-combine-iterations — packages/website/public/auto.global.js:2
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

217. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

218. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

219. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

220. [warning] js-tosorted-immutable — packages/website/public/auto.global.js:2
   [...array].sort() — use array.toSorted() for immutable sorting (ES2023)

221. [warning] async-await-in-loop — packages/website/public/auto.global.js:2
   await inside a for-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

222. [warning] client-passive-event-listeners — packages/website/public/auto.global.js:2
   "scroll" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault())

223. [warning] rerender-transitions-scroll — packages/website/public/auto.global.js:2
   setState in a "scroll" handler triggers re-renders at scroll/pointer frequency — wrap in startTransition (mark as non-urgent), use useDeferredValue, or stash in a ref + rAF throttle

224. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

225. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

226. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

227. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

228. [warning] js-combine-iterations — packages/website/public/auto.global.js:2
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

229. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

230. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

231. [warning] js-flatmap-filter — packages/website/public/auto.global.js:2
   .map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass

232. [warning] js-combine-iterations — packages/website/public/auto.global.js:2
   .filter().forEach() iterates the array twice — combine into a single loop with .reduce() or for...of

233. [warning] js-combine-iterations — packages/website/public/auto.global.js:2
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

234. [warning] js-combine-iterations — packages/website/public/auto.global.js:2
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

235. [warning] js-combine-iterations — packages/website/public/auto.global.js:2
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

236. [warning] js-combine-iterations — packages/website/public/auto.global.js:2
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

237. [warning] client-passive-event-listeners — packages/website/public/auto.global.js:2
   "scroll" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault())

238. [warning] js-set-map-lookups — packages/website/public/auto.global.js:2
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

❌ Errors (10)

Async client component "B" — client components cannot be async · 5 in 1 file

nextjs-async-client-component

Fetch data in a parent Server Component and pass it as props, or use useQuery/useSWR in the client component

File Lines
packages/website/public/auto.global.js 2, 2, 2, 2, 2
useEffect schedules `setTimeout(...)` but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls clearTimeout(...) · 3 in 2 files

effect-needs-cleanup

Return a cleanup function that releases the subscription / timer: return () =&gt; target.removeEventListener(name, handler) for listeners, return () =&gt; clearInterval(id) / clearTimeout(id) for timers, or return unsubscribe if the subscribe call already returned one

File Lines
packages/scan/src/web/views/notifications/slowdown-history.tsx 27, 339
packages/scan/src/web/views/notifications/notifications.tsx 227
Missing "key" prop for element in iterator. · 1 in 1 file

jsx-key

Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).

File Lines
packages/scan/src/web/views/notifications/collapsed-event.tsx 165
"triggerRef.current" in deps — refs are mutable and don't trigger re-renders, so React won't re-run this effect when it changes. Read the ref inside the effect body instead · 1 in 1 file

no-mutable-in-deps

Read mutable values (location.pathname, ref.current) inside the effect body instead of in the deps array, or subscribe with useSyncExternalStore. Mutations to these don't trigger re-renders, so listing them in deps doesn't make the effect react to changes

File Lines
packages/scan/src/web/views/notifications/popover.tsx 73

⚠️ Warnings (228)

Unknown property found · 83 in 4 files

no-unknown-property

Use 'strokeWidth' instead

File Lines
packages/scan/src/web/components/svg-sprite/index.tsx 5, 5, 5, 18, 18, 18, 23, 23, +46 more
packages/scan/src/web/views/notifications/icons.tsx 18, 19, 20, 78, 79, 80, 123, 124, +19 more
packages/scan/src/web/widget/resize-handle.tsx 349
packages/website/app/replay/page.tsx 183
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows · 19 in 5 files

js-batch-dom-css

Batch DOM/CSS reads and writes — interleaving them inside a loop causes layout thrashing. Read first, then write

File Lines
packages/scan/src/core/notifications/outline-overlay.ts 172, 176, 177, 178, 179, 195
packages/scan/src/new-outlines/index.ts 304, 305, 306, 307, 318, 381
packages/scan/src/web/widget/index.tsx 574, 606, 607
packages/extension/src/inject/notification.ts 36, 130
packages/scan/src/web/views/inspector/flash-overlay.ts 64, 68
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups · 17 in 3 files

js-set-map-lookups

Use a Set or Map for repeated membership tests / keyed lookups — Array.includes/find is O(n) per call

File Lines
packages/website/public/auto.global.js 2, 2, 2, 2, 2, 2, 2, 2, +3 more
packages/scan/src/web/views/inspector/utils.ts 1357, 1394, 1446, 1865, 1888
packages/scan/src/core/index.ts 299
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+) · 15 in 4 files

design-no-redundant-size-axes

Collapse w-N h-N to size-N (Tailwind v3.4+) when both axes match

File Lines
packages/website/app/replay/page.tsx 99, 111, 123, 148, 149, 205, 207, 215, +1 more
packages/scan/src/web/views/inspector/components-tree/index.tsx 1072, 1086, 1102
packages/website/app/page.tsx 36, 45
packages/website/components/header.tsx 43
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of · 12 in 4 files

js-combine-iterations

Combine .map().filter() (or similar chains) into a single pass with .reduce() or a for...of loop to avoid iterating the array twice

File Lines
packages/website/public/auto.global.js 2, 2, 2, 2, 2, 2, 2
packages/scan/src/web/views/notifications/notifications.tsx 34, 43, 51
packages/scan/src/web/views/inspector/what-changed.tsx 49
packages/scan/src/web/views/toolbar/index.tsx 194
border-gray-950 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest) · 11 in 3 files

design-no-default-tailwind-palette

Replace indigo-* / gray-* / slate-* with project tokens, your brand color, or a less-default neutral (zinc, neutral, stone)

File Lines
packages/website/app/replay/page.tsx 86, 86, 86, 132, 149
kitchen-sink/src/main.tsx 19, 24, 29
packages/scan/src/web/views/inspector/diff-value.tsx 55, 81, 118
3 setState calls in a single useEffect — consider using useReducer or deriving state · 6 in 5 files

no-cascading-set-state

Combine into useReducer: const [state, dispatch] = useReducer(reducer, initialState)

File Lines
packages/scan/src/web/views/notifications/slowdown-history.tsx 27, 59
kitchen-sink/src/examples/sierpinski/index.tsx 27
packages/scan/src/web/views/notifications/collapsed-event.tsx 36
packages/scan/src/web/views/inspector/what-changed.tsx 36
packages/scan/src/web/views/notifications/popover.tsx 75
Component "ComponentsTree" is 792 lines — consider breaking it into smaller focused components · 5 in 5 files

no-giant-component

Extract logical sections into focused components: &lt;UserHeader /&gt;, &lt;UserActions /&gt;, etc.

File Lines
packages/scan/src/web/views/inspector/components-tree/index.tsx 386
packages/scan/src/web/views/inspector/overlay/index.tsx 48
packages/scan/src/web/widget/resize-handle.tsx 26
packages/scan/src/web/views/notifications/render-bar-chart.tsx 184
packages/scan/src/web/widget/index.tsx 44
"scroll" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault()) · 5 in 2 files

client-passive-event-listeners

Add { passive: true } as the third argument: addEventListener('scroll', handler, { passive: true }). Only do this if the handler does NOT call event.preventDefault() — passive listeners silently ignore preventDefault(), which breaks features like pull-to-refresh suppression, custom gestures, and nested-scroll containment.

File Lines
packages/website/public/auto.global.js 2, 2, 2, 2
packages/scan/src/new-outlines/index.ts 407
Enforce a clickable non-interactive element has at least one keyboard event listener. · 4 in 2 files

click-events-have-key-events

Visible, non-interactive elements with click handlers must have one of keyup, keydown, or keypress listener.

File Lines
packages/website/app/replay/page.tsx 136, 162, 172
kitchen-sink/src/examples/e2e-fixture/index.tsx 46
Static HTML elements with event handlers require a role. · 4 in 2 files

no-static-element-interactions

Add a role attribute to this element, or use a semantic HTML element instead.

File Lines
packages/website/app/replay/page.tsx 136, 162, 172
kitchen-sink/src/examples/e2e-fixture/index.tsx 46
Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950) · 4 in 2 files

no-pure-black-background

Tint the background slightly toward your brand hue — e.g. #0a0a0f or Tailwind's bg-gray-950. Pure black looks harsh on modern displays

File Lines
packages/scan/src/web/toolbar.tsx 22, 27
packages/website/app/replay/page.tsx 201, 222
aggregatedChanges.contextChanges.set is read 3 times inside this loop — hoist into a const at the top of the loop body · 4 in 2 files

js-cache-property-access

Hoist the deep member access into a const at the top of the loop body: const { x, y } = obj.deeply.nested

File Lines
packages/scan/src/web/views/inspector/whats-changed/use-change-store.ts 123, 128
packages/website/public/auto.global.js 2, 2
Date.now() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional · 4 in 2 files

rendering-hydration-mismatch-time

Wrap dynamic time/random values in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

File Lines
packages/scan/src/web/views/notifications/render-bar-chart.tsx 261, 365
packages/scan/src/web/views/notifications/notifications.tsx 441, 464
await inside a while-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently · 3 in 3 files

async-await-in-loop

Collect the items and use await Promise.all(items.map(...)) to run independent operations concurrently

File Lines
packages/scan/src/new-outlines/index.ts 153
packages/scan/tsup.config.ts 20
packages/website/public/auto.global.js 2
.map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass · 3 in 3 files

js-flatmap-filter

Use .flatMap(item =&gt; condition ? [value] : []) — transforms and filters in a single pass instead of creating an intermediate array

File Lines
packages/scan/src/web/views/inspector/timeline/utils.ts 148
packages/scan/src/core/notifications/event-tracking.ts 290
packages/website/public/auto.global.js 2
[...array].sort() — use array.toSorted() for immutable sorting (ES2023) · 3 in 2 files

js-tosorted-immutable

Use array.toSorted() (ES2023) instead of [...array].sort() for immutable sorting without the spread allocation

File Lines
packages/website/public/auto.global.js 2, 2
packages/scan/src/polyfills.ts 4
Array index "index" used as key — causes bugs when list is reordered or filtered · 3 in 3 files

no-array-index-as-key

Use a stable unique identifier: key={item.id} or key={item.slug} — index keys break on reorder/filter

File Lines
packages/scan/src/web/views/inspector/diff-value.tsx 143
packages/scan/src/web/views/inspector/what-changed.tsx 452
packages/scan/src/web/views/notifications/render-bar-chart.tsx 502
setState in a "scroll" handler triggers re-renders at scroll/pointer frequency — wrap in startTransition (mark as non-urgent), use useDeferredValue, or stash in a ref + rAF throttle · 2 in 2 files

rerender-transitions-scroll

Wrap the setState in startTransition (mark as non-urgent), use useDeferredValue, or stash in a ref + rAF throttle so scroll/pointer events don't trigger a re-render per fire

File Lines
packages/scan/src/new-outlines/index.ts 411
packages/website/public/auto.global.js 2
useState(getIsProduction()) calls initializer on every render — use useState(() => getIsProduction()) for lazy initialization · 2 in 2 files

rerender-lazy-state-init

Wrap in an arrow function so it only runs once: useState(() =&gt; expensiveComputation())

File Lines
packages/scan/src/web/views/notifications/render-explanation.tsx 16
packages/scan/src/web/views/notifications/render-bar-chart.tsx 67
Page without metadata or generateMetadata export — hurts SEO · 2 in 2 files

nextjs-missing-metadata

Add export const metadata = { title: '...', description: '...' } or export async function generateMetadata()

File Lines
packages/website/app/replay/page.tsx 1
packages/website/app/page.tsx 1
Do not use `dangerouslySetInnerHTML` prop · 2 in 1 file

no-danger

dangerouslySetInnerHTML is a way to inject HTML into your React component. This is dangerous because it can easily lead to XSS vulnerabilities.

File Lines
packages/website/components/install-guide.tsx 260, 284
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'` · 1 in 1 file

no-react19-deprecated-apis

Pass ref as a regular prop on function components — forwardRef is no longer needed in React 19+. Replace useContext(X) with use(X) for branch-aware context reads. Only enabled on projects detected as React 19+.

File Lines
[`kitchen-sink/sr

Issue body truncated. See the full report at react.review/dashboard.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions