|
1 | 1 | # react-virtualized-diff |
2 | 2 |
|
3 | | -React virtualized diff viewer for large text/code files. |
| 3 | +A high-performance, virtualized React diff viewer designed for **very large text files** and smooth developer experience. |
4 | 4 |
|
5 | | -> This package is part of the `virtualized-diff-viewer` monorepo. |
| 5 | +> Package name on npm: **`react-virtualized-diff`** |
6 | 6 |
|
7 | | -## Install |
| 7 | +--- |
| 8 | + |
| 9 | +## Why this project |
| 10 | + |
| 11 | +Most diff viewers are good for small files but become slow when input grows to tens of thousands of lines. |
| 12 | + |
| 13 | +`react-virtualized-diff` focuses on: |
| 14 | + |
| 15 | +- **Performance first** rendering with virtualization |
| 16 | +- **Readable side-by-side UI** for code/text review |
| 17 | +- **Configurable context lines** around changes |
| 18 | +- **TypeScript support** for reliable integration |
| 19 | +- **Simple React API** for quick adoption |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +## Features |
| 24 | + |
| 25 | +- ✅ Side-by-side diff layout |
| 26 | +- ✅ Virtualized row rendering (good for large files) |
| 27 | +- ✅ Collapsed unchanged blocks with configurable context |
| 28 | +- ✅ Lightweight integration in React apps |
| 29 | +- ✅ TypeScript declarations out of the box |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +## Installation |
8 | 34 |
|
9 | 35 | ```bash |
| 36 | +# pnpm |
| 37 | +pnpm add react-virtualized-diff |
| 38 | + |
| 39 | +# npm |
10 | 40 | npm install react-virtualized-diff |
| 41 | + |
| 42 | +# yarn |
| 43 | +yarn add react-virtualized-diff |
11 | 44 | ``` |
12 | 45 |
|
13 | | -## Usage |
| 46 | +--- |
| 47 | + |
| 48 | +## Quick start |
14 | 49 |
|
15 | 50 | ```tsx |
16 | 51 | import { DiffViewer } from 'react-virtualized-diff'; |
17 | 52 |
|
18 | | -<DiffViewer original={oldText} modified={newText} contextLines={2} height={500} />; |
| 53 | +const oldText = `line 1\nline 2\nline 3`; |
| 54 | +const newText = `line 1\nline 2 changed\nline 3\nline 4`; |
| 55 | + |
| 56 | +export function Example() { |
| 57 | + return ( |
| 58 | + <DiffViewer |
| 59 | + original={oldText} |
| 60 | + modified={newText} |
| 61 | + contextLines={2} |
| 62 | + height={480} |
| 63 | + /> |
| 64 | + ); |
| 65 | +} |
19 | 66 | ``` |
20 | 67 |
|
21 | | -## Props |
| 68 | +--- |
| 69 | + |
| 70 | +## API (current) |
| 71 | + |
| 72 | +### `DiffViewer` props |
| 73 | + |
| 74 | +- `original: string` – original text content |
| 75 | +- `modified: string` – modified text content |
| 76 | +- `contextLines?: number` – unchanged lines to keep around changes (default behavior from component) |
| 77 | +- `height?: number | string` – viewport height for virtualization container |
| 78 | + |
| 79 | +> Tip: for best performance with huge files, keep rendering area constrained with a fixed `height`. |
| 80 | +
|
| 81 | +--- |
| 82 | + |
| 83 | +## Benchmark suite |
| 84 | + |
| 85 | +A runnable benchmark harness is included to compare: |
| 86 | + |
| 87 | +- `react-virtualized-diff` (this project) |
| 88 | +- `react-diff-viewer` |
| 89 | +- `react-diff-viewer-continued` |
| 90 | +- `react-diff-view` |
| 91 | + |
| 92 | +Metrics collected for each dataset size (`1k / 10k / 50k / 100k` lines): |
| 93 | + |
| 94 | +- FPS (average during auto-scroll) |
| 95 | +- Initial render time (ms) |
| 96 | +- Memory usage (`usedJSHeapSize` in Chromium) |
| 97 | +- Per benchmark case timeout: `60000 ms` (timeout cases are recorded in results instead of failing the run) |
| 98 | + |
| 99 | +Quick result highlights (from the latest run): |
| 100 | + |
| 101 | +- At **10k lines**, `react-virtualized-diff` keeps ~**60 FPS**, with **187.2 ms** initial render and **9.5 MB** memory. |
| 102 | +- At **50k/100k lines**, `react-diff-viewer` and `react-diff-viewer-continued` hit timeout, while this project finishes both cases. |
| 103 | +- At **100k lines**, this project uses **141.1 MB** memory vs `react-diff-view` at **1297.0 MB** (~9.2x lower), and keeps **60.4 FPS** vs **5.6 FPS**. |
| 104 | + |
| 105 | +Run: |
| 106 | + |
| 107 | +```bash |
| 108 | +pnpm install |
| 109 | +pnpm benchmark |
| 110 | +``` |
| 111 | + |
| 112 | +> If Playwright Chromium is missing, the script will auto-run `pnpm exec playwright install chromium` once. |
| 113 | +
|
| 114 | +> `react-diff-viewer-continued` is optional in the benchmark app. If missing locally, benchmark falls back to `react-diff-viewer` for that case. |
| 115 | +
|
| 116 | +Output files: |
| 117 | + |
| 118 | +- `benchmark-results/results.json` |
| 119 | +- `benchmark-results/results.md` |
| 120 | + |
| 121 | +➡️ See detailed benchmark table: [benchmark-results/results.md](./benchmark-results/results.md) |
| 122 | + |
| 123 | +## Monorepo structure |
| 124 | + |
| 125 | +```text |
| 126 | +apps/demo/ # Vite demo app |
| 127 | +packages/react/ # npm package: react-virtualized-diff |
| 128 | +``` |
| 129 | + |
| 130 | +--- |
| 131 | + |
| 132 | +## Local development |
| 133 | + |
| 134 | +```bash |
| 135 | +pnpm install |
| 136 | +pnpm dev # run demo app |
| 137 | +pnpm build # build workspace packages |
| 138 | +``` |
| 139 | + |
| 140 | +--- |
| 141 | + |
| 142 | +## npm package README support |
| 143 | + |
| 144 | +To ensure npm users always see correct documentation: |
| 145 | + |
| 146 | +- Package-level README is maintained at `packages/react/README.md` |
| 147 | +- `packages/react/package.json` includes README in publish files |
| 148 | +- Root README links to the package docs and Chinese docs |
| 149 | + |
| 150 | +--- |
| 151 | + |
| 152 | +## Release log |
| 153 | + |
| 154 | +See [CHANGELOG.md](https://github.com/Zhang-JiahangH/virtualized-diff-viewer/blob/main/benchmark-results/results.md) for tracked releases and supported capabilities. |
| 155 | + |
| 156 | +--- |
| 157 | + |
| 158 | +## Future plan |
| 159 | + |
| 160 | +### Near-term roadmap |
| 161 | + |
| 162 | +- [ ] Optional syntax highlighting (performance-aware) |
| 163 | +- [ ] More comprehensive live demo scenarios (big files, mixed edits) |
| 164 | +- [ ] Public hosted demo site for quick evaluation |
| 165 | +- [ ] Better customization hooks (line renderers, gutters) |
| 166 | + |
| 167 | +### Additional TODOs to make this project more popular |
| 168 | + |
| 169 | +- [x] Detailed benchmark report vs common diff viewers |
| 170 | +- [ ] Keyboard navigation + accessibility improvements |
| 171 | +- [ ] Dark/light theme presets and design tokens |
| 172 | +- [ ] SSR usage guide (Next.js / Remix examples) |
| 173 | +- [ ] More real-world examples (JSON, logs, markdown, code) |
| 174 | +- [ ] CI release automation + semantic versioning workflow |
| 175 | +- [ ] Contribution guide and issue templates |
| 176 | +- [ ] International docs beyond English/Chinese |
22 | 177 |
|
23 | | -- `original: string` |
24 | | -- `modified: string` |
25 | | -- `contextLines?: number` |
26 | | -- `height?: number | string` |
| 178 | +--- |
27 | 179 |
|
28 | | -## Links |
| 180 | +## License |
29 | 181 |
|
30 | | -- Repository README: `../../README.md` |
31 | | -- Chinese README: `../../README.zh-CN.md` |
32 | | -- Changelog: `../../CHANGELOG.md` |
| 182 | +MIT |
0 commit comments