https://github.com/MrWangJustToDo/git-diff-view
A Diff View component for React / Vue / Solid / Svelte / Ink, just like Github
https://github.com/MrWangJustToDo/git-diff-view
cli-component diff diff-component diff-view diff-viewer file-diff git-diff github-diff react-diff-component solid-diff-component svelte-diff-component two-file-diff vue-diff-component
Last synced: 4 months ago
JSON representation
A Diff View component for React / Vue / Solid / Svelte / Ink, just like Github
- Host: GitHub
- URL: https://github.com/MrWangJustToDo/git-diff-view
- Owner: MrWangJustToDo
- License: mit
- Created: 2024-01-15T12:17:00.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-08-24T15:11:13.000Z (5 months ago)
- Last Synced: 2025-08-24T19:36:09.708Z (5 months ago)
- Topics: cli-component, diff, diff-component, diff-view, diff-viewer, file-diff, git-diff, github-diff, react-diff-component, solid-diff-component, svelte-diff-component, two-file-diff, vue-diff-component
- Language: TypeScript
- Homepage: https://mrwangjusttodo.github.io/git-diff-view/
- Size: 6.31 MB
- Stars: 488
- Watchers: 6
- Forks: 20
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Git Diff Component
A Diff view component for React / Vue / Solid / Svelte,
The most one component what easy to use and feature complete.
[](https://github.com/MrWangJustToDo/git-diff-view/actions/workflows/deploy.yml)


## Demo ---- git-diff / file-diff
[git-mode](https://mrwangjusttodo.github.io/git-diff-view/?type=try&tab=git)

[file-mode](https://mrwangjusttodo.github.io/git-diff-view/?type=try&tab=file)

[GitHub compare](https://mrwangjusttodo.github.io/MrWangJustToDo.io?overlay=open&playGround=GitHub)

## How to use (React / Vue / Solid / Svelte)
See example project [Example](https://github.com/MrWangJustToDo/git-diff-view/tree/main/ui)
## Packages
| Package | Version |
| :--------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
| [`@git-diff-view/core`](packages/core) | [](https://www.npmjs.com/package/@git-diff-view/core) |
| [`@git-diff-view/file`](packages/file) | [](https://www.npmjs.com/package/@git-diff-view/file) |
| [`@git-diff-view/react`](packages/react) | [](https://www.npmjs.com/package/@git-diff-view/react) |
| [`@git-diff-view/vue`](packages/vue) | [](https://www.npmjs.com/package/@git-diff-view/vue) |
| [`@git-diff-view/solid`](packages/solid) | [](https://www.npmjs.com/package/@git-diff-view/solid) |
| [`@git-diff-view/svelte`](packages/svelte)|[](https://www.npmjs.com/package/@git-diff-view/svelte)|
| [`@git-diff-view/cli`](packages/cli) | [](https://www.npmjs.com/package/@git-diff-view/cli) |
### syntax highlighter
| Package | Version |
| :-------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- |
| [`@git-diff-view/lowlight`](packages/lowlight) `build in` | [](https://www.npmjs.com/package/@git-diff-view/lowlight) |
| [`@git-diff-view/shiki`](packages/shiki) | [](https://www.npmjs.com/package/@git-diff-view/shiki) |
## Screen Shot





### Template mode
For better performance and customization, now the `DiffView` component support `template mode`, and it's the default setting. SEE [Template Mode](https://github.com/MrWangJustToDo/git-diff-view/blob/main/packages/core/src/parse/template.ts)
### FastDiff template
Using the `template mode`, the `DiffView` component can utilize the `fast-diff` package to generate diffLine templates for better readability of differences. SEE [FastDiffTemplate](https://github.com/MrWangJustToDo/git-diff-view/blob/main/packages/core/src/parse/template.ts)
#### Default diffLine

#### FastDiff diffLine

#### How to enable FastDiff template
```ts
import { setEnableFastDiffTemplate } from '@git-diff-view/core' // or react/vue runtime package
// experimental feature, use with caution
setEnableFastDiffTemplate(true);
```
## Features
+ [x] Show the `git diff` result
+ [x] Support `Split View` and `Unified View`
+ [x] Support `Warp` / `UnWarp` the code line
+ [x] Support `light` / `dark` theme by default (since v0.0.17)
+ [x] Support `Syntax Highlight` with `full syntax context` (base on `hast` AST)
+ [x] Support `Extend Data` component in the `Diff View`
+ [x] Support `Widget` component in the `Diff View`
+ [x] Support `Web Worker` / `Node Server` to improve performance
+ [x] Support `React` and `Vue` component
+ [x] Support compare by `@git-diff-view/core`(git diff) or `@git-diff-view/file`(file content)
+ [x] Support `Diff Match Patch` to improve line diff (experimental)
+ [x] Support `SSR` for `React` and `Vue` component (since v0.0.21)
+ [x] Support `RSC` for `React` component (since v0.0.21)
+ [x] More Render Platform: `Solid` / `Svelte` / `Cli`
+ [ ] Support `Virtual Scroll` to improve performance
## Install
```shell
# In React Project
pnpm add @git-diff-view/react
# In Vue Project
pnpm add @git-diff-view/vue
```
## Use in React
#### There are two ways to use this component:
#### 1. Use the `DiffView` component directly.
```tsx
import { DiffView, DiffModeEnum } from "@git-diff-view/react";
import "@git-diff-view/react/styles/diff-view.css";
// if you have your own tailwindcss config, you can use the `diff-view-pure.css` to avoid CSS conflicts
import "@git-diff-view/react/styles/diff-view-pure.css";
// use data
data={{
oldFile?: { fileName?: string | null; fileLang?: string | null; content?: string | null };
newFile?: { fileName?: string | null; fileLang?: string | null; content?: string | null };
hunks: string[];
}}
extendData={{oldFile: {10: {data: 'foo'}}, newFile: {20: {data: 'bar'}}}}
renderExtendLine={({ data }) => ReactNode}
diffViewFontSize={number}
diffViewHighlight={boolean}
diffViewMode={DiffModeEnum.Split | DiffModeEnum.Unified}
diffViewWrap={boolean}
diffViewTheme={'light' | 'dark'}
diffViewAddWidget
onAddWidgetClick={({ side, lineNumber }) => void}
renderWidgetLine={({ onClose, side, lineNumber }) => ReactNode}
/>
```
#### 2. Use the `DiffView` component with `@git-diff-view/core` or `@git-diff-view/file`
```tsx
// with @git-diff-view/file
import { DiffFile, generateDiffFile } from "@git-diff-view/file";
const file = generateDiffFile(
data?.oldFile?.fileName || "",
data?.oldFile?.content || "",
data?.newFile?.fileName || "",
data?.newFile?.content || "",
data?.oldFile?.fileLang || "",
data?.newFile?.fileLang || ""
);
file.initTheme('light' / 'dark');
file.init();
file.buildSplitDiffLines();
file.buildUnifiedDiffLines();
// with @git-diff-view/core
import { DiffFile } from "@git-diff-view/core";
const file = new DiffFile(
data?.oldFile?.fileName || "",
data?.oldFile?.content || "",
data?.newFile?.fileName || "",
data?.newFile?.content || "",
data?.hunks || [],
data?.oldFile?.fileLang || "",
data?.newFile?.fileLang || ""
);
file.initTheme('light' / 'dark');
file.init();
file.buildSplitDiffLines();
file.buildUnifiedDiffLines();
// use current data to render
;
// or use the bundle data to render, eg: postMessage/httpRequest
const bundle = file.getBundle();
const diffFile = DiffFile.createInstance(data || {}, bundle);
;
```
#### Props
| Props | Description |
| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| data | The diff data need to show, type: `{ oldFile: {fileName?: string, content?: string}, newFile: {fileName?: string, content?: string}, hunks: string[] }`, you can only pass hunks data, and the component will generate the oldFile and newFile data automatically |
| diffFile | the target data to render |
| renderWidgetLine | return a valid `react` element to show the widget, this element will render when you click the `addWidget` button in the diff view |
| renderExtendLine | return a valid `react` element to show the extend data |
| extendData | a list to store the extend data to show in the `Diff View`, type: {oldFile: {lineNumber: {data: any}}, newFile: {lineNumber: {data: any}}} |
| diffViewFontSize | the fontSize for the DiffView component, type: number |
| diffViewHighlight | enable syntax highlight, type: boolean |
| diffViewMode | the mode for the DiffView component, type: `DiffModeEnum.Split` / `DiffModeEnum.Unified` |
| diffViewWrap | enable code line auto wrap, type: boolean |
| diffViewTheme | the theme for the DiffView component, type: `light` / `dark` |
| diffViewAddWidget| enable `addWidget` button, type: boolean |
| onAddWidgetClick | when the `addWidget` button clicked, type: `({ side: "old" / "new", lineNumber: number }) => void` |
## Development
```bash
# clone this project
# pnpm install
# pnpm run build:packages
# pnpm run dev:react / pnpm run dev:vue
```