{"id":23914041,"url":"https://github.com/MrWangJustToDo/git-diff-view","last_synced_at":"2025-09-10T22:31:39.687Z","repository":{"id":217317174,"uuid":"743521233","full_name":"MrWangJustToDo/git-diff-view","owner":"MrWangJustToDo","description":"A Diff View component for React / Vue / Solid / Svelte / Ink, just like Github","archived":false,"fork":false,"pushed_at":"2025-08-24T15:11:13.000Z","size":6613,"stargazers_count":488,"open_issues_count":13,"forks_count":20,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-08-24T19:36:09.708Z","etag":null,"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"],"latest_commit_sha":null,"homepage":"https://mrwangjusttodo.github.io/git-diff-view/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MrWangJustToDo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-01-15T12:17:00.000Z","updated_at":"2025-08-24T15:11:17.000Z","dependencies_parsed_at":"2024-02-26T05:26:17.513Z","dependency_job_id":"796c7fbb-02c0-4a4a-8896-8a8ce9445e40","html_url":"https://github.com/MrWangJustToDo/git-diff-view","commit_stats":{"total_commits":209,"total_committers":1,"mean_commits":209.0,"dds":0.0,"last_synced_commit":"aa2e918498270f737d28e7531eab08fa3f1b8831"},"previous_names":["mrwangjusttodo/git-diff-view"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/MrWangJustToDo/git-diff-view","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MrWangJustToDo%2Fgit-diff-view","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MrWangJustToDo%2Fgit-diff-view/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MrWangJustToDo%2Fgit-diff-view/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MrWangJustToDo%2Fgit-diff-view/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MrWangJustToDo","download_url":"https://codeload.github.com/MrWangJustToDo/git-diff-view/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MrWangJustToDo%2Fgit-diff-view/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274536169,"owners_count":25303780,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-10T02:00:12.551Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["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"],"created_at":"2025-01-05T10:01:32.097Z","updated_at":"2025-09-10T22:31:39.680Z","avatar_url":"https://github.com/MrWangJustToDo.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://mrwangjusttodo.github.io/git-diff-view\"\u003e\n    \u003cimg src=\"icon.png\" alt=\"logo\" width=\"180\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# Git Diff Component\n\nA Diff view component for React / Vue / Solid / Svelte,\nThe most one component what easy to use and feature complete.\n\n[![Deploy](https://github.com/MrWangJustToDo/git-diff-view/actions/workflows/deploy.yml/badge.svg)](https://github.com/MrWangJustToDo/git-diff-view/actions/workflows/deploy.yml)\n![NPM Downloads](https://img.shields.io/npm/dm/%40git-diff-view%2Fcore)\n![NPM License](https://img.shields.io/npm/l/%40git-diff-view%2Fcore)\n\n## Demo ---- git-diff / file-diff\n[git-mode](https://mrwangjusttodo.github.io/git-diff-view/?type=try\u0026tab=git)\n\n![git mode](https://raw.githubusercontent.com/MrWangJustToDo/git-diff-view/aa2e918498270f737d28e7531eab08fa3f1b8831/gitMode.png)\n\n[file-mode](https://mrwangjusttodo.github.io/git-diff-view/?type=try\u0026tab=file)\n\n![file mode](https://raw.githubusercontent.com/MrWangJustToDo/git-diff-view/aa2e918498270f737d28e7531eab08fa3f1b8831/fileMode.png)\n\n[GitHub compare](https://mrwangjusttodo.github.io/MrWangJustToDo.io?overlay=open\u0026playGround=GitHub)\n\n![GitHub compare](https://raw.githubusercontent.com/MrWangJustToDo/git-diff-view/aa2e918498270f737d28e7531eab08fa3f1b8831/4.png)\n\n## How to use （React / Vue / Solid / Svelte）\n\nSee example project [Example](https://github.com/MrWangJustToDo/git-diff-view/tree/main/ui)\n\n## Packages\n\n| Package                                  | Version                                                                                                                    |\n| :--------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- |\n| [`@git-diff-view/core`](packages/core)   | [![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/core)](https://www.npmjs.com/package/@git-diff-view/core)   |\n| [`@git-diff-view/file`](packages/file)   | [![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/file)](https://www.npmjs.com/package/@git-diff-view/file)   |\n| [`@git-diff-view/react`](packages/react) | [![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/react)](https://www.npmjs.com/package/@git-diff-view/react) |\n| [`@git-diff-view/vue`](packages/vue)     | [![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/vue)](https://www.npmjs.com/package/@git-diff-view/vue)     |\n| [`@git-diff-view/solid`](packages/solid) | [![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/solid)](https://www.npmjs.com/package/@git-diff-view/solid) |\n| [`@git-diff-view/svelte`](packages/svelte)|[![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/svelte)](https://www.npmjs.com/package/@git-diff-view/svelte)|\n| [`@git-diff-view/cli`](packages/cli)     | [![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/cli)](https://www.npmjs.com/package/@git-diff-view/cli)     |\n\n### syntax highlighter\n\n| Package                                                   | Version                                                                                                                          |\n| :-------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- |\n| [`@git-diff-view/lowlight`](packages/lowlight) `build in` | [![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/lowlight)](https://www.npmjs.com/package/@git-diff-view/lowlight) |\n| [`@git-diff-view/shiki`](packages/shiki)                  | [![npm (scoped)](https://img.shields.io/npm/v/%40git-diff-view/shiki)](https://www.npmjs.com/package/@git-diff-view/shiki)       |\n\n## Screen Shot\n\n![Screenshot](https://raw.githubusercontent.com/MrWangJustToDo/git-diff-view/aa2e918498270f737d28e7531eab08fa3f1b8831/1.png)\n![Screenshot](https://raw.githubusercontent.com/MrWangJustToDo/git-diff-view/69c801e5eb5fcabc9c9655825eb1228f18dc1e0c/5.png)\n![Screenshot](https://raw.githubusercontent.com/MrWangJustToDo/git-diff-view/aa2e918498270f737d28e7531eab08fa3f1b8831/theme.png)\n![Screenshot](https://raw.githubusercontent.com/MrWangJustToDo/git-diff-view/aa2e918498270f737d28e7531eab08fa3f1b8831/2.png)\n![Screenshot](https://raw.githubusercontent.com/MrWangJustToDo/git-diff-view/aa2e918498270f737d28e7531eab08fa3f1b8831/3.png)\n\n### Template mode\n\nFor 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)\n\n### FastDiff template\n\nUsing 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)\n\n#### Default diffLine\n![Screenshot](https://github.com/MrWangJustToDo/git-diff-view/blob/main/default.png)\n\n#### FastDiff diffLine\n![Screenshot](https://github.com/MrWangJustToDo/git-diff-view/blob/main/enableFastDiffTemplate.png)\n\n#### How to enable FastDiff template\n```ts\nimport { setEnableFastDiffTemplate } from '@git-diff-view/core' // or react/vue runtime package\n\n// experimental feature, use with caution\nsetEnableFastDiffTemplate(true);\n```\n\n## Features\n\n+ [x] Show the `git diff` result \n+ [x] Support `Split View` and `Unified View`\n+ [x] Support `Warp` / `UnWarp` the code line\n+ [x] Support `light` / `dark` theme by default (since v0.0.17)\n+ [x] Support `Syntax Highlight` with \u003cb\u003e`full syntax context`\u003c/b\u003e (base on `hast` AST)\n+ [x] Support `Extend Data` component in the `Diff View`\n+ [x] Support `Widget` component in the `Diff View`\n+ [x] Support `Web Worker` / `Node Server` to improve performance\n+ [x] Support `React` and `Vue` component\n+ [x] Support compare by `@git-diff-view/core`(git diff) or `@git-diff-view/file`(file content)\n+ [x] Support `Diff Match Patch` to improve line diff (experimental)\n+ [x] Support `SSR` for `React` and `Vue` component (since v0.0.21)\n+ [x] Support `RSC` for `React` component (since v0.0.21)\n+ [x] More Render Platform: `Solid` / `Svelte` / `Cli`\n+ [ ] Support `Virtual Scroll` to improve performance\n\n\n## Install\n\n```shell\n# In React Project\npnpm add @git-diff-view/react\n\n# In Vue Project\npnpm add @git-diff-view/vue\n\n```\n\n## Use in React\n\n#### There are two ways to use this component:\n\n#### 1. Use the `DiffView` component directly.\n\n```tsx\nimport { DiffView, DiffModeEnum } from \"@git-diff-view/react\";\nimport \"@git-diff-view/react/styles/diff-view.css\";\n// if you have your own tailwindcss config, you can use the `diff-view-pure.css` to avoid CSS conflicts\nimport \"@git-diff-view/react/styles/diff-view-pure.css\";\n\n\u003cDiffView\u003cstring\u003e\n  // use data\n  data={{\n    oldFile?: { fileName?: string | null; fileLang?: string | null; content?: string | null };\n    newFile?: { fileName?: string | null; fileLang?: string | null; content?: string | null };\n    hunks: string[];\n  }}\n  extendData={{oldFile: {10: {data: 'foo'}}, newFile: {20: {data: 'bar'}}}}\n  renderExtendLine={({ data }) =\u003e ReactNode}\n  diffViewFontSize={number}\n  diffViewHighlight={boolean}\n  diffViewMode={DiffModeEnum.Split | DiffModeEnum.Unified}\n  diffViewWrap={boolean}\n  diffViewTheme={'light' | 'dark'}\n  diffViewAddWidget\n  onAddWidgetClick={({ side, lineNumber }) =\u003e void}\n  renderWidgetLine={({ onClose, side, lineNumber }) =\u003e ReactNode}\n/\u003e\n\n```\n\n#### 2. Use the `DiffView` component with `@git-diff-view/core` or `@git-diff-view/file`\n\n```tsx\n// with @git-diff-view/file\nimport { DiffFile, generateDiffFile } from \"@git-diff-view/file\";\nconst file = generateDiffFile(\n  data?.oldFile?.fileName || \"\",\n  data?.oldFile?.content || \"\",\n  data?.newFile?.fileName || \"\",\n  data?.newFile?.content || \"\",\n  data?.oldFile?.fileLang || \"\",\n  data?.newFile?.fileLang || \"\"\n);\nfile.initTheme('light' / 'dark');\nfile.init();\nfile.buildSplitDiffLines();\nfile.buildUnifiedDiffLines();\n\n// with @git-diff-view/core\nimport { DiffFile } from \"@git-diff-view/core\";\nconst file = new DiffFile(\n  data?.oldFile?.fileName || \"\",\n  data?.oldFile?.content || \"\",\n  data?.newFile?.fileName || \"\",\n  data?.newFile?.content || \"\",\n  data?.hunks || [],\n  data?.oldFile?.fileLang || \"\",\n  data?.newFile?.fileLang || \"\"\n);\nfile.initTheme('light' / 'dark');\nfile.init();\nfile.buildSplitDiffLines();\nfile.buildUnifiedDiffLines();\n\n// use current data to render\n\u003cDiffView diffFile={file} {...props} /\u003e;\n// or use the bundle data to render, eg: postMessage/httpRequest\nconst bundle = file.getBundle();\nconst diffFile = DiffFile.createInstance(data || {}, bundle);\n\u003cDiffView diffFile={diffFile} {...props} /\u003e;\n```\n\n#### Props\n\n| Props  | Description  |\n| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 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 |\n| diffFile         | the target data to render |\n| renderWidgetLine | return a valid `react` element to show the widget, this element will render when you click the `addWidget` button in the diff view  |\n| renderExtendLine | return a valid `react` element to show the extend data |\n| extendData       | a list to store the extend data to show in the `Diff View`, type: {oldFile: {lineNumber: {data: any}}, newFile: {lineNumber: {data: any}}}   |\n| diffViewFontSize | the fontSize for the DiffView component, type: number |\n| diffViewHighlight | enable syntax highlight, type: boolean |\n| diffViewMode     | the mode for the DiffView component, type: `DiffModeEnum.Split` / `DiffModeEnum.Unified` |\n| diffViewWrap     | enable code line auto wrap, type: boolean |\n| diffViewTheme    | the theme for the DiffView component, type: `light` / `dark` |\n| diffViewAddWidget| enable `addWidget` button, type: boolean |\n| onAddWidgetClick | when the `addWidget` button clicked, type: `({ side: \"old\" / \"new\", lineNumber: number }) =\u003e void` |\n\n## Development\n\n```bash\n# clone this project\n\n# pnpm install\n\n# pnpm run build:packages\n\n# pnpm run dev:react / pnpm run dev:vue\n\n```\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMrWangJustToDo%2Fgit-diff-view","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMrWangJustToDo%2Fgit-diff-view","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMrWangJustToDo%2Fgit-diff-view/lists"}