Skip to Content
🎉 ShotSweep is live! Launched on NFSFU234 Open Source Day.
DocsOutputThe Manifest

The manifest

Every capture run writes a manifest.json into --out. It’s the machine-readable record the rest of ShotSweep — and your own tooling — builds on: diff matches entries by URL and viewport, --describe summarizes it, and CI scripts can parse it directly.

Shape

Each entry corresponds to one screenshot (or one failed attempt):

manifest.json
[ { "url": "https://example.com", "mode": "full", "viewport": "1440x900", "file": "screenshots/example.com/home/full-1440x900.png", "sizeBytes": 482113, "timestamp": "2026-08-10T09:14:22.104Z", "warnings": [ "19 of 19 image(s) didn't finish loading and will appear blank or as alt text. Try --image-wait 30000, ..." ] }, { "url": "https://example.com/dashboard", "mode": "full", "viewport": "1440x900", "error": "page.goto: Timeout 30000ms exceeded.", "timestamp": "2026-08-10T09:14:53.881Z" } ]

Successful entries have file and sizeBytes; failed entries have error instead, with no file. Two optional fields add detail:

  • warnings — present when a page was captured with a caveat, such as a load timeout or images that didn’t finish. The capture still succeeded.
  • selector — present on --mode element entries.

file always uses forward slashes, even when captured on Windows, so a manifest from one machine can be compared on another (for example diff in Linux CI). Any user:password@ in a URL is masked.

How repeated runs merge

A capture run merges into any existing manifest at the same --out path instead of overwriting it. Entries are tracked per job (URL + mode + viewport, plus the selector for element captures):

  • A job that succeeds replaces every earlier entry for that job, including old errors.
  • A job that fails replaces earlier errors for that job but keeps an earlier success, since that screenshot is still on disk.
  • Entries for other jobs are left alone.

So the manifest reflects the current state of the folder instead of growing with stale failures. It is written atomically, so an interrupted run can’t leave a half-written file. If an existing manifest.json can’t be parsed, it is moved aside as manifest.json.corrupt-<timestamp> and a fresh one is started, rather than being overwritten.

The run record

Unless you pass --no-record, each run also writes run-record.json next to the manifest: a snapshot of the tool version, Playwright and Chromium versions, Node version, OS and architecture, the resolved configuration, and a SHA-256 hash of every screenshot from that run.

--bearer, --header, --cookie and --session are recorded as [REDACTED], and credentials inside URLs are masked. shotsweep diff reads the record to flag environment drift between two runs.

Where it’s used

  • shotsweep diff reads two manifests and matches screenshots by URL + viewport.
  • --describe groups the manifest by page to build its summary.
  • CI — parse it directly, or use --json on the capture command for a run-level summary instead of the full per-file manifest.
Last updated on