Overview
The DiffRenderable component displays git-style diffs with syntax highlighting, line numbers, and support for both unified and split view modes. It parses standard unified diff format and provides rich styling options.
Basic Usage
import { DiffRenderable, SyntaxStyle } from "@opentui/core"
const diff = `--- a/calculator.ts
+++ b/calculator.ts
@@ -1,13 +1,20 @@
class Calculator {
add(a: number, b: number): number {
return a + b;
}
- subtract(a: number, b: number): number {
- return a - b;
+ subtract(a: number, b: number, c: number = 0): number {
+ return a - b - c;
}
}`
const diffView = new DiffRenderable(renderer, {
diff,
view: "unified",
filetype: "typescript",
syntaxStyle,
})
Props
Unified diff content in standard git diff format.
view
'unified' | 'split'
default:"'unified'"
Diff view mode:
'unified': Single pane with +/- indicators
'split': Side-by-side comparison
Language/filetype for syntax highlighting (e.g., "typescript", "python").
Syntax styling configuration for code highlighting.
Show line numbers in the gutter.
Enable concealment of hidden syntax elements.
Tree-sitter client for syntax parsing.
Color Customization
Default foreground color.
addedBg
string | RGBA
default:"'#1a4d1a'"
Background color for added lines (gutter).
removedBg
string | RGBA
default:"'#4d1a1a'"
Background color for removed lines (gutter).
contextBg
string | RGBA
default:"'transparent'"
Background color for unchanged context lines (gutter).
Background color for added line content. Falls back to addedBg if not specified.
Background color for removed line content. Falls back to removedBg if not specified.
Background color for context line content. Falls back to contextBg if not specified.
addedSignColor
string | RGBA
default:"'#22c55e'"
Color for the ”+” sign on added lines.
removedSignColor
string | RGBA
default:"'#ef4444'"
Color for the ”-” sign on removed lines.
lineNumberFg
string | RGBA
default:"'#888888'"
Foreground color for line numbers.
lineNumberBg
string | RGBA
default:"'transparent'"
Background color for the line number gutter.
addedLineNumberBg
string | RGBA
default:"'transparent'"
Background color for line numbers on added lines.
removedLineNumberBg
string | RGBA
default:"'transparent'"
Background color for line numbers on removed lines.
Background color for selected text.
Foreground color for selected text.
View Modes
Unified View
Displays changes in a single column with + for additions and - for removals:
1 class Calculator {
2 add(a: number, b: number): number {
3 return a + b;
-4 subtract(a: number, b: number): number {
-5 return a - b;
+4 subtract(a: number, b: number, c: number = 0): number {
+5 return a - b - c;
Split View
Displays before and after side-by-side:
Before After
4 subtract(a, b) { | 4 subtract(a, b, c = 0) {
5 return a - b; | 5 return a - b - c;
Examples
GitHub Dark Theme
const syntaxStyle = SyntaxStyle.fromStyles({
keyword: { fg: parseColor("#FF7B72"), bold: true },
string: { fg: parseColor("#A5D6FF") },
comment: { fg: parseColor("#8B949E"), italic: true },
function: { fg: parseColor("#D2A8FF") },
default: { fg: parseColor("#E6EDF3") },
})
const diffView = new DiffRenderable(renderer, {
diff: diffContent,
view: "unified",
filetype: "typescript",
syntaxStyle,
addedBg: "#1a4d1a",
removedBg: "#4d1a1a",
addedSignColor: "#22c55e",
removedSignColor: "#ef4444",
lineNumberFg: "#6b7280",
lineNumberBg: "#161b22",
})
Split View
const diffView = new DiffRenderable(renderer, {
diff: diffContent,
view: "split",
filetype: "typescript",
syntaxStyle,
wrapMode: "word",
width: "100%",
})
Toggle View Mode
const diffView = new DiffRenderable(renderer, {
diff: diffContent,
view: "unified",
filetype: "typescript",
syntaxStyle,
})
renderer.keyInput.on("keypress", (key) => {
if (key.name === "v") {
diffView.view = diffView.view === "unified" ? "split" : "unified"
}
})
Custom Color Scheme (Monokai)
const diffView = new DiffRenderable(renderer, {
diff: diffContent,
view: "unified",
filetype: "typescript",
syntaxStyle: monokaiStyle,
addedBg: "#2d4a2b",
removedBg: "#4a2b2b",
contextBg: "transparent",
addedSignColor: "#A6E22E",
removedSignColor: "#F92672",
lineNumberFg: "#75715E",
lineNumberBg: "#1e1f1c",
})
Without Line Numbers
const diffView = new DiffRenderable(renderer, {
diff: diffContent,
view: "unified",
filetype: "typescript",
syntaxStyle,
showLineNumbers: false,
})
With Word Wrapping
const diffView = new DiffRenderable(renderer, {
diff: diffContent,
view: "split",
filetype: "typescript",
syntaxStyle,
wrapMode: "word",
})
Real Git Diff
import { exec } from "child_process"
import { promisify } from "util"
const execAsync = promisify(exec)
// Get git diff
const { stdout: diff } = await execAsync("git diff HEAD~1 HEAD -- src/file.ts")
const diffView = new DiffRenderable(renderer, {
diff,
view: "split",
filetype: "typescript",
syntaxStyle,
})
Methods
setLineColor()
Set custom color for a specific line.
diffView.setLineColor(5, "#ff0000")
clearLineColor()
Clear custom color for a line.
diffView.clearLineColor(5)
setLineColors()
Set multiple line colors at once.
const colors = new Map([
[3, "#ff0000"],
[5, "#00ff00"],
])
diffView.setLineColors(colors)
highlightLines()
Highlight a range of lines.
diffView.highlightLines(10, 15, "#ff00ff")
clearHighlightLines()
Clear highlighting for a range.
diffView.clearHighlightLines(10, 15)
clearAllLineColors()
Clear all custom line colors.
diffView.clearAllLineColors()
Properties
diff
Get or set the diff content.
diffView.diff = newDiffContent
const current = diffView.diff
view
Get or set the view mode.
filetype
Get or set the language for syntax highlighting.
diffView.filetype = "python"
syntaxStyle
Get or set the syntax style.
diffView.syntaxStyle = newSyntaxStyle
wrapMode
Get or set the wrap mode.
diffView.wrapMode = "word"
showLineNumbers
Get or set line number visibility.
diffView.showLineNumbers = false
Color Properties
All color properties can be read and written:
diffView.addedBg = "#1a4d1a"
diffView.removedBg = "#4d1a1a"
diffView.addedSignColor = "#22c55e"
diffView.removedSignColor = "#ef4444"
diffView.lineNumberFg = "#6b7280"
// ... and more
DiffRenderable expects standard unified diff format:
--- a/file.ts
+++ b/file.ts
@@ -1,5 +1,6 @@
context line
-removed line
+added line
context line
You can generate this format using:
git diff
diff -u file1 file2
- JavaScript diff libraries like
diff package
Error Handling
If the diff cannot be parsed, DiffRenderable displays an error message and falls back to showing the raw diff as syntax-highlighted code:
// Invalid diff format
const diffView = new DiffRenderable(renderer, {
diff: "invalid diff content",
filetype: "diff",
syntaxStyle,
})
// Shows: "Error parsing diff: [error message]" followed by the raw content
- Efficient diff parsing with the
diff package
- Smart content alignment in split view for wrapped lines
- Minimal re-rendering when toggling styles
- Handles large diffs with good performance
- Code - Syntax-highlighted code display (used internally)
- LineNumberRenderable - Line number gutter (used internally)
- Text - Plain text display