Getting started
Deterministic comparison shows what changed. AI explains what it means.
Paste or load a "Before" and "After" document into the two panels on the home page and click Compare. DiffFind always runs a deterministic diff first — that result is never overwritten or replaced by AI output, only annotated with an optional interpretation on top of it.
Comparison modes
Set the Format dropdown to match your content, or leave it on auto-detect:
| Format | What's compared |
|---|---|
| Text | Character, word, sentence, line, or paragraph-level diff |
| JSON / YAML / XML | Structural diff by JSON Pointer path, not raw text |
| CSV | Structural diff by row/column path (e.g. /3/price) |
Structural formats still get the line-numbered inline text view alongside the path-based change cards — you don't need to switch formats to see both.
Loading input
Each Before/After panel has a loader dropdown so you don't have to hand-copy content:
- Plain — type or paste directly (default).
- URL — fetches a GET request server-side and loads the response body.
- cURL — paste a full
curlcommand; it's parsed and executed server-side. - File — reads a local file directly in the browser, including PDF (extracted via pdf.js and compared as text; when both sides are PDFs, the diff renders directly on the rendered pages) and XLS/XLSX (extracted via SheetJS — every sheet becomes an array of row objects, wrapped in one JSON object keyed by sheet name, then compared as JSON).
POST /v1/load with a 15s timeout and a 5MB response cap. It fetches whatever URL it's given — don't expose it to untrusted input without an allowlist.
Pretty print
The Pretty print checkbox reformats minified JSON/YAML/XML/CSV into
readable, indented text (via POST /v1/format), and keeps auto-reformatting
anything subsequently loaded via curl/URL/File. Unchecking it restores each side's exact
original content.
Analysis & AI providers
The Analysis dropdown controls how much AI does on top of the deterministic diff:
- Semantic + Lexical (default) — shows both the raw diff and the AI interpretation.
- Lexical — deterministic-only, no API key needed.
- Semantic — still runs the deterministic diff, but the UI favors the AI interpretation over raw diff detail.
Every fact an AI interpretation cites is checked against the source documents before being shown, with a verification status on each one.
Open Settings (the gear icon) to choose which model powers semantic analysis — Built-in (no AI) (default, no API key), Claude, OpenAI, Gemini, Groq, or OpenRouter — and to store an API key for whichever provider you pick. Each provider's model dropdown offers Default as the first option — pick it and DiffFind always uses whichever model it currently recommends for that provider, so you never have to come back and update your choice when a newer model ships. Pick a specific model instead if you want to pin an exact version. Click Save at the bottom of the panel to confirm your changes.
Get an API key from whichever provider you want to use:
- Claude
- OpenAI
- Gemini
- Groq — has a free tier.
- OpenRouter — has a free tier; its Default model always routes to a free backend.
On the hosted app, connecting a real AI provider requires being signed in — if you're browsing anonymously, Settings only offers Built-in (no AI), since there's no account to store a key against yet. Log in to connect one.
Find & history
The find bar searches the raw text you're about to compare — type a query and matches highlight directly in the Before/After panels, with a scope selector for Both / Before / After. Click Clear to reset just the find query, results, and highlights, without touching the Before/After content or your comparison options.
Check Semantic to search by meaning instead of exact text — it finds passages related to your query even when the wording doesn't match at all. This always runs entirely on your own machine using a small local embedding model — no API key, no external calls needed. It doesn't search as you type: click Search (or press Enter) to run it, and it works with or without having run a comparison first. Results appear in a collapsible Match details list below — each match shows a snippet and a similarity score, and clicking one jumps straight to it.
When a real AI provider is configured in Settings (the same one used for semantic analysis after a comparison), Find automatically layers an optional second pass on top: the provider re-ranks each side's already-found matches for true relevance — Before and After independently, never combined — and, when one of them genuinely answers your query, surfaces a short answer in its own always-visible Answer box above the collapsible match list (a side without an answer shows a struck-out "No answer found"). Searching both documents at once can show an answer for each side, so you can compare them directly instead of seeing only one. Clicking an answer pinpoints the exact phrase it's grounded in — asking "who is the tenant" and getting back "The tenant is Alex J. Morgan." highlights just "Alex J. Morgan", not the whole sentence — while Previous/Next and clicking a match card still highlight the whole passage as usual. With Settings on Default, Find behaves exactly as described above; a failed re-rank never breaks the search, it just falls back to that side's local ranking with no answer shown, and clicking an answer with no locatable phrase just highlights the whole match instead.
Built-in answers (no AI). With no AI provider selected, Semantic Find can still answer direct questions such as "who is the tenant" or "what is the termination date". It ranks passages with local meaning-based and keyword scoring, then copies the answer word for word from your document — nothing is written or paraphrased, and no external AI is called or sent your text. The answer appears in the Answer box with the supporting quote when it differs from the answer (hover for the page, section and "Extracted from the document by DiffFind (no AI)"); click it to jump to and highlight the exact spot. When it isn't sure — topic searches like "termination clause", facts the document doesn't state, conflicting or "except/unless" wording — it shows the ranked passages and a struck-out "No answer found" for each side. It is the default whenever no AI provider is selected (Built-in (no AI)) — there is nothing to switch on. The same mode runs the deterministic comparison, and the provider chip in the header shows Built-in (no AI), with "Answers: Built-in" in its tooltip. An AI provider's answer, or its decision to give no answer, is never replaced by the built-in one, and Lexical Find and comparisons never use it.
A History dropdown recalls your last 10 unique comparisons (stored in
your browser via localStorage) and restores each side the way it was
originally loaded.
Inline diff view
After comparing text, a side-by-side inline diff view shows both full documents, line-numbered, with character-level highlighting inside each changed line. A minimap next to each pane marks every changed line and the current scroll position — click it to jump straight there. Every change card is also clickable and scrolls both panes to that change.
REST API
Everything the UI does is available directly from the API — nothing is UI-only. Full request/response schemas are in the OpenAPI reference.
POST /v1/compare
{
"before": "Payment is due in 30 days.",
"after": "Payment is due in 15 days."
}
| Endpoint | Purpose |
|---|---|
POST /v1/compare | Run a comparison, with optional AI semantic analysis |
POST /v1/find | Semantic search (local embedding model) over raw Before/After content |
POST /v1/load | Fetch document content from a URL or curl command |
POST /v1/format | Pretty-print JSON/YAML/XML/CSV content |
POST /v1/locate | Map a structural change's path to its source line number |
GET /health | Liveness check |
Account & API keys
These apply to the hosted app when you're signed in — local mode has no account to manage (your provider keys there are just environment variables on your own machine).
Removing a stored API key — open Settings (the gear icon) and click Remove next to a connected provider, or do the same from the Account page. Either way the key is deleted immediately, not just disconnected — it's gone from the database, not recoverable.
Deleting your account — go to the Account page and scroll to Delete account. Type your email address to confirm, then click Delete my account. This permanently removes your account, active sessions, saved settings, and any connected API keys in one step — there's no undo, and no confirmation email is sent, so make sure before you click.
Chrome extension
DiffFind Launcher is an optional Chrome extension that adds a toolbar button for opening DiffFind in its own app-style window. It is only a launcher — all comparing still happens here in the app.
- Install — add it from the Chrome Web Store (Chrome 102 or later) and pin it from Chrome's extensions menu.
- Open — click the DiffFind icon, then Open DiffFind. Launching again restores and focuses your existing window, with your current comparison as you left it, instead of opening a duplicate. If you closed the window, the next launch opens a new one.
- Self-hosted — click Configure in the popup, enter the http or https URL of your DiffFind instance, and click Save. Reset returns to
https://app.difffind.com. A window that is already open keeps its current page. - Privacy — it requests only Chrome's
storagepermission (to remember your window for the session and the URL you set), and does not read page content, browsing history, documents, or AI-provider keys.
After restarting the browser, or reloading, updating, or re-enabling the extension, close any old DiffFind window before launching again to avoid a second window. More details on the DiffFind website.
Support
Questions? Email support@difffind.com. Found a bug or have a feature request? Open an issue on GitHub.