aidenybai / aidenybai/element-source

React Review Audit

Open
#2 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
448
Forks
11
PR merge metrics
No merged PRs in 30d

Description

**Score: 96/100** · 1 error · 68 warnings

Copy as prompt

```text
Fix the following React Review diagnostics in my codebase.

## Errors (1)

1. [error] require-reduced-motion — packages/website/package.json:0
Project uses a motion library but has no prefers-reduced-motion handling — required for accessibility (WCAG 2.3.3)

## Warnings (68)

2. [warning] no-inline-exhaustive-style — examples/astro/src/components/react/inspector-overlay.tsx:41
9 inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse

3. [warning] no-unknown-property — examples/astro/src/components/solid/solid-card.tsx:14
Unknown property found

4. [warning] advanced-event-handler-refs — examples/nextjs/app/components/inspector-overlay.tsx:40
useEffect re-subscribes a "handleDocumentClick" listener every time the handler identity changes — store the handler in a ref and have the listener read `handlerRef.current()`, then drop it from the deps

5. [warning] no-inline-exhaustive-style — examples/nextjs/app/components/inspector-overlay.tsx:73
9 inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse

6. [warning] async-await-in-loop — examples/nextjs/out/_next/static/chunks/app/layout-e16f6df1afef6fe5.js:1
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

7. [warning] async-await-in-loop — examples/nextjs/out/_next/static/chunks/app/layout-e16f6df1afef6fe5.js:1
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

8. [warning] js-set-map-lookups — examples/nextjs/out/_next/static/chunks/webpack-d7602772852bf587.js:1
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

9. [warning] js-set-map-lookups — examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

10. [warning] js-set-map-lookups — examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

11. [warning] js-set-map-lookups — examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

12. [warning] js-set-map-lookups — examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

13. [warning] js-cache-property-access — examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1
n.memoizedProps.revealOrder is read 4 times inside this loop — hoist into a const at the top of the loop body

14. [warning] js-cache-property-access — examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1
t.style.display is read 3 times inside this loop — hoist into a const at the top of the loop body

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

16. [warning] no-unknown-property — examples/opentui/src/app.tsx:5
Unknown property found

17. [warning] no-unknown-property — examples/opentui/src/app.tsx:6
Unknown property found

18. [warning] no-unknown-property — examples/opentui/src/sample-card.tsx:17
Unknown property found

19. [warning] no-inline-exhaustive-style — examples/react-router/src/components/inspector-overlay.tsx:41
9 inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse

20. [warning] js-set-map-lookups — examples/remix/build/server/index.js:255
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

21. [warning] js-combine-iterations — examples/remix/build/server/index.js:584
.map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

22. [warning] js-set-map-lookups — examples/remix/build/server/index.js:671
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

23. [warning] async-await-in-loop — examples/remix/build/server/index.js:680
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

24. [warning] js-set-map-lookups — examples/remix/build/server/index.js:682
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

25. [warning] async-await-in-loop — examples/remix/build/server/index.js:802
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

26. [warning] no-inline-exhaustive-style — examples/remix/app/components/inspector-overlay.tsx:44
9 inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse

27. [warning] no-children-prop — examples/remix/build/client/assets/components-BYiSABuR.js:28
Avoid passing children using a prop.

28. [warning] no-children-prop — examples/remix/build/client/assets/components-BYiSABuR.js:28
Avoid passing children using a prop.

29. [warning] no-children-prop — examples/remix/build/client/assets/components-BYiSABuR.js:28
Avoid passing children using a prop.

30. [warning] no-children-prop — examples/remix/build/client/assets/components-BYiSABuR.js:28
Avoid passing children using a prop.

31. [warning] no-children-prop — examples/remix/build/client/assets/components-BYiSABuR.js:28
Avoid passing children using a prop.

32. [warning] no-children-prop — examples/remix/build/client/assets/components-BYiSABuR.js:28
Avoid passing children using a prop.

33. [warning] no-children-prop — examples/remix/build/client/assets/components-BYiSABuR.js:176
Avoid passing children using a prop.

34. [warning] no-danger — examples/remix/build/client/assets/components-BYiSABuR.js:125
Do not use `dangerouslySetInnerHTML` prop

35. [warning] no-danger — examples/remix/build/client/assets/components-BYiSABuR.js:138
Do not use `dangerouslySetInnerHTML` prop

36. [warning] no-danger — examples/remix/build/client/assets/components-BYiSABuR.js:163
Do not use `dangerouslySetInnerHTML` prop

37. [warning] no-danger — examples/remix/build/client/assets/components-BYiSABuR.js:165
Do not use `dangerouslySetInnerHTML` prop

38. [warning] advanced-event-handler-refs — examples/tanstack-start/src/components/inspector-overlay.tsx:38
useEffect re-subscribes a "handleDocumentClick" listener every time the handler identity changes — store the handler in a ref and have the listener read `handlerRef.current()`, then drop it from the deps

39. [warning] no-inline-exhaustive-style — examples/tanstack-start/src/components/inspector-overlay.tsx:71
9 inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse

40. [warning] html-has-lang — examples/tanstack-start/src/routes/__root.tsx:9
Missing lang attribute.

41. [warning] no-inline-exhaustive-style — examples/vite-react/src/inspector-overlay.tsx:41
9 inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse

42. [warning] no-inline-exhaustive-style — examples/webpack-react/src/inspector-overlay.tsx:41
9 inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse

43. [warning] js-flatmap-filter — packages/element-source/tests/frameworks/vue.test.ts:59
.map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass

44. [warning] js-combine-iterations — packages/element-source/src/frameworks/vue.ts:64
.map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

45. [warning] no-flush-sync — packages/element-source/tests/frameworks/react.test.ts:5
flushSync from react-dom skips View Transition snapshots and concurrent rendering — prefer startTransition for non-urgent updates

46. [warning] async-await-in-loop — packages/element-source/src/resolve.ts:27
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

47. [warning] no-flush-sync — packages/element-source/tests/resolve.test.ts:5
flushSync from react-dom skips View Transition snapshots and concurrent rendering — prefer startTransition for non-urgent updates

48. [warning] js-set-map-lookups — packages/element-source/src/frameworks/solid.ts:77
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

49. [warning] async-await-in-loop — packages/element-source/src/frameworks/solid.ts:87
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

50. [warning] js-set-map-lookups — packages/element-source/src/frameworks/solid.ts:89
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

51. [warning] js-set-map-lookups — packages/element-source/src/frameworks/react.ts:130
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

52. [warning] js-combine-iterations — packages/element-source/src/utils/merge-stack-context.ts:4
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

53. [warning] js-combine-iterations — packages/element-source/src/utils/merge-stack-context.ts:4
.map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

54. [warning] no-flush-sync — packages/element-source/tests/frameworks/capacitor.test.ts:5
flushSync from react-dom skips View Transition snapshots and concurrent rendering — prefer startTransition for non-urgent updates

55. [warning] click-events-have-key-events — packages/website/components/hero-demo.tsx:109
Enforce a clickable non-interactive element has at least one keyboard event listener.

56. [warning] click-events-have-key-events — packages/website/components/hero-demo.tsx:121
Enforce a clickable non-interactive element has at least one keyboard event listener.

57. [warning] no-static-element-interactions — packages/website/components/hero-demo.tsx:109
Static HTML elements with event handlers require a role.

58. [warning] no-static-element-interactions — packages/website/components/hero-demo.tsx:121
Static HTML elements with event handlers require a role.

59. [warning] use-lazy-motion — packages/website/components/hero-demo.tsx:4
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size

60. [warning] rerender-state-only-in-handlers — packages/website/components/hero-demo.tsx:67
useState "paused" is updated but never read in the component's return — use useRef so updates don't trigger re-renders

61. [warning] use-lazy-motion — packages/website/hooks/use-sliding-highlight.tsx:4
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size

62. [warning] no-react19-deprecated-apis — packages/website/hooks/use-sliding-highlight.tsx:102
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`

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

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

65. [warning] rerender-state-only-in-handlers — packages/website/components/copy-button.tsx:12
useState "copied" is updated but never read in the component's return — use useRef so updates don't trigger re-renders

66. [warning] no-react19-deprecated-apis — packages/website/providers/site-provider.tsx:3
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`

67. [warning] no-react19-deprecated-apis — packages/website/components/ui/tabs.tsx:86
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`

68. [warning] no-danger — packages/website/app/page.tsx:31
Do not use `dangerouslySetInnerHTML` prop

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

---

### ❌ Errors (1)

**`require-reduced-motion`**

Project uses a motion library but has no prefers-reduced-motion handling — required for accessibility (WCAG 2.3.3)

> Add `useReducedMotion()` from your animation library, or a `@media (prefers-reduced-motion: reduce)` CSS query

[`packages/website/package.json:0`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/package.json#L0)

---

### ⚠️ Warnings (68)

**`js-set-map-lookups`**

array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

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

[`examples/nextjs/out/_next/static/chunks/webpack-d7602772852bf587.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/webpack-d7602772852bf587.js#L1)
[`examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js#L1)
[`examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js#L1)
[`examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js#L1)
[`examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js#L1)
[`examples/remix/build/server/index.js:255`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/server/index.js#L255)
[`examples/remix/build/server/index.js:671`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/server/index.js#L671)
[`examples/remix/build/server/index.js:682`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/server/index.js#L682)
[`packages/element-source/src/frameworks/solid.ts:77`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/src/frameworks/solid.ts#L77)
[`packages/element-source/src/frameworks/solid.ts:89`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/src/frameworks/solid.ts#L89)
[`packages/element-source/src/frameworks/react.ts:130`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/src/frameworks/react.ts#L130)

**`no-inline-exhaustive-style`**

9 inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse

> Move styles to a CSS class, CSS module, Tailwind utilities, or a styled component — inline objects with many properties hurt readability and create new references every render

[`examples/astro/src/components/react/inspector-overlay.tsx:41`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/astro/src/components/react/inspector-overlay.tsx#L41)
[`examples/nextjs/app/components/inspector-overlay.tsx:73`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/app/components/inspector-overlay.tsx#L73)
[`examples/react-router/src/components/inspector-overlay.tsx:41`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/react-router/src/components/inspector-overlay.tsx#L41)
[`examples/remix/app/components/inspector-overlay.tsx:44`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/app/components/inspector-overlay.tsx#L44)
[`examples/tanstack-start/src/components/inspector-overlay.tsx:71`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/tanstack-start/src/components/inspector-overlay.tsx#L71)
[`examples/vite-react/src/inspector-overlay.tsx:41`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/vite-react/src/inspector-overlay.tsx#L41)
[`examples/webpack-react/src/inspector-overlay.tsx:41`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/webpack-react/src/inspector-overlay.tsx#L41)

**`no-children-prop`**

Avoid passing children using a prop.

> The canonical way to pass children in React is to use JSX elements

[`examples/remix/build/client/assets/components-BYiSABuR.js:28`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L28)
[`examples/remix/build/client/assets/components-BYiSABuR.js:28`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L28)
[`examples/remix/build/client/assets/components-BYiSABuR.js:28`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L28)
[`examples/remix/build/client/assets/components-BYiSABuR.js:28`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L28)
[`examples/remix/build/client/assets/components-BYiSABuR.js:28`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L28)
[`examples/remix/build/client/assets/components-BYiSABuR.js:28`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L28)
[`examples/remix/build/client/assets/components-BYiSABuR.js:176`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L176)

**`async-await-in-loop`**

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

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

[`examples/nextjs/out/_next/static/chunks/app/layout-e16f6df1afef6fe5.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/app/layout-e16f6df1afef6fe5.js#L1)
[`examples/nextjs/out/_next/static/chunks/app/layout-e16f6df1afef6fe5.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/app/layout-e16f6df1afef6fe5.js#L1)
[`examples/remix/build/server/index.js:680`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/server/index.js#L680)
[`examples/remix/build/server/index.js:802`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/server/index.js#L802)
[`packages/element-source/src/resolve.ts:27`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/src/resolve.ts#L27)
[`packages/element-source/src/frameworks/solid.ts:87`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/src/frameworks/solid.ts#L87)

**`no-danger`**

Do not use `dangerouslySetInnerHTML` prop

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

[`examples/remix/build/client/assets/components-BYiSABuR.js:125`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L125)
[`examples/remix/build/client/assets/components-BYiSABuR.js:138`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L138)
[`examples/remix/build/client/assets/components-BYiSABuR.js:163`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L163)
[`examples/remix/build/client/assets/components-BYiSABuR.js:165`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/client/assets/components-BYiSABuR.js#L165)
[`packages/website/app/page.tsx:31`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/app/page.tsx#L31)

**`no-unknown-property`**

Unknown property found

> Use 'onClick' instead

[`examples/astro/src/components/solid/solid-card.tsx:14`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/astro/src/components/solid/solid-card.tsx#L14)
[`examples/opentui/src/app.tsx:5`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/opentui/src/app.tsx#L5)
[`examples/opentui/src/app.tsx:6`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/opentui/src/app.tsx#L6)
[`examples/opentui/src/sample-card.tsx:17`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/opentui/src/sample-card.tsx#L17)

**`js-combine-iterations`**

.map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

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

[`examples/remix/build/server/index.js:584`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/remix/build/server/index.js#L584)
[`packages/element-source/src/frameworks/vue.ts:64`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/src/frameworks/vue.ts#L64)
[`packages/element-source/src/utils/merge-stack-context.ts:4`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/src/utils/merge-stack-context.ts#L4)
[`packages/element-source/src/utils/merge-stack-context.ts:4`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/src/utils/merge-stack-context.ts#L4)

**`no-flush-sync`**

flushSync from react-dom skips View Transition snapshots and concurrent rendering — prefer startTransition for non-urgent updates

> Use startTransition for non-urgent updates — flushSync forces a sync flush that skips View Transitions and concurrent rendering

[`packages/element-source/tests/frameworks/react.test.ts:5`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/tests/frameworks/react.test.ts#L5)
[`packages/element-source/tests/resolve.test.ts:5`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/tests/resolve.test.ts#L5)
[`packages/element-source/tests/frameworks/capacitor.test.ts:5`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/tests/frameworks/capacitor.test.ts#L5)

**`no-react19-deprecated-apis`**

useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`

> 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+.

[`packages/website/hooks/use-sliding-highlight.tsx:102`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/hooks/use-sliding-highlight.tsx#L102)
[`packages/website/providers/site-provider.tsx:3`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/providers/site-provider.tsx#L3)
[`packages/website/components/ui/tabs.tsx:86`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/ui/tabs.tsx#L86)

**`advanced-event-handler-refs`**

useEffect re-subscribes a "handleDocumentClick" listener every time the handler identity changes — store the handler in a ref and have the listener read `handlerRef.current()`, then drop it from the deps

> Store the handler in a ref and have the listener read `handlerRef.current()` — the subscription stays put while the latest handler is always called

[`examples/nextjs/app/components/inspector-overlay.tsx:40`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/app/components/inspector-overlay.tsx#L40)
[`examples/tanstack-start/src/components/inspector-overlay.tsx:38`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/tanstack-start/src/components/inspector-overlay.tsx#L38)

**`js-cache-property-access`**

n.memoizedProps.revealOrder is read 4 times inside this loop — hoist into a const at the top of the loop body

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

[`examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js#L1)
[`examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/out/_next/static/chunks/8e6518bb-ac69cad76942bec4.js#L1)

**`nextjs-missing-metadata`**

Page without metadata or generateMetadata export — hurts SEO

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

[`examples/nextjs/app/page.tsx:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/nextjs/app/page.tsx#L1)
[`packages/website/app/page.tsx:1`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/app/page.tsx#L1)

**`click-events-have-key-events`**

Enforce a clickable non-interactive element has at least one keyboard event listener.

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

[`packages/website/components/hero-demo.tsx:109`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/hero-demo.tsx#L109)
[`packages/website/components/hero-demo.tsx:121`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/hero-demo.tsx#L121)

**`no-static-element-interactions`**

Static HTML elements with event handlers require a role.

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

[`packages/website/components/hero-demo.tsx:109`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/hero-demo.tsx#L109)
[`packages/website/components/hero-demo.tsx:121`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/hero-demo.tsx#L121)

**`use-lazy-motion`**

Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size

> Use `import { LazyMotion, m } from "framer-motion"` with `domAnimation` features — saves ~30kb

[`packages/website/components/hero-demo.tsx:4`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/hero-demo.tsx#L4)
[`packages/website/hooks/use-sliding-highlight.tsx:4`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/hooks/use-sliding-highlight.tsx#L4)

**`rerender-state-only-in-handlers`**

useState "paused" is updated but never read in the component's return — use useRef so updates don't trigger re-renders

> Replace useState with useRef when the value is only mutated and never read in render — `ref.current = ...` updates without re-rendering the component

[`packages/website/components/hero-demo.tsx:67`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/hero-demo.tsx#L67)
[`packages/website/components/copy-button.tsx:12`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/copy-button.tsx#L12)

**`rendering-svg-precision`**

SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference

> Truncate path/points/transform decimals to 1–2 digits — sub-pixel precision adds bytes with no visible difference

[`packages/website/components/icons/logo-icon.tsx:13`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/icons/logo-icon.tsx#L13)
[`packages/website/components/icons/logo-icon.tsx:20`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/website/components/icons/logo-icon.tsx#L20)

**`html-has-lang`**

Missing lang attribute.

> Add a `lang` attribute to the `html` element whose value represents the primary language of document.

[`examples/tanstack-start/src/routes/__root.tsx:9`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/examples/tanstack-start/src/routes/__root.tsx#L9)

**`js-flatmap-filter`**

.map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass

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

[`packages/element-source/tests/frameworks/vue.test.ts:59`](https://github.com/aidenybai/element-source/blob/ff11ad2a3c6131e2b4ce569c1911b6bcb1eeb582/packages/element-source/tests/frameworks/vue.test.ts#L59)

---

Last scored May 18, 2026 at 10:18 AM UTC. Maintained by [React Review](https://github.com/millionco/react-review).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.