{"id":48854274,"url":"https://github.com/timoheimonen/diffvoid","last_synced_at":"2026-04-15T11:38:06.214Z","repository":{"id":348881643,"uuid":"1199785783","full_name":"timoheimonen/diffvoid","owner":"timoheimonen","description":"your secure place to compare texts","archived":false,"fork":false,"pushed_at":"2026-04-03T08:41:47.000Z","size":122,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T14:02:53.416Z","etag":null,"topics":["cloudflare-pages","compare","privacy"],"latest_commit_sha":null,"homepage":"https://diffvoid.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timoheimonen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-02T17:52:33.000Z","updated_at":"2026-04-03T08:49:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/timoheimonen/diffvoid","commit_stats":null,"previous_names":["timoheimonen/diffvoid"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/timoheimonen/diffvoid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoheimonen%2Fdiffvoid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoheimonen%2Fdiffvoid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoheimonen%2Fdiffvoid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoheimonen%2Fdiffvoid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timoheimonen","download_url":"https://codeload.github.com/timoheimonen/diffvoid/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoheimonen%2Fdiffvoid/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31840098,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T11:29:19.690Z","status":"ssl_error","status_checked_at":"2026-04-15T11:29:19.171Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-pages","compare","privacy"],"created_at":"2026-04-15T11:38:05.540Z","updated_at":"2026-04-15T11:38:06.154Z","avatar_url":"https://github.com/timoheimonen.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# diffvoid.com\n\nA secure, browser-based text comparison tool. Compare two texts side-by-side to see differences instantly. All processing happens locally in your browser — your text never leaves your device.\n\n**Live:** [diffvoid.com](https://diffvoid.com)\n\n## Features\n\n- **100% Client-Side**: All text comparison happens in your browser. No data is sent to any server.\n- **Line-Aware Diff**: Aligns line sequences with LCS/heuristics so inserted or removed lines do not shift the entire comparison.\n- **Character-Level Diff**: Highlights exact character differences within modified lines.\n- **Invisible Character Detection**: Automatically highlights invisible Unicode characters (zero-width spaces, non-breaking spaces, soft hyphens, directional marks, etc.) with visual indicators.\n- **Copy Without Invisible Characters**: When invisible characters are detected, copy buttons appear next to the comparison result. Zero-width characters are removed completely, while special spaces (NBSP, En/Em space, etc.) are replaced with standard spaces to preserve word separation.\n- **Adjustable Divider**: Drag the center divider to adjust the width of left and right panels. Double-click divider or click Clear to reset to 50/50.\n- **Dark/Light Mode**: Toggle between dark and light themes. Preference is saved locally.\n- **Web Worker Processing**: Comparison runs in a background Web Worker to keep the UI responsive. Falls back to synchronous processing if workers are unavailable.\n- **Chunked Rendering**: Large diffs are rendered in batches to prevent browser freezing.\n- **Input Limit**: Maximum 25,000 lines per side enforced to maintain performance.\n- **Automatic Algorithm Switching**: Character-level diff uses DP (LCS matrix) for typical input sizes and Hirschberg (linear memory) for very large inputs.\n- **Privacy-First**: No ads, no analytics, no tracking. Open source and auditable.\n\n## How to Use\n\n1. Paste text into the left panel\n2. Paste text into the right panel\n3. Differences are highlighted automatically:\n   - **Green background**: Matching text\n   - **Red background**: Different, added, or deleted text\n   - **Invisible characters**: Shown as `[ZWSP]`, `|`, `[NBSP]`, `[LRM]`, or red boxes for spaces in diffs\n4. When invisible characters are detected, **copy buttons (L/R)** appear next to the mismatch counter:\n   - **Zero-width characters** (like `[ZWSP]`, `[LRM]`) are removed completely\n   - **Special spaces** (like `[NBSP]`, `[EM]`, `[EN]`) are replaced with standard spaces to prevent word merging\n5. Drag the center divider to adjust panel widths\n6. Click the trash icon to clear both panels\n\n## Invisible Characters Detected\n\nThe tool highlights these commonly problematic invisible Unicode characters:\n\n| Code | Name | Display |\n|------|------|---------|\n| U+200B | Zero Width Space | `\\|` |\n| U+200C | Zero Width Non-Joiner | `[ZWNJ]` |\n| U+200D | Zero Width Joiner | `[ZWJ]` |\n| U+FEFF | BOM / ZWNBSP | `[BOM]` |\n| U+00A0 | Non-Breaking Space | `[NBSP]` |\n| U+202F | Narrow No-Break Space | `[NNBSP]` |\n| U+200A | Hair Space | `[HS]` |\n| U+2009 | Thin Space | `[THIN]` |\n| U+3000 | Ideographic Space | `[IDEO]` |\n| U+2002 | En Space | `[EN]` |\n| U+2003 | Em Space | `[EM]` |\n| U+2007 | Figure Space | `[FIG]` |\n| U+2008 | Punctuation Space | `[PUNCT]` |\n| U+205F | Medium Mathematical Space | `[MMSP]` |\n| U+00AD | Soft Hyphen | `[SHY]` |\n| U+200E | Left-to-Right Mark | `[LRM]` |\n| U+200F | Right-to-Left Mark | `[RLM]` |\n| U+180E | Mongolian Vowel Separator | `[MVS]` |\n| U+2060 | Word Joiner | `[WJ]` |\n\n## Technical Details\n\n### Diff Algorithm\n\nUses line sequence alignment with an LCS/heuristic approach:\n- **Line-level diff**: Matching blocks stay aligned even when lines are inserted or deleted\n- **Character-level diff**: For modified lines, detailed character comparison shows exact differences\n\n**Character-level algorithms**:\n- **DP (LCS matrix)**: Dynamic programming approach using a full Longest Common Subsequence matrix. Fast and accurate for typical text sizes.\n- **Hirschberg (linear memory)**: Hirschberg's divide-and-conquer algorithm with O(n) space complexity. Automatically used for very large inputs to reduce memory use.\n\n### Browser Compatibility\n\nWorks in all modern browsers that support:\n- ES6 JavaScript\n- LocalStorage\n- CSS Variables\n\n## Privacy\n\n- No data collection\n- No cookies\n- No third-party tracking\n- Optional: Theme preference stored in localStorage only\n\nSee [Privacy Policy](https://diffvoid.com/privacy.html), [Terms of Service](https://diffvoid.com/tos.html), and [About](https://diffvoid.com/about.html) for details.\n\n## Development\n\n### Project Structure\n\n```\npublic/\n├── index.html       # Main HTML structure\n├── script.js        # Comparison logic and UI\n├── shared-diff.js   # Shared diff rendering (invisibles, HTML generation)\n├── worker.js        # Web Worker for off-thread diff rendering\n├── theme.js         # Theme toggle and persistence\n├── style.css        # Styling with CSS variables\n├── shared.css       # Shared styles for static pages\n├── favicon.svg      # Site favicon\n├── tos.html         # Terms of Service\n├── privacy.html     # Privacy Policy\n├── about.html       # About page\n├── robots.txt       # Robots exclusion rules\n└── sitemap.xml      # Sitemap\n```\n\n### Running Locally\n\nSimply open `public/index.html` in a browser, or serve with any static file server:\n\n```bash\n# Using Python 3\npython -m http.server 8000 --directory public\n\n# Using Node.js\nnpx serve public\n```\n\nThen visit `http://localhost:8000`\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Author\n\nTimo Heimonen  \u003ctimo.heimonen@proton.me\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimoheimonen%2Fdiffvoid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimoheimonen%2Fdiffvoid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimoheimonen%2Fdiffvoid/lists"}