Back

Visual Text Diff Highlighter

100% Client-Side Myers

Compare code snippets, prose, database schemas, and JSON configs with Myers diff algorithm, inline character highlights, and side-by-side or unified view. Zero server telemetry guarantees total data confidentiality.

diff checker onlinecompare two textsside by side text diff
Load Sample:
Original Text (Old / Left)
Modified Text (New / Right)
Additions+34 lines
Deletions-3 lines
Modifications~12 lines
Unchanged16 lines
Change Hunks8 blocks
Similarity34%
Change 1 of 8
Whitespace:
Split view is wide. Swipe horizontally or switch:
#Original Version (31 lines)#Modified Version (62 lines)
1interface UserProfile {1interface UserProfile {
2 id: string;2 id: string;
3 username: string;3 username: string;
4 email: string;4 email: string;
5- role: "user" | "admin";5+ role: "user" | "admin" | "moderator";
~6+ isActive: boolean;
6 createdAt: string;7 createdAt: string;
~8+ updatedAt: string;
7}9}
810
9-function fetchUserData(userId: string): Promise<UserProfile> {11+// High-speed LRU memory cache layer
10- console.log("Fetching user profile for:", userId);12+const userMemoryCache = new Map<string, UserProfile>();
11- return fetch(`/api/users/${userId}`)13+
12- .then(res => res.json())14+async function fetchUserData(userId: string, forceRefresh = false): Promise<UserProfile> {
13- .catch(err => {15+ if (!forceRefresh && userMemoryCache.has(userId)) {
14- console.error("Failed to load user", err);16+ return userMemoryCache.get(userId)!;
15- throw err;17+ }
~18+
~19+ try {
~20+ const res = await fetch(`/api/v2/users/${userId}`, {
~21+ headers: { "Accept": "application/json" },
~22+ cache: forceRefresh ? "no-store" : "default",
16 });23 });
~24+
~25+ if (!res.ok) {
~26+ throw new Error(`HTTP ${res.status}: ${res.statusText}`);
~27+ }
~28+
~29+ const profile: UserProfile = await res.json();
~30+ userMemoryCache.set(userId, profile);
~31+ return profile;
~32+ } catch (err: unknown) {
~33+ console.error(`Failed to load user profile ${userId}:`, err);
~34+ throw err;
~35+ }
17}36}
1837
19-function useUserProfile(id: string) {38+function useUserProfile(id: string, forceRefresh = false) {
20 const [user, setUser] = useState<UserProfile | null>(null);39 const [user, setUser] = useState<UserProfile | null>(null);
21 const [loading, setLoading] = useState(true);40 const [loading, setLoading] = useState(true);
~41+ const [error, setError] = useState<Error | null>(null);
2242
23 useEffect(() => {43 useEffect(() => {
24- fetchUserData(id).then(data => {44+ let active = true;
25- setUser(data);45+ setLoading(true);
26- setLoading(false);~
27- });~
28- }, [id]);~
2946
30- return { user, loading };47+ fetchUserData(id, forceRefresh)
~48+ .then(data => {
~49+ if (active) setUser(data);
~50+ })
~51+ .catch(err => {
~52+ if (active) setError(err);
~53+ })
~54+ .finally(() => {
~55+ if (active) setLoading(false);
~56+ });
~57+
~58+ return () => { active = false; };
~59+ }, [id, forceRefresh]);
~60+
~61+ return { user, loading, error };
31}62}

Myers Diff Algorithm & Architecture Reference

Engineered with Eugene W. Myers' landmark Difference Algorithm, the identical foundation powering Git, Subversion, and Linux kernel patches.

Zero-Knowledge Privacy

Every calculation executes 100% inside your local browser engine. Confidential proprietary code, private SSH keys, and HIPAA/GDPR sensitive documents never touch any remote network endpoint.

Side-by-Side vs Unified

Split view aligns parallel line numbers side-by-side with spacer pads for quick dual-pane inspection. Unified view packs differences into a single chronological stream compatible with standard patch files.

Sub-line Inline Precision

Rather than merely highlighting entire lines as modified, our dual-tier tokenizer executes Myers diff on internal word and character tokens, pinpointing typos, changed variables, and altered numerical constants.

Frequently Asked Questions (FAQ)

How does the Myers Diff Algorithm find the shortest edit path?

Myers diff models text comparison as a grid traversal edit graph where moving right corresponds to deleting a character from string A, and moving down corresponds to inserting a character into string B. Diagonal moves represent free equal matches. The algorithm discovers the shortest sequence of edits (smallest edit distance D) in O(ND) time complexity, ensuring minimal and intuitive diffs.

Can I export diffs directly as Git-compatible patch files?

Yes! Click the "Copy Patch" button or the download icon to obtain a standard unified diff containing '@@ -oldStart,oldCount +newStart,newCount @@' hunk headers that can be piped directly into `git apply` or `patch -p1`.

How does whitespace and case sensitivity affect comparison?

By default, comparison is strict and preserves every space and tab. Selecting "Ignore Trailing" strips carriage returns and trailing whitespace, which is useful when comparing files edited across Windows (CRLF) and Linux (LF). "Ignore All Whitespace" normalizes internal indentation for formatted vs minified code comparisons.

Is there any limit to the file size I can compare?

Because execution is memory-efficient and bounded with common prefix/suffix pruning and typed array vectors, typical code files and documents up to several thousand lines compute in under 30 milliseconds. For safety, files uploaded via the file picker are limited to 5MB to keep browser main thread responsiveness instant.