Diff

Diff renders one file patch in a unified or split view with syntax highlighting and optional line numbers. Use Code when you do not need patch parsing.

Availability

FieldAvailability
Package@opentui/core
Core renderableDiffRenderable
React<diff> (automatic)
Solid<diff> is runtime built in. Its exact props declaration is missing.
StatusBuilt in with a Solid typing limitation

Basic usage

Renderable API

OpenTUI preview

Run this example to open an interactive terminal.

Source code · typescript
import { DiffRenderable, SyntaxStyle, RGBA, createCliRenderer } from "@opentui/core"

const renderer = await createCliRenderer()

const syntaxStyle = SyntaxStyle.fromStyles(
  {
    default: { fg: RGBA.fromHex("#E6EDF3") },
    string: { fg: RGBA.fromHex("#A5D6FF") },
    keyword: { fg: RGBA.fromHex("#FF7B72"), bold: true },
  },
  renderer.nativeScene,
)

const patch = `diff --git a/app.ts b/app.ts
index 1111111..2222222 100644
--- a/app.ts
+++ b/app.ts
@@ -1,3 +1,3 @@
 setup()
-const a = 1
+const a = 2
 ready(a)
`

const diff = new DiffRenderable(renderer, {
  id: "diff",
  width: "100%",
  height: 16,
  diff: patch,
  view: "split",
  filetype: "typescript",
  syntaxStyle,
  showLineNumbers: true,
})

renderer.root.add(diff)

Monochrome views of the same patch:

Unified view:

 1   setup()
 2 - const a = 1
 2 + const a = 2
 3   ready(a)

Split view:

 1   setup()      1   setup()
 2 - const a = 1  2 + const a = 2
 3   ready(a)     3   ready(a)

For multi-file input, Diff shows only the first file patch (patches[0]). Create one DiffRenderable for each file patch that you need to show.

Split view scroll sync

In split view, set syncScroll: true to link the two panes. A mouse-wheel scroll in one pane then copies its scrollX and scrollY to the other pane:

const diff = new DiffRenderable(renderer, {
  id: "diff",
  view: "split",
  syncScroll: true,
  diff: patch,
  syntaxStyle,
})

// Toggle at runtime
diff.syncScroll = false

Scroll sync has no effect in the unified view.

If you omit syntaxStyle, Diff creates an empty fallback style and destroys it when you destroy the Diff. Destroying a Diff also destroys its inactive panes. Diff does not destroy a syntaxStyle you pass. Destroy it after no renderable uses it.

Properties

PropertyTypeDefaultDescription
diffstring""Unified diff string
view"unified" or "split""unified"Layout style
syncScrollbooleanfalseLink horizontal and vertical scroll in split view
filetypestring-Syntax highlighting language
fgstring or RGBA-Base foreground for inner code panes
syntaxStyleSyntaxStyle-Syntax style for code
wrapMode"word", "char", or "none"-Code wrapping mode
concealbooleanfalseConceal markup when highlighting
selectionBgstring or RGBA-Selection background in code panes
selectionFgstring or RGBA-Selection foreground in code panes
treeSitterClientTreeSitterClient-Custom Tree-sitter client
showLineNumbersbooleantrueShow line numbers
lineNumberFgstring or RGBA#888888Line number text color
lineNumberBgstring or RGBAtransparentLine number background
addedLineNumberBgstring or RGBAtransparentLine number background for added lines
removedLineNumberBgstring or RGBAtransparentLine number background for removed lines
addedBgstring or RGBA#1a4d1aBackground for added lines
removedBgstring or RGBA#4d1a1aBackground for removed lines
contextBgstring or RGBAtransparentBackground for context lines
addedContentBgstring or RGBA-Optional content background (added)
removedContentBgstring or RGBA-Optional content background (removed)
contextContentBgstring or RGBA-Optional content background (context)
addedSignColorstring or RGBA#22c55eSign color for added lines
removedSignColorstring or RGBA#ef4444Sign color for removed lines

Other grammars require Tree-sitter configuration. See the Tree-sitter reference.

Use Code for source text without patch structure. Use Line number gutter with other line-aware renderables. Use Markdown for documents and TextTable for general tabular comparisons.