CLI Reference¶
Diffract can be used in two ways from the command line:
- GUI mode - launch the app and pre-load one or two paths into the comparison view.
- Headless mode - run a comparison entirely in the terminal with no window, writing the result to standard output.
GUI mode¶
Open a file comparison:
Open a directory comparison:
Pre-fill only the left side:
Open the welcome screen (no pre-loaded paths):
Single-instance behaviour¶
If Diffract is already running when you invoke it from the command line, the new paths are sent to the running instance via a TCP loopback connection. A new comparison tab opens in the existing window without launching a second process.
The running instance's port is written to {systemTemp}/diffract_port.txt when the app starts. The CLI launcher reads this file to locate the running instance. If the file is absent or the connection fails, a new Diffract process is started.
Path rules¶
- Paths can be absolute or relative to the current working directory.
- If both paths point to directories, a directory comparison opens.
- If one path is a file and the other is a directory, Diffract opens the file and leaves the directory-side path bar empty.
- Archive files (
.zip,.tar.gz,.jar) open in archive comparison mode (Pro). - Image, Excel, Word, and PDF files open in their respective comparison modes (Pro).
Exit behaviour¶
GUI mode returns immediately after sending the paths to the running instance (or after launching a new process). It does not wait for the comparison to complete.
Note
For use as a git difftool, see Git Integration.
Headless mode¶
Headless mode runs a comparison without opening any window and prints the result to standard output. It is intended for scripts, CI pipelines, and editor integrations.
Basic usage¶
Directory comparison:
Options¶
| Option | Description |
|---|---|
--format / -f |
Output format: unified (default), json, or summary. |
--exit-code |
Exit with code 0 if files are identical, 1 if they differ. Without this flag the exit code is always 0 on success. |
--algo |
Diff algorithm: myers (default), patience, histogram. semantic is also available with a Pro licence. |
--ignore-case |
Treat uppercase and lowercase letters as identical. |
--ignore-whitespace |
Ignore all whitespace differences. |
--ignore-trailing-whitespace |
Ignore trailing spaces and tabs on each line. |
--ignore-line-endings |
Treat CRLF and LF line endings as identical. |
--auth-header |
HTTP header for remote (http/https) paths, e.g. --auth-header "Authorization: Bearer <token>". Repeatable. (Pro) |
--ssh-password |
Password for ssh/scp remote paths. (Pro) |
--ssh-key |
Path to an OpenSSH ed25519 or RSA private key for ssh/scp paths. |
--ssh-passphrase |
Passphrase for an encrypted --ssh-key. |
--aws-access-key / --aws-secret-key |
AWS access key ID / secret for s3:// paths. (Pro) |
--aws-region |
AWS region for s3:// paths (default us-east-1). |
--aws-endpoint |
Custom S3-compatible endpoint (MinIO / R2 / Wasabi) for s3:// paths. |
--azure-account |
Azure storage account name for az:// paths. |
--azure-key / --azure-sas |
Azure shared key / SAS token for az:// paths. |
--gcs-token |
GCS OAuth bearer token for gs:// paths. |
--ftp-user / --ftp-password |
Username / password for ftp:// / ftps:// paths (default: anonymous). (Pro) |
--help / -h |
Print usage information and exit. |
Remote paths¶
Either path argument can be a remote URL. Diffract fetches it to a temporary file and then runs the normal comparison.
HTTP / HTTPS - public URLs need no extra flags:
For authenticated endpoints, pass one or more --auth-header flags:
diffract --headless compare \
https://api.example.com/config.yaml local/config.yaml \
--auth-header "Authorization: Bearer $TOKEN"
SSH / SFTP - use an scp://user@host[:port]/path (or user@host:/path) path
with a password or an ed25519 key:
# Password auth
diffract --headless compare scp://deploy@web01/etc/nginx/nginx.conf ./nginx.conf \
--ssh-password "$SSH_PASSWORD"
# Key auth
diffract --headless compare deploy@web01:/etc/hosts ./hosts \
--ssh-key ~/.ssh/id_ed25519
Cloud object storage - compare an s3://, az://, or gs:// object:
# Amazon S3 with explicit keys
diffract --headless compare s3://my-bucket/config.yaml ./config.yaml \
--aws-access-key "$AWS_ACCESS_KEY_ID" \
--aws-secret-key "$AWS_SECRET_ACCESS_KEY" --aws-region us-east-1
# S3-compatible (MinIO/R2/Wasabi) via a custom endpoint
diffract --headless compare s3://my-bucket/config.yaml ./config.yaml \
--aws-access-key KEY --aws-secret-key SECRET --aws-endpoint http://localhost:9000
# Azure Blob (SAS token) and GCS (bearer token)
diffract --headless compare az://container/config.yaml ./config.yaml \
--azure-account myacct --azure-sas "$AZURE_SAS"
diffract --headless compare gs://my-bucket/config.yaml ./config.yaml \
--gcs-token "$(gcloud auth print-access-token)"
With no --aws-* keys (and no region/endpoint), S3 paths use the default AWS
credential chain (environment variables, then ~/.aws/credentials); public
buckets/objects work with no credentials at all.
FTP / FTPS - compare an ftp:// or ftps:// file:
# Authenticated FTPS (TLS)
diffract --headless compare ftps://files.example.com/pub/app.yaml ./app.yaml \
--ftp-user deploy --ftp-password "$FTP_PASSWORD"
# Anonymous FTP (no flags needed)
diffract --headless compare ftp://files.example.com/pub/readme.txt ./readme.txt
With no --ftp-user, FTP paths log in anonymously. Plain ftp:// is
unencrypted; prefer ftps:// on untrusted networks.
Host keys are trusted on first use and checked against ~/.ssh/known_hosts; a
changed host key exits with code 2. An unreachable, denied, or directory path
also exits with code 2 and a message on standard error. (Remote comparison
requires a Pro licence in the GUI; the headless paths are provided for CI and
scripting.)
Output formats¶
unified (default) - standard unified diff:
json - array of diff objects, one per line pair:
[
{
"status": "same",
"leftLine": 1,
"rightLine": 1,
"leftContent": "line one",
"rightContent": "line one"
},
{
"status": "modified",
"leftLine": 2,
"rightLine": 2,
"leftContent": "line two",
"rightContent": "line TWO"
},
{
"status": "same",
"leftLine": 3,
"rightLine": 3,
"leftContent": "line three",
"rightContent": "line three"
}
]
summary - single line with counts:
Fields: added lines (+), removed lines (-), modified lines (~), unchanged lines (=). A ⇕N field is appended when moved blocks are detected.
For directory comparisons the summary counts files, not lines, and uses [+], [-], [~], and [=] badges per entry.
Exit codes¶
| Code | Meaning |
|---|---|
0 |
Success. Files are identical, or differ and --exit-code was not passed. |
1 |
Files differ (only when --exit-code is passed). |
2 |
Error (missing path, unreadable file, bad arguments). |
Examples¶
Check whether two config files differ in a script:
diffract --headless --exit-code prod.conf staging.conf
if [ $? -eq 1 ]; then echo "configs differ"; fi
Export a comparison as JSON for further processing:
Case-insensitive summary of two directories:
AST-aware semantic comparison (Pro licence required):
Note
--algo semantic requires a valid Pro licence key to be activated on the machine. It falls back to Myers silently if no licence is present or the language is unsupported.