Fluxo UIFluxo UIv0.1.1

Diff Viewer

High-performance text diff viewer with unified, split, inline, and minimal variants. Handles very large files via row virtualization, supports ignore options and a configurable comparison cap.

Basic Usage

Unified Diff

Classic git-style unified diff with word-level highlights on changed lines.

before.js
after.js
1
function greet(name) {
1
+
function greet(name, greeting = "Hello") {
2
console.log("Hello, " + name);
2
+
console.log(`${greeting}, ${name}!`);
3
}
4
5
function add(a, b) {
6
return a + b;
6
+
return Number(a) + Number(b);
7
}
8
9
const PI = 3.14;
9
+
const PI = 3.14159;
10
const E = 2.71;
10
+
const TAU = 6.28318;
11
12
greet("World");
13
+
greet("Friend", "Hi");
13
console.log(add(2, 3));
14
import { DiffViewer } from 'fluxo-ui';

<DiffViewer
    oldValue={oldText}
    newValue={newText}
    oldTitle="before.js"
    newTitle="after.js"
/>

Variants

Split View

Side-by-side two-column layout.

before.js
after.js
1
function greet(name) {
1
+
function greet(name, greeting = "Hello") {
2
console.log("Hello, " + name);
2
+
console.log(`${greeting}, ${name}!`);
3
}
3
}
4
4
5
function add(a, b) {
5
function add(a, b) {
6
return a + b;
6
+
return Number(a) + Number(b);
7
}
7
}
8
8
9
const PI = 3.14;
9
+
const PI = 3.14159;
10
const E = 2.71;
10
+
const TAU = 6.28318;
11
11
12
greet("World");
12
greet("World");
13
+
greet("Friend", "Hi");
13
console.log(add(2, 3));
14
console.log(add(2, 3));
14
15
<DiffViewer variant="split" oldValue={...} newValue={...} />
<DiffViewer variant="inline" oldValue={...} newValue={...} />
<DiffViewer variant="minimal" collapseUnchanged oldValue={...} newValue={...} />

Inline Diff

Compact inline word-level diff for small snippets.

function greet(name) {function greet(name, greeting = "Hello") { console.log("Hello, " + name); console.log(`${greeting}, ${name}!`); } function add(a, b) { return a + b; return Number(a) + Number(b); } const PI = 3.14;const PI = 3.14159; const E = 2.71;const TAU = 6.28318; greet("World"); greet("Friend", "Hi"); console.log(add(2, 3));

Collapse Unchanged

Runs of unchanged lines are folded into context hunks.

1
function greet(name) {
1
+
function greet(name, greeting = "Hello") {
2
console.log("Hello, " + name);
2
+
console.log(`${greeting}, ${name}!`);
3
}
4
5
function add(a, b) {
6
return a + b;
6
+
return Number(a) + Number(b);
7
}
8
9
const PI = 3.14;
9
+
const PI = 3.14159;
10
const E = 2.71;
10
+
const TAU = 6.28318;
11
12
greet("World");
13
+
greet("Friend", "Hi");
13
console.log(add(2, 3));
14

Ignore Options

Ignore Options

Toggle whitespace, case, and empty-line sensitivity.

1
// Config file
1
+
// config file
2
const HOST = "localhost";
2
+
const HOST = "localhost";
3
const PORT = 3000;
3
+
const PORT = 3000;
4
4
+
const user = "admin";
5
const USER = "Admin";
5
+
const pass = "secret";
6
const PASS = "Secret";
7
8
9
const DB = "mydb";
10
const TIMEOUT = 30;
11
<DiffViewer
    oldValue={oldText}
    newValue={newText}
    ignoreWhitespace
    ignoreCase
    ignoreEmptyLines
/>

Interactive Viewer

Interactive Diff Viewer

File list on the left, diff on the right. Switch between unified and split view, toggle word highlighting and ignore options.

4 files changed+43−17
Files changed
src/server.js+18−6
server.js (before)
server.js (after)
1
import express from 'express';
2
import { createPool } from 'mysql2/promise';
3
import bcrypt from 'bcrypt';
4
+
import helmet from 'helmet';
5
+
import rateLimit from 'express-rate-limit';
4
5
const app = express();
6
const PORT = 3000;
8
+
const PORT = process.env.PORT ?? 3000;
7
8
const pool = createPool({
9
host: 'localhost',
11
+
host: process.env.DB_HOST ?? 'localhost',
10
user: 'root',
12
+
user: process.env.DB_USER ?? 'root',
11
password: 'password',
13
+
password: process.env.DB_PASS ?? '',
12
database: 'users_db',
14
+
database: process.env.DB_NAME ?? 'users_db',
15
+
connectionLimit: 10,
13
});
14
15
app.use(express.json());
18
+
app.use(helmet());
19
+
app.use(express.json({ limit: '16kb' }));
16
21
+
const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 });
22
+
app.use('/register', limiter);
23
+
17
app.post('/register', async (req, res) => {
18
const { username, password } = req.body;
19
if (!username || !password) {
<DiffViewer
    variant={view}
    oldValue={selectedFile.oldValue}
    newValue={selectedFile.newValue}
    oldTitle={`${selectedFile.name} (before)`}
    newTitle={`${selectedFile.name} (after)`}
    wordDiff={wordDiff}
    ignoreWhitespace={ignoreWs}
    ignoreCase={ignoreCase}
    ignoreEmptyLines={ignoreEmpty}
    collapseUnchanged={3}
/>

Large Files

Large File Performance

Virtualized rendering. 2000+ lines diff smoothly. Use maxLines to cap comparison.

maxLines:
<DiffViewer
    oldValue={oldLarge}
    newValue={newLarge}
    variant="split"
    collapseUnchanged
    maxLines={5000}
    maxHeight={500}
/>

Import

import { DiffViewer } from 'fluxo-ui';
import type { DiffViewerProps, DiffVariant } from 'fluxo-ui';

Props

oldValue
string

The old/before text.

newValue
string

The new/after text.

variant
'unified' | 'split' | 'inline' | 'minimal'"'unified'"

Diff display style.

oldTitle
string

Header label for the old side.

newTitle
string

Header label for the new side.

showLineNumbers
boolean"true"

Show gutter line numbers.

wordDiff
boolean"true"

Highlight word-level changes inside replaced lines.

collapseUnchanged
boolean | number"false"

Fold unchanged runs. A number sets the context line count (default 3).

maxHeight
number | string"480"

Max scroll viewport height.

ignoreWhitespace
boolean"false"

Collapse whitespace runs when comparing.

ignoreCase
boolean"false"

Case-insensitive comparison.

ignoreEmptyLines
boolean"false"

Treat blank lines as equal.

maxLines
number

Stop comparing after N lines. Larger files are truncated with a footer notice.

rowHeight
number"22"

Row pixel height used for virtualization.

highlight
(line: string) => ReactNode

Custom syntax-highlight hook.