CLI reference
Commands, options and defaults for difora 0.8.3 (Node 24.22.1+).
Install
difora from npm (or
read the
GitHub README if
npm does not load): npm install --save-dev difora.
Commands
-
npx difora upload ./screenshots: upload all PNGs under the directory, compare and print a review link. Requires a project token and a detected or explicit branch. Names are relative paths without.png; directories are traversed and symlinks are skipped. -
npx difora doctor: print detection, API health and a token check when a token is supplied. It exits 0 when the checks pass; a missing token is reported but does not itself cause failure. It prints text, including when passed--json. -
npx difora --help(also-horhelp): print help and exit 0. Running without a command prints help and exits 2. -
npx difora --version(also-v): print the version and exit 0.
Upload options
Read commands (0.13.0+): use
npx difora builds to list results and
npx difora inspect 42 to inspect a project build number.
They require DIFORA_READ_TOKEN, support
--json and exit 0 for successful reads regardless of review
status. See the read API guide for filters,
explicit build IDs, permissions and safe image downloads.
Explicit flags override their environment equivalents; environment overrides beat detection. Defaults below apply when neither is supplied. Boolean flags take no argument.
| Flag | Argument | Default | Environment equivalent | Meaning |
|---|---|---|---|---|
--branch |
<name> | Detected CI/local Git branch | DIFORA_BRANCH | Override the uploaded branch; required if detection finds none. |
--commit |
<sha> | Detected CI/local Git commit; otherwise empty | DIFORA_COMMIT | Override the commit SHA. |
--message |
<text> | Detected commit message; otherwise empty | DIFORA_COMMIT_MESSAGE | Set the build commit message (up to 500 characters). |
--api-url |
<url> | https://app.difora.eu/api | DIFORA_API_URL | Choose the Difora API base URL. |
--token |
<token> | Required for upload | DIFORA_TOKEN | Authenticate with a project CI token; prefer the environment variable. |
--no-wait |
— | Off (wait for comparison) | — | Return after finalizing the upload; an unfinished comparison returns exit 0. |
--exit-zero-on-changes |
— | Off | — | Return 0 for changes awaiting review; rejected/error builds still return 1. |
--timeout |
<seconds> | 300 | — | Wait up to this positive number of seconds after upload finalization. |
--concurrency |
<n> | 4 | — | Number of simultaneous image uploads; positive integer, capped at 16. |
--json |
— | Off | — | Print the upload result as JSON on stdout; send progress to stderr. |
--post-status |
— | Off | DIFORA_STATUS_TOKEN supplies credentials | Post repository commit statuses from CI; does not post PR/MR comments. |
--parallel |
— | Off unless a shard or parallel ID is configured | DIFORA_SHARD / DIFORA_PARALLEL_ID | Combine uploads into one build; requires valid shard coordinates. |
--shard |
<i>/<n> | CI shard coordinates in parallel mode | DIFORA_SHARD | Set the one-based shard index/count (1 ≤ i ≤ n ≤ 256); enables parallel mode. |
--parallel-id |
<key> | Environment override, then provider/run ID, then commit SHA | DIFORA_PARALLEL_ID | Set the shared group ID (1–200 characters); enables parallel mode. |
--shard-timeout |
<minutes> | Project setting (initially 30) | — | Allow 1–1440 minutes for shard uploads; enables parallel mode. |
--base-branch |
<name> | Detected PR target, otherwise project baseline branch | DIFORA_BASE_BRANCH | Set the target branch for merge-base comparison. |
--base-commit |
<sha> | Resolved merge-base when available | — | Use an explicit ancestor SHA (7–64 hexadecimal characters). |
--no-merge-base |
— | Off | — | Use current branch baselines and skip merge-base resolution, including an explicit base commit. |
--config |
<file> | difora.config.json in screenshot directory, then working directory | — | Load snapshot rules from this JSON path; no file means no repository rules. |
--pr |
<number> | Detected PR/MR number; otherwise unset | DIFORA_PR_NUMBER | Set a PR/MR number from 1 to 2147483647; comments still require a configured integration. |
--base-commit is used for feature-branch comparisons;
uploading to the base branch itself does not select an ancestor. Missing
Git history produces a warning and a fallback to current baselines. See
checkout depth and target fetching.
The doctor command accepts the same option syntax for
checking detection and credentials; upload, capture and comparison
options do not make it upload screenshots. Invalid environment overrides
can fail before a flag is applied; remove an invalid variable rather
than trying to override it.
Environment variables
DIFORA_TOKEN, DIFORA_API_URL,
DIFORA_BRANCH, DIFORA_COMMIT,
DIFORA_COMMIT_MESSAGE, DIFORA_PR_NUMBER,
DIFORA_BASE_BRANCH, DIFORA_SHARD and
DIFORA_PARALLEL_ID correspond to the options above.
-
DIFORA_STATUS_TOKEN: credentials for--post-status. GitHub falls back toGITHUB_TOKEN; GitLab falls back toCI_JOB_TOKENwhere permitted. Bitbucket Cloud requiresDIFORA_STATUS_TOKEN. Setting a token alone does not enable statuses. See provider permissions. -
DIFORA_SCREENSHOT_DIR: output directory for the Playwright and Storybook helpers. A helper'sdiroption wins; the default is./screenshots. This does not set the CLI's upload directory. -
PERCY_PARALLEL_NONCEandPERCY_PARALLEL_TOTAL: compatibility aliases for group ID and shard count. Difora overrides win; a valid shard index is still required.
Branch/commit detection supports GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI, Jenkins, Azure DevOps, Travis, Buildkite and Drone, then the local Git checkout. PR/MR builds use the source branch. A detached local checkout needs an explicit branch. Use a scratch branch for local trials and approve baselines only from CI or its exact rendering environment.
Exit codes
| Code | Meaning |
|---|---|
0 |
Passed or approved; also pending review with --exit-zero-on-changes, or an unfinished build with --no-wait. |
1 |
Changes await review, the build was rejected, or comparison failed. |
2 |
Usage, configuration, authentication or upload failure, including the monthly snapshot limit. |
3 |
Waiting timed out; the build continues and its review URL shows the eventual result. |
Repository status-posting failures print a warning and do not change the comparison's exit code. Use the review link to distinguish visual changes from processing errors.
Snapshot usage and retries
Each submitted snapshot counts once when a build starts comparison, including unchanged images and all shards, against your organization's UTC calendar-month allowance; a new build attempt counts again.
Run pull requests and pushes to main only so a PR branch is
not uploaded twice; each new build counts toward snapshot usage.
For example, 20 named PNGs in each of 10 new builds use 200 snapshots even when every image is unchanged. Already-stored image data is not transferred again, but its named snapshots still count. Detected removals do not add usage.
- Uploading images or retrying requests within the same build does not add additional usage. An incomplete upload that never starts comparison uses none.
- Re-running comparison on an existing build does not count again, including after changing thresholds. A comparison error does not remove its usage.
- Running a fresh non-sharded upload creates a new build and counts again. A new parallel attempt counts its whole combined suite, including copied shards. Repeated finalization of the same shard does not count twice.
- Projects in one organization share its allowance; Free allows one project, paid plans allow unlimited projects. Separate organizations have separate plans.
Native and mobile captures
CLI 0.12.0 adds
difora annotate <dir> --platform ios for declared
device metadata. Record PNGs with your own tooling, keep stable variant
names, then upload normally. See
native, mobile and PDF capture recipes
for flags, compatibility and verified toolchains.