JavaScript SDK Overview
The Vizzly JavaScript SDK captures screenshots from your tests and sends them to the Vizzly CLI for comparison. It’s a single function call that works with any test framework.
Installation
Install the CLI (which includes the client):
npm install -D @vizzly-testing/cliThe CLI handles comparisons, uploads, and API communication. The client just sends it screenshots.
Import in your tests:
import { vizzlyScreenshot } from '@vizzly-testing/cli/client';Quick Start
import { test, expect } from '@playwright/test';import { vizzlyScreenshot } from '@vizzly-testing/cli/client';
test('homepage visual test', async ({ page }) => { await page.goto('/'); await expect(page.locator('h1')).toBeVisible();
const screenshot = await page.screenshot(); await vizzlyScreenshot('homepage', screenshot);});The SDK posts the screenshot to the CLI’s local server. The CLI does the actual work.
Running Tests
Local Development (TDD Mode)
TDD mode runs everything locally. Start the server:
npx vizzly tdd startRun your tests in another terminal:
npm testOpen http://localhost:47392 to review and approve changes.
CI/CD (Cloud Mode)
Cloud mode uploads screenshots for team review. Wrap your test command:
npx vizzly run "npm test"You’ll need an API token. Get it from your project settings on app.vizzly.dev:

Screenshot Options
Custom Properties
Add any metadata you want:
await vizzlyScreenshot('dashboard', screenshot, { browser: 'chrome', viewport: { width: 1920, height: 1080 }, theme: 'dark', user_role: 'admin'});These properties become part of the screenshot signature. Change a property, you get a new baseline. This lets you maintain separate baselines for different browsers, themes, or test contexts.
Comparison Threshold
Control how sensitive the comparison is:
await vizzlyScreenshot('homepage', screenshot, { threshold: 2.0});Threshold is measured in CIEDE2000 Delta E units:
0- Exact match (pixel-perfect)1- Just Noticeable Difference (JND)2- Recommended default (tolerates minor rendering variations)- Higher values allow more difference
See Threshold Configuration for details on how this works.
How It Works
The SDK is deliberately simple:
- CLI starts an HTTP server on port 47392 (configurable)
- SDK POSTs screenshots to
http://localhost:47392/screenshot - CLI handles comparisons, uploads, and API calls
The SDK finds the server by:
- Checking
VIZZLY_SERVER_URLenvironment variable - Looking for
.vizzly/server.jsonin current and parent directories
If it can’t find a server, screenshots are skipped silently. Your tests keep passing.
Edge Case Helpers
Most test suites never need these. They’re for advanced scenarios.
vizzlyFlush()
Wait for all queued screenshots to finish processing:
afterAll(async () => { await vizzlyFlush();});The simple HTTP client doesn’t actually queue anything, so this is a no-op. It exists for API compatibility with the old batch client.
isVizzlyReady()
Check if the client found a server:
if (isVizzlyReady()) { // Server is available}getVizzlyInfo()
Get client state for debugging:
const info = getVizzlyInfo();console.log(info);// {// enabled: true,// serverUrl: 'http://localhost:47392',// ready: true,// buildId: 'bld_abc123',// tddMode: true,// disabled: false// }Next Steps
- Test Framework Integration - Playwright, Cypress, Jest, Puppeteer examples
- Client API Reference - Full API documentation
- Parallel Builds - Sharding and parallel execution
- CLI Commands - Complete CLI reference