Skip to content

Enable React Compiler for @spatialdata/react and @spatialdata/vis, add scoped ESLint - #73

Merged
xinaesthete merged 5 commits into
mainfrom
claude/compassionate-torvalds-a518a1
Jun 29, 2026
Merged

Enable React Compiler for @spatialdata/react and @spatialdata/vis, add scoped ESLint#73
xinaesthete merged 5 commits into
mainfrom
claude/compassionate-torvalds-a518a1

Conversation

@xinaesthete

@xinaesthete xinaesthete commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What

Enables the React Compiler (babel-plugin-react-compiler 1.0) for the two React-shipping packages — @spatialdata/react and @spatialdata/vis — and adds a narrowly-scoped ESLint setup to surface the Rules-of-React analysis Biome doesn't cover.

Why

The compiler auto-memoizes components/hooks, removing manual useMemo/useCallback churn and reducing re-renders. We're on React 19, so it uses the built-in react/compiler-runtime (no runtime shim). Biome has no equivalent to the compiler's Rules-of-React linting, so a thin ESLint layer gives that feedback without replacing Biome as the primary linter.

Changes

React Compiler wiring

  • @vitejs/plugin-react v6 dropped the old babel option, so the compiler is wired via the plugin's exported reactCompilerPreset() + @rolldown/plugin-babel as a separate plugin.
  • vite.config.base.ts: opt-in reactCompiler flag on defineViteConfig — enabled only for react/vis (the other packages are data/zarr/deck.gl, not React component libs, so they don't pay the cost or carry the dep).
  • Added react/compiler-runtime to the Rollup external list — without it the compiler runtime gets bundled into the published libs (the react bundle ballooned with React internals inlined); externalizing keeps React a single peer dep.
  • packages/vis/vite.config.demo.ts: same wiring for the demo.

Scoped ESLint (Biome stays primary)

  • eslint.config.mjs: flat config running the eslint-plugin-react-hooks v7 recommended ruleset (includes the granular React Compiler diagnostics), scoped to packages/{react,vis}/src.
  • pnpm lint:react script; non-blocking react-lint CI job in test.yml (there's an existing backlog of findings — flip continue-on-error to false once cleared to make it required).

Low-risk lint fixes

  • Tree: resolve the display value before returning JSX so a throw from toJSON() is actually caught (JSX is lazy; the old try/catch around the return never caught render errors). Behavior preserved.
  • SpatialCanvasViewer: documented two intentional granular dep arrays (useLayerData returns a fresh object each render, so depending on layerData would re-run the memo/effect every render).

Tooling

  • .claude/launch.json: vis-demo launch config used to verify the change.

Verification

  • react-compiler-healthcheck: 100% — 3/3 (react) and 30/30 (vis) components compile, no bailouts, no incompatible libraries.
  • Builds + typecheck clean for both packages; react 7/7, vis 39/39 tests pass.
  • Live smoke of the vis demo (compiler-on confirmed in the served bundle: SpatialCanvas compiled with 43 memo slots) against a real Xenium HTJ2K dataset: store parses, image renders via viv/deck.gl, layer auto-selection works, hover tooltips resolve cells correctly — zero console errors (notably no "maximum update depth").

Notes for reviewers

  • Changeset: none added. Enabling the compiler changes the emitted code of the published @spatialdata/react / @spatialdata/vis packages — consider whether a patch changeset is warranted before release.
  • Follow-up: ESLint still reports 19 findings (react-hooks/refs ×10, set-state-in-effect ×9), all in the SpatialCanvas/tooltip hot path — pre-existing, not compiler regressions (the healthcheck still compiles them). These overlap with known hover-tooltip readPixels sluggishness and are tracked for a dedicated pass; the CI job stays non-blocking until then.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added React Compiler support to the React and visualization packages.
    • Added a new React-focused lint check to catch issues in React/TSX code.
    • Added a VS Code debug setup for launching the demo app.
  • Chores

    • Updated workspace and package tooling to support the new React build and lint workflow.
    • Added a CI job to run the React lint check without blocking existing tests.
  • Documentation

    • Clarified a few code comments around rendering behavior and dependency handling.

xinaesthete and others added 3 commits June 29, 2026 17:14
Biome lacks the React Compiler / Rules-of-React analysis, so add a
narrowly-scoped ESLint setup (eslint-plugin-react-hooks v7) that runs only
against the React-shipping packages via `pnpm lint:react`. Biome remains the
primary linter.

- eslint.config.mjs: flat config, react-hooks recommended ruleset, scoped to
  packages/{react,vis}/src.
- package.json: add eslint, eslint-plugin-react-hooks, @typescript-eslint/parser
  devDeps and the lint:react script.
- test.yml: add a non-blocking `react-lint` CI job (existing backlog of
  findings); flip continue-on-error once cleared to make it required.

Fix the low-risk findings:
- Tree: resolve the display value before returning JSX so a throw from
  toJSON() is actually caught (JSX is lazy; try/catch around the return is not).
- SpatialCanvasViewer: document the two intentional granular dep arrays.
  useLayerData returns a fresh object each render, so depending on `layerData`
  would re-run the memo/effect every render; the stable members are the correct
  deps.

The remaining refs / set-state-in-effect findings in the canvas code are left
for the tooltip-performance follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
.claude/launch.json with a `vis-demo` entry (pnpm --filter @spatialdata/vis
dev:demo on port 5173) for previewing the visualization demo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@xinaesthete, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e81c7f6f-6fb0-45a9-94e4-1cb4516f7421

📥 Commits

Reviewing files that changed from the base of the PR and between e6af9c2 and 5eebeca.

📒 Files selected for processing (1)
  • .github/workflows/test.yml
📝 Walkthrough

Walkthrough

The PR integrates the React Compiler via @rolldown/plugin-babel and babel-plugin-react-compiler into the shared Vite base config and per-package configs for packages/react and packages/vis. It also adds an ESLint flat config enforcing react-hooks rules with a non-blocking CI job, adds eslint-disable comments and refactors Tree/index.tsx to comply, and includes a VS Code debug launch config.

Changes

React Compiler Integration and Lint Enforcement

Layer / File(s) Summary
Workspace dependencies
pnpm-workspace.yaml, package.json, packages/react/package.json, packages/vis/package.json
Adds @rolldown/plugin-babel and babel-plugin-react-compiler to the pnpm workspace catalog and to devDependencies in root and both packages; also adds @typescript-eslint/parser, eslint, and eslint-plugin-react-hooks at root.
Shared Vite base config
vite.config.base.ts
Adds a reactCompiler?: boolean option to defineViteConfig; when enabled, conditionally appends the Babel plugin with reactCompilerPreset(); expands Rollup external to include react/compiler-runtime.
Per-package Vite configs
packages/react/vite.config.ts, packages/vis/vite.config.ts, packages/vis/vite.config.demo.ts
Passes reactCompiler: true in packages/react and packages/vis library configs; adds the Babel preset plugin directly to the demo config's plugins array.
ESLint flat config and CI job
eslint.config.mjs, package.json, .github/workflows/test.yml
Introduces eslint.config.mjs targeting TSX files in both packages with @typescript-eslint/parser and eslint-plugin-react-hooks; adds lint:react script; adds a non-blocking react-lint CI job.
Source fixes for lint compliance
packages/vis/src/SpatialCanvas/SpatialCanvasViewer.tsx, packages/vis/src/Tree/index.tsx
Adds eslint-disable-next-line react-hooks/exhaustive-deps with justifying comments in SpatialCanvasViewer.tsx; refactors Tree/index.tsx try/catch to resolve value before rendering rather than returning inside try.
VS Code debug config
.claude/launch.json
Adds a vis-demo debug configuration launching the vis package dev server via pnpm on port 5173.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • Taylor-CCB-Group/SpatialData.js#25: Also modifies vite.config.base.ts Rollup external configuration for React runtime modules, directly adjacent to the react/compiler-runtime addition in this PR.
  • Taylor-CCB-Group/SpatialData.js#32: Touches SpatialCanvasViewer.tsx in the same useSpatialCanvasRendererFromLayerInputs function where this PR adds the exhaustive-deps suppression comments.

Poem

🐇 Hop, hop! The Compiler awakes,
Babel transforms all that it takes.
ESLint watches each hook with care,
try/catch refactored beyond compare.
The bunny lint-checks and then compiles away—
React Compiler ships today! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main changes: enabling React Compiler for the react and vis packages and adding scoped ESLint support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/compassionate-torvalds-a518a1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Job-level continue-on-error kept the overall workflow green but still
reported the react-lint check itself as failed, which trips CI-failure
monitors and reads as a broken required check. Move continue-on-error to
the lint step so the job concludes green while still running eslint;
findings remain visible in the step log. Remove it to make the check a
required gate once the lint backlog is cleared.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/launch.json:
- Around line 4-9: The vis-demo entry in launch.json is not a valid VS Code
debug configuration because it omits the required type/request fields and uses
the wrong schema version. Update the launch configuration to use version 0.2.0
and add an appropriate node-based launch setup for the pnpm command in the
vis-demo entry, including console: "integratedTerminal" if it should run in the
terminal. Remove port 5173 unless this config is explicitly attaching to a
debugger, and if browser debugging is needed, split that into a separate config
rather than keeping it in the same launch profile.

In @.github/workflows/test.yml:
- Around line 16-25: The react-lint job is using broader default token access
and checkout credentials than it needs. Add a minimal permissions block to the
job so it only has read access, and update the actions/checkout step to disable
persisted credentials. Keep the changes scoped to the react-lint job in the
workflow so the job still runs normally while reducing token exposure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b6aff3f8-32ed-4b61-b84b-d6ef090da5c5

📥 Commits

Reviewing files that changed from the base of the PR and between f877503 and e6af9c2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • .claude/launch.json
  • .github/workflows/test.yml
  • eslint.config.mjs
  • package.json
  • packages/react/package.json
  • packages/react/vite.config.ts
  • packages/vis/package.json
  • packages/vis/src/SpatialCanvas/SpatialCanvasViewer.tsx
  • packages/vis/src/Tree/index.tsx
  • packages/vis/vite.config.demo.ts
  • packages/vis/vite.config.ts
  • pnpm-workspace.yaml
  • vite.config.base.ts

Comment thread .claude/launch.json
Comment thread .github/workflows/test.yml
Add a minimal `permissions: contents: read` block and set
`persist-credentials: false` on checkout for the react-lint job, per
CodeRabbit/zizmor review. The lint job only needs read access; this limits
token blast radius and avoids persisting checkout credentials.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xinaesthete
xinaesthete merged commit f973983 into main Jun 29, 2026
3 checks passed
@xinaesthete
xinaesthete deleted the claude/compassionate-torvalds-a518a1 branch June 29, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant