DEV Community

Bishes
Bishes

Posted on

How I Built a Side-by-Side Diff Checker in 100 Lines of JavaScript (No Libraries)

One of the tools in my DevForge suite is a side-by-side diff checker. No libraries, no frameworks - just vanilla JavaScript and a classic algorithm.

Here's exactly how it works.

The LCS Algorithm

The core is the Longest Common Subsequence (LCS) algorithm. Given two sequences (in our case, arrays of lines), it finds the longest sequence that appears in both. Everything not in the LCS is either an addition or a deletion.

Step 1: Build the DP Table

`javascript
function computeDiff(a, b) {
const linesA = a.split('\n');
const linesB = b.split('\n');
const m = linesA.length, n = linesB.length;

const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (linesA[i - 1] === linesB[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
`

This creates an (m+1) x (n+1) table where dp[i][j] is the length of the LCS of the first i lines of text A and the first j lines of text B.

Step 2: Backtrack to Find the Diff

Starting from dp[m][n], we walk backward through the table:

javascript
const result = [];
let i = m, j = n;
const temp = [];
while (i > 0 || j > 0) {
if (i > 0 && j > 0 && linesA[i - 1] === linesB[j - 1]) {
temp.push({ type: 'unchanged', text: linesA[i - 1], lnA: i, lnB: j });
i--; j--;
} else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
temp.push({ type: 'added', text: linesB[j - 1], lnA: null, lnB: j });
j--;
} else {
temp.push({ type: 'removed', text: linesA[i - 1], lnA: i, lnB: null });
i--;
}
}
return temp.reverse();
}

When two lines match, we mark them as unchanged. When they don't, we follow the larger DP value - if going left (B's side) is higher, it's an addition; if going up (A's side), it's a deletion.

Rendering the Diff

css
.diff-line.added { background: #23863622; }
.diff-line.removed { background: #da363322; }
.diff-line.unchanged { background: transparent; }

Each diff line gets a class: dded (green tint),
emoved (red tint), or unchanged. Line numbers from both sides are displayed in a column format: old:new.

Why This Matters

No libraries means:

  • Zero dependencies - no npm install, no build step
  • Fast load - the entire tool is a single HTML file under 10KB
  • Privacy - everything runs in the browser, no network requests

Try It

The tool is live at: https://bshes.github.io/json2ts/diff/

The full suite of 10 tools: https://bshes.github.io/json2ts/

GitHub repo (all source, MIT licensed): https://github.com/Bshes/json2ts


The entire suite is free and open source. If you find it useful, star the repo or share it with a teammate.

Top comments (0)