@reshotdev/screenshot
v0.0.1-beta.57
Published
Record and run versioned Product Journeys with visual, accessibility, and publication evidence
Maintainers
Readme
@reshotdev/screenshot
Reshot is Product Journey Infrastructure: the living system of record for how a software product works. This CLI lets developers define, import, record, and execute versioned Product Journeys while preserving their outcomes, source, context, and evidence.
A Run keeps functional, visual, and accessibility evidence together. Attributable Review Decisions can then produce governed documentation, support, training, demos, marketing media, Publications, and Release Books from the same approved source truth.
Status: Beta (0.x). The API may change between minor versions.
Install
npm install -g @reshotdev/screenshotRequires Node.js >= 18. Playwright browsers are installed automatically on first run.
Quick Start
# 1. Interactive setup wizard
reshot setup
# 2. Start your app with a production-like local server
npm run build
npm run start
# 3. Execute the configured Journey locally
reshot run
# 4. Inspect the evidence envelope before hosted submission
reshot evidence --dry-runFor launch-grade reliability, do not treat next dev as the supported capture
runtime. Use a production-like local server and see the
Supported Environments guide.
For the canonical repository workflow—native Playwright discovery/import,
Journey creation, execution, Review, publication, and export—run
reshot journey --help. There is no flag that approves on your behalf: every
Decision remains attributable.
OAuth / magic-link / Supabase apps: use
playwright codegen $YOUR_APP --save-storage=.reshot/auth-state.jsononce, then set"storageStatePath": ".reshot/auth-state.json"in your config — or setRESHOT_SESSION_STATEin CI. See Authentication below for details.
Configuration
Start with one flow in reshot.config.json. A target contract is not required:
{
"baseUrl": "http://localhost:3000",
"assetDir": ".reshot/output",
"viewport": { "width": 1280, "height": 720 },
"scenarios": [
{
"key": "homepage",
"name": "Homepage hero",
"url": "/",
"steps": [
{ "action": "waitForSelector", "selector": "main" },
{ "action": "screenshot", "key": "hero", "description": "Hero section" }
]
}
]
}Run reshot run, inspect the local output, then use reshot evidence --dry-run
to inspect the retained evidence envelope. Add authentication and context
dimensions after this first Journey is working.
Commands
| Command | Description | Key Flags |
| --- | --- | --- |
| reshot setup | Interactive config wizard | --offline, --force |
| reshot journey | Canonical Journey authoring, import, Run, Review, publication, and export | --help |
| reshot runner | Customer-local authenticated Journey runner | --help |
| reshot run | Execute capture scenarios | --scenarios, --diff, --all-variants, --concurrency, --no-headless |
| reshot record [title] | Interactive recording via Chrome DevTools | --browser, --url, --port |
| reshot import-tests | Import existing Playwright work into Journey mappings | --dry-run, --no-interactive |
| reshot evidence | Submit or inspect the last Run's evidence envelope | --manifest, --dry-run |
| reshot barriers | Inspect accessibility barriers attached to Journey evidence | --status, --criterion, --json |
| reshot doctor target | Audit target routes, readiness, and auth contract | --scenarios, --json |
| reshot doctor release | Run preflight, target, and docs-asset checks | --scenarios, --json |
| reshot status | View Journey, Run, publication, and open-barrier status | --jobs, --drifts, --json |
| reshot auth | Link the CLI to a Reshot project | RESHOT_API_KEY, RESHOT_PROJECT_ID |
Advanced: Certified Targets
Certified targets are optional release contracts for established integrations.
They add explicit runtime, ownership, authentication, readiness, route, and
artifact requirements to the same basic flow configuration. Most integrations
should omit target until capture and publish are already working.
Add a target block when the app needs these stronger guarantees:
{
"target": {
"key": "product-app",
"displayName": "Product App",
"tier": "certified",
"owner": "Product Platform",
"baseUrl": "http://localhost:3000",
"captureSafe": false,
"supportedLocalCommand": "npm run build && npm run start",
"defaultAuthMode": "fixture",
"requiredEnv": ["PROJECT_ID"],
"certificationScenarioKeys": ["dashboard"]
}
}Certified scenarios can additionally declare ready, requiredRoutes,
requiredSelectors, expectedArtifacts, and publishPolicy fields.
Certification workflow
Use these commands when a target app needs release-grade verification:
reshot doctor target
reshot run --scenarios dashboard
reshot doctor release --scenarios dashboardRelease-doctor reports are written to .reshot/reports/release-doctor.json.
Step Types
Steps define a sequence of browser actions within a scenario:
| Step | Description | Key Properties |
| --- | --- | --- |
| wait | Pause execution | ms |
| screenshot | Capture current viewport | key, description |
| click | Click a DOM element | selector, optional |
| type | Type text into an input | selector, text |
| keyboard | Send keyboard input | key (e.g., "Meta+k", "Enter") |
| waitForSelector | Wait for element to appear | selector, timeout |
| navigate | Go to a URL | url |
| fillForm | Fill multiple form fields | fields (selector-to-value map) |
Variant System
Capture the same scenario across multiple dimensions (themes, locales, roles) without duplicating config:
{
"variants": {
"dimensions": {
"theme": {
"label": "Color Theme",
"options": {
"light": {
"name": "Light Mode",
"inject": [
{ "method": "localStorage", "key": "theme", "value": "light" },
{ "method": "browser", "colorScheme": "light" }
]
},
"dark": {
"name": "Dark Mode",
"inject": [
{ "method": "localStorage", "key": "theme", "value": "dark" },
{ "method": "browser", "colorScheme": "dark" }
]
}
}
},
"locale": {
"label": "Language",
"options": {
"en": {
"name": "English",
"inject": [
{ "method": "browser", "locale": "en-US" }
]
},
"de": {
"name": "German",
"inject": [
{ "method": "browser", "locale": "de-DE", "timezone": "Europe/Berlin" }
]
}
}
}
},
"presets": {
"all-themes": { "name": "All Themes", "dimensions": ["theme"] },
"matrix": { "name": "Full Matrix", "dimensions": ["theme", "locale"] }
}
}
}Run all variants:
reshot run --all-variants
# Captures: homepage/light/en, homepage/light/de, homepage/dark/en, homepage/dark/deInjection methods: localStorage, sessionStorage, browser (colorScheme, locale, timezone), cookie, queryParam.
Viewport Presets
Use preset names in your config or with the --viewport flag:
| Category | Preset | Resolution | Scale |
| --- | --- | --- | --- |
| Desktop | desktop-hd | 1920x1080 | 1x |
| Desktop | desktop | 1280x720 | 1x |
| Desktop | desktop-retina | 1280x720 | 2x |
| Tablet | tablet-landscape | 1024x768 | 2x |
| Tablet | tablet-portrait | 768x1024 | 2x |
| Mobile | mobile | 375x667 | 2x |
| Mobile | mobile-large | 414x896 | 3x |
| Docs | docs-wide | 1200x800 | 2x |
| Docs | docs-standard | 960x640 | 2x |
| Social | social-og | 1200x630 | 2x |
| Social | social-twitter | 1200x600 | 2x |
Visual Diffing
Compare captures against baselines to detect changes:
{
"diffing": {
"enabled": true,
"threshold": 0.1,
"antialiasing": true,
"ignoreRegions": [
{ "x": 0, "y": 0, "width": 1280, "height": 50 }
]
}
}# Run with diffing enabled
reshot run --diff
# Compare against cloud baselines
reshot run --diff --cloudPixel-level comparison using pixelmatch. The threshold (0-1) controls sensitivity — 0.1 means 10% pixel difference tolerance. antialiasing: true compensates for font rendering differences across platforms. ignoreRegions excludes dynamic areas like timestamps or ads.
Interactive Recording
Record scenarios by interacting with your app in a real browser:
# Launch Chrome and start recording
reshot record "Checkout Flow" --browser --url http://localhost:3000During recording:
- Press S to capture a screenshot step
- Press C to start/stop a video clip
- Press Q to quit and save
The recorded scenario is appended to reshot.config.json automatically.
Authentication
Storage State (recommended)
For OAuth, magic-link, Supabase Auth, Clerk, Auth.js, and any other modern auth flow that can't be scripted with form fields, capture a Playwright storage state once and let reshot reuse it for every scenario:
npx playwright codegen http://localhost:3000 --save-storage=.reshot/auth-state.jsonThen point your config at it:
{
"storageStatePath": ".reshot/auth-state.json"
}reshot record does the same thing interactively and writes to
~/.reshot/session-state.json by default.
CI (no browser to record from)
A GitHub Actions runner has no Chrome to sync a session from, so pass the storage state in as a secret:
env:
RESHOT_SESSION_STATE: ${{ secrets.RESHOT_SESSION_STATE }}RESHOT_SESSION_STATE accepts either the storage-state JSON inline (paste the
file contents into the secret) or a path to a file in the checkout. It takes
precedence over storageStatePath, which in turn takes precedence over
~/.reshot/session-state.json. Use a dedicated test account: the state is a
live session for whoever captured it.
Test backdoors
If your app has a dev/test backdoor that bypasses auth at the server layer
(for example a /api/devtools fixture endpoint, a header-based
impersonation hook, or a localhost-only cookie), you can point reshot at it
via baseUrl and skip storage state entirely. This is often the cleanest
option for first-party apps that already maintain such an endpoint for
testing.
Login Steps (password forms only) — NOT IMPLEMENTED
auth.loginSteps is documented here as intent only: no CLI code reads it.
Use Storage State above, including for password forms. The shape it will
take when it ships:
{
"auth": {
"loginUrl": "http://localhost:3000/login",
"loginSteps": [
{ "action": "type", "selector": "input[name='email']", "text": "${EMAIL}" },
{ "action": "type", "selector": "input[name='password']", "text": "${PASSWORD}" },
{ "action": "click", "selector": "button[type='submit']" },
{ "action": "waitForSelector", "selector": "[data-authenticated='true']" }
]
}
}loginSteps will not be able to drive OAuth, magic-link, or any
redirect-based flow — Storage State above is the path for those.
Output Formats
Step-by-Step Images (default)
.reshot/output/dashboard/20260315-120000/theme-light/
├── step-0-overview.png
└── step-1-analytics.pngVideo Recording
Set "format": "summary-video" in scenario output config to record the full browser session as MP4.
Selective Capture (Crop)
{
"output": {
"crop": {
"enabled": true,
"selector": ".modal-dialog",
"padding": 16
}
}
}Crops the screenshot to the bounding box of the selected element.
Automation in Scripts
Use headless mode with environment variables to integrate into build scripts or local workflows:
# In your Makefile or build script
export RESHOT_API_KEY=$(cat .reshot/api-key)
reshot run --scenarios dashboard --no-headless false
reshot evidenceSet RESHOT_API_KEY and RESHOT_PROJECT_ID to run without interactive auth:
RESHOT_API_KEY=your-key RESHOT_PROJECT_ID=your-project reshot runFor headless execution, ensure:
- Your app is running on localhost (e.g.,
npm run build && npm run start) headless: trueis set inreshot.config.json- API credentials are available as environment variables
Canonical Journey Export
Export a Journey from the explicit local authoring cache when an offline, portable definition is required:
reshot journey export <journey-id> --format json --offlineSupported formats are TypeScript, JSON, and YAML. The --offline flag is
required so a local-cache export cannot be mistaken for current hosted truth.
Accessibility Barrier Inspection
Accessibility barriers remain a first-class Journey capability and can be inspected without turning them into a separate product hierarchy:
# List open barriers
reshot barriers --status open
# Filter by WCAG criterion and emit machine-readable output
reshot barriers --criterion 1.4.3 --jsonStandalone Mode
Run without any cloud connection:
reshot setup --offlineLocal capture, recording, and diffing remain available. Hosted Journey, evidence, Review, Publication, and Network operations require project authentication.
Limitations
- Beta release. The CLI interface and config format may change between minor versions.
- Playwright browsers are downloaded on first run (~200MB for Chromium).
- Video recording requires Chromium (Firefox and WebKit support screenshots only).
- Hosted Journey and evidence operations require a Reshot account at reshot.dev.
- Privacy masking (automatic PII redaction) is best-effort and should not be relied on for compliance.
Documentation
License
Apache-2.0. See LICENSE.
