This file is the operating manual for AI coding agents (Cursor, Claude Code, Codex, Aider, Devin, and others) working in this repository. Read this file before making changes.
Human contributors may also find it useful. It is written in direct, imperative style on purpose.
react-virtualized-diff is a React component for rendering large code/text diffs without freezing the browser. The published library lives in packages/react/. The repo is a pnpm workspace monorepo — use pnpm, not npm or yarn.
Public documentation lives in README.md and llms.txt. User-facing API changes must update both.
packages/react/ # published npm package source — this is where most work happens
apps/demo/ # Vite demo app, used for manual testing and the hosted live demo
apps/benchmark/ # benchmark harness that produces benchmark-results/results.md
benchmark-results/ # committed benchmark output, reviewed in PRs when perf changes
.github/workflows/ # CI: runs lint + build
scripts/ # repo-level tooling
The published surface area is exactly what packages/react/ exports. Nothing under apps/ ships to npm.
pnpm install
Node and pnpm are required. Do not run npm install or yarn — it will corrupt the workspace lockfile.
All commands run from the repo root unless noted.
pnpm dev— start the Vite demo app against the local package source (watches and reloads)pnpm build— buildpackages/react/pnpm test— run the test suitepnpm lint— run lint checkspnpm benchmark— run the benchmark harness; updatesbenchmark-results/results.md
All of these must pass locally:
pnpm lintis cleanpnpm buildsucceedspnpm testpassesCHANGELOG.mdhas an entry for the change
CI also runs pnpm lint and pnpm build. Tests and CHANGELOG are checked by reviewers.
These are in priority order. If they conflict, earlier rules win.
-
Default scope is
packages/react/. Make changes here unless there is a direct reason not to. If a change requires touchingapps/demo/,apps/benchmark/, or repo-level config, call that out explicitly in the PR description and explain why. -
Public API changes must update
README.mdandllms.txt. The list of props in both files is part of the public contract. Renaming a prop, changing a default, adding a prop, or removing a prop requires updating both docs in the same PR.llms.txtis how AI coding agents in downstream projects learn this library — keeping it accurate is load-bearing. -
Performance-sensitive changes require a benchmark comparison. "Performance-sensitive" includes anything in the render path, diff computation, virtual list integration, or memoization boundaries. Run
pnpm benchmarkonmainfirst, then on your branch, and paste both relevant rows into the PR description. Do not rely on the committedresults.mdalone — it is a snapshot and may be stale. -
Every change gets a
CHANGELOG.mdentry. Even small fixes. Use the existing format in that file. Entries do not need to be long — one sentence is fine — but they must exist.
- TypeScript throughout. Strict mode is on — do not introduce
anyto silence type errors. If a type is genuinely unknowable, useunknownand narrow. - Formatting is controlled by
.prettierrcand.editorconfig. Do not hand-adjust whitespace; run the formatter. - Prefer named exports from
packages/react/entry points. - React hooks follow standard rules (exhaustive deps unless justified with a comment).
- Do not commit
dist/or other build output..gitignorecovers this; double-check before pushing. - Do not hand-edit
pnpm-lock.yaml. If a dependency needs to change, usepnpm add/pnpm removeand commit the lockfile update. - Do not add new runtime dependencies without flagging the addition in the PR description. Bundle size is part of the library's value.
- Do not bump the version in any
package.json. Releases are managed separately. - Do not modify
benchmark-results/results.mdby hand — it is generated bypnpm benchmark. - Do not rewrite the "Why react-virtualized-diff" section of
README.mdor the framing of the benchmark without reviewer discussion. Those sections reflect the project's positioning.
Open a draft PR with a clear description of what you tried and why. The maintainer (@Zhang-JiahangH) would rather see an honest draft than a polished PR that made the wrong call.