logo

Git Diff Component

A Diff view component for React / Vue / Solid / Svelte, The most one component what easy to use and feature complete.

Demo ---- git-diff / file-diff

git-mode

file-mode

GitHub compare

How to use (React / Vue / Solid / Svelte)

See example project Example

Packages

Package Version
@git-diff-view/core
@git-diff-view/file
@git-diff-view/react
@git-diff-view/vue
@git-diff-view/solid
@git-diff-view/svelte

syntax highlighter

Package Version
@git-diff-view/lowlight build in
@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

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

Default diffLine

FastDiff diffLine

Features

  • Show the git diff result
  • Support Split View and Unified View
  • Support Warp / UnWarp the code line
  • Support light / dark theme by default (since v0.0.17)
  • Support Syntax Highlight with full syntax context (base on hast AST)
  • Support Extend Data component in the Diff View
  • Support Widget component in the Diff View
  • Support Web Worker / Node Server to improve performance
  • Support React and Vue component
  • Support compare by @git-diff-view/core(git diff) or @git-diff-view/file(file content)
  • Support Diff Match Patch to improve line diff (experimental)
  • Support SSR for React and Vue component (since v0.0.21)
  • Support RSC for React component (since v0.0.21)
  • Support Virtual Scroll to improve performance

Install

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

import { DiffView, DiffModeEnum } from "@git-diff-view/react";
import "@git-diff-view/react/styles/diff-view.css";

<DiffView<string>
  // 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

// 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
<DiffView diffFile={file} {...props} />;
// or use the bundle data to render, eg: postMessage/httpRequest
const bundle = file.getBundle();
const diffFile = DiffFile.createInstance(data || {}, bundle);
<DiffView diffFile={diffFile} {...props} />;

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

# clone this project

# pnpm install

# pnpm run build:packages

# pnpm run dev:react / pnpm run dev:vue

Top categories

Loading Svelte Themes