Lastest Documentation
Complete reference for the self-hostable visual regression testing platform.
Overview
| Type | Visual regression testing |
|---|---|
| License | FSL-1.1-ALv2 (converts to Apache 2.0) |
| Written in | TypeScript, Rust |
| Hosting | Self-hosted (Docker) |
| AI | Agentic test generation |
| Repository | GitHub |
Lastest is a self-hostable visual regression testing platform that combines AI-powered test generation with human oversight. It is designed for teams that want to catch visual regressions before they reach production without building and maintaining test suites by hand.
The core workflow is straightforward: an agentic AI explores your application, identifies critical user flows, and generates visual regression tests automatically. After the initial generation run, every subsequent replay executes deterministically with zero token cost. You retain full control through a human oversight dashboard where you approve, reject, or refine tests before they enter your pipeline.
Key value propositions:
- AI test generation - An agentic AI navigates your app like a real user, generating comprehensive tests across pages, states, and breakpoints.
- Human oversight - Every AI-generated test passes through a review dashboard. You maintain final say on what enters your test suite.
- Zero-token replays - AI is used once to create the test. After that, tests replay using deterministic browser automation with no LLM calls and no ongoing cost.
- Self-hosted - Run Lastest on your own infrastructure with a single
docker-compose up -d. No data leaves your network. - Source-available - FSL-1.1-ALv2, converts to Apache 2.0. No seat limits, no usage fees, no vendor lock-in. See the source.
Getting Started
This quick start guide assumes you have Docker installed on your machine. If you prefer a manual installation, see the manual installation section below.
Step 1: Clone the repository and start the stack.
git clone https://github.com/las-team/lastest.gitcd lastestdocker-compose up -dStep 2: Open the dashboard at http://localhost:3700.
Step 3: Add your first project by entering your application's URL. Lastest will run an initial crawl to discover pages and generate a site map.
Step 4: Click Generate Tests to start the AI agent. It will explore your application, interact with elements, and produce a set of baseline screenshots.
Step 5: Review the generated tests in the oversight dashboard. Approve the ones you want in your pipeline, discard or edit the rest.
Step 6: Run subsequent tests on demand or integrate with your CI/CD pipeline. From this point forward, replays are deterministic and cost nothing.
Installation
Lastest can be installed via Docker (recommended) or manually from source. Both methods are documented below.
Docker (Recommended)
The Docker setup includes all dependencies: the web dashboard, the test runner, the diff engine, and a PostgreSQL database. Everything is configured via a single docker-compose.yml file.
Prerequisites
- Docker Engine 20.10 or later
- Docker Compose v2.0 or later
- At least 2 GB of available RAM
Steps
# Clone the repositorygit clone https://github.com/las-team/lastest.gitcd lastest# Copy the default environment filecp .env.example .env# Start all services in detached modedocker-compose up -dAfter the stack is running, open http://localhost:3700 in your browser. The default admin credentials are printed to the container logs on first launch. Run docker-compose logs lastest-web to view them.
Updating
git pull origin maindocker-compose pulldocker-compose up -dManual (From Source)
Manual installation gives you more control over each component and is useful for development or non-Docker environments.
Prerequisites
- Node.js 18 or later
- Rust 1.70 or later (for the diff engine)
- PostgreSQL 14 or later
- Chromium or Google Chrome
Steps
# Clone and install dependenciesgit clone https://github.com/las-team/lastest.gitcd lastestnpm install# Build the diff engine (Rust)cd packages/diff-enginecargo build --releasecd ../..# Set up the databasecp .env.example .env# Edit .env with your PostgreSQL connection stringnpm run db:migrate# Build the web dashboardnpm run build# Start the servernpm startThe server will listen on port 3700 by default. Override this with the PORT environment variable.
AI Test Generation
Lastest uses an agentic AI system to automatically generate visual regression tests. Rather than requiring you to write selectors and navigation steps by hand, the AI explores your application like a real user would: clicking links, filling out forms, opening menus, and capturing screenshots at each meaningful state.
How It Works
- Crawl phase: The agent starts at your application's root URL and discovers all reachable pages by following links and analyzing the DOM.
- Exploration phase: On each page, the agent identifies interactive elements (buttons, inputs, dropdowns, tabs) and exercises them to reveal different visual states.
- Capture phase: At each distinct state, the agent takes a full-page screenshot across configured viewport sizes (desktop, tablet, mobile by default).
- Test synthesis: The agent generates a deterministic test script for each captured flow. These scripts use standard browser automation under the hood and do not call any LLM at replay time.
One-Time Token Cost
The AI agent requires LLM tokens only during the initial test generation. This is a one-time cost per test. Once a test is generated, it is stored as a deterministic script that replays using Puppeteer with no AI involvement. This means:
- Initial generation: uses LLM tokens (proportional to application size and complexity).
- Every subsequent run: zero tokens, zero external API calls, zero cost.
- Re-generation (when you want to update tests): uses tokens again, but only for the tests you choose to regenerate.
Human Oversight
AI-generated tests are not automatically added to your pipeline. Every test appears in the oversight dashboard in a pending state. From there, you can:
- Approve - Add the test to your active suite.
- Reject - Discard the test entirely.
- Edit - Modify the test steps, selectors, or thresholds before approving.
- Regenerate - Ask the AI to try a different approach for this flow.
Diff Engines
Lastest ships with three built-in diff engines, each optimized for different types of visual comparison. You can configure which engine to use globally, per-project, or per-test. See our blog post on Understanding the 3 Diff Engines for an in-depth comparison.
Pixel Diff
The pixel diff engine performs an exact, pixel-by-pixel comparison between the baseline and current screenshots. If any pixel's RGB values differ beyond the configured threshold, the test reports a diff.
Best for: Catching every change, no matter how small. Ideal for pixel-perfect designs, brand assets, and components where exact rendering matters.
Trade-off: High sensitivity means it will also flag sub-pixel rendering differences caused by font hinting, anti-aliasing, or GPU variations. Use a small threshold value (e.g., 0.01) to allow for minor rendering variance.
// lastest.config.js{diffEngine: "pixel",threshold: 0.01}Structural Diff
The structural diff engine is DOM-aware. Instead of comparing raw pixels, it compares the structure and layout of the page. It extracts bounding boxes, element hierarchy, and computed styles, then calculates structural divergence.
Best for: Detecting layout shifts, missing elements, and structural regressions while ignoring cosmetic changes like color tweaks, font rendering differences, or minor padding adjustments that do not affect layout.
Trade-off: It will not catch purely visual changes that do not alter the DOM structure or layout geometry. If someone changes a background color without moving any elements, structural diff will not flag it.
// lastest.config.js{diffEngine: "structural",structuralThreshold: 0.05}Perceptual Diff
The perceptual diff engine uses a human-perception-weighted algorithm based on the CIE76 color difference standard and spatial frequency analysis. It is designed to catch changes that a real user would notice while ignoring differences that are invisible to the human eye.
Best for: Balancing coverage with noise reduction. It catches meaningful color changes, layout shifts, and content differences while filtering out sub-pixel rendering noise and minor anti-aliasing variations.
Trade-off: Slightly less sensitive than pixel diff, but dramatically fewer false positives in practice. This is the recommended default engine for most teams.
// lastest.config.js{diffEngine: "perceptual",perceptualThreshold: 0.02}CI/CD Integration
Lastest integrates directly into your CI/CD pipeline via its CLI. Tests run against your Lastest instance and report results back with pass/fail exit codes compatible with any CI system.
GitHub Actions
# .github/workflows/visual-regression.ymlname: Visual Regression Testson:pull_request:branches: [main]jobs:visual-test:runs-on: ubuntu-lateststeps: - uses: actions/checkout@v4 - name: Start applicationrun: docker-compose up -d - name: Wait for app to be readyrun: npx wait-on http://localhost:3000 - name: Run Lastest visual testsrun: |npx lastest test \ --api-url http://localhost:3700 \ --project my-app \ --fail-on-diff - name: Upload diff artifactsif: failure()uses: actions/upload-artifact@v4with:name: visual-diffspath: ./lastest-results/GitLab CI
# .gitlab-ci.ymlvisual_regression:stage: testimage: node:18services: - name: docker:dindalias: dockervariables:DOCKER_HOST: tcp://docker:2375before_script: - npm install -g lastest-cliscript: - lastest test --api-url $LASTEST_URL --project $CI_PROJECT_NAME --fail-on-diffartifacts:when: on_failurepaths: - ./lastest-results/expire_in: 7 daysonly: - merge_requestsCLI Reference
# Run all tests for a projectnpx lastest test --api-url http://localhost:3700 --project my-app# Run tests and fail if any diffs are detectednpx lastest test --api-url http://localhost:3700 --project my-app --fail-on-diff# Update baselines to the current screenshotsnpx lastest baseline --api-url http://localhost:3700 --project my-app --approve-allConfiguration
Lastest is configured through a lastest.config.js file at the root of your project. This file controls test behavior, diff engine selection, viewport sizes, and more.
// lastest.config.jsmodule.exports = {// Base URL of your application under testbaseUrl: "http://localhost:3000",// Lastest server URLapiUrl: "http://localhost:3700",// Project identifierproject: "my-app",// Diff engine: "pixel", "structural", or "perceptual"diffEngine: "perceptual",// Diff threshold (0 = exact match, 1 = any diff passes)threshold: 0.02,// Viewport sizes to testviewports: [{ width: 1440, height: 900, label: "desktop" },{ width: 768, height: 1024, label: "tablet" },{ width: 375, height: 812, label: "mobile" }],// Paths to exclude from crawlingexclude: ["/admin/*", "/api/*"],// Maximum number of concurrent browser instancesconcurrency: 4,// Wait for network idle before capturing (ms)waitForNetworkIdle: 2000,// Selectors to mask (e.g., dynamic content like dates)mask: [".timestamp", "[data-dynamic]"],// Fail CI if any diff exceeds thresholdfailOnDiff: true};Key Options
| Option | Type | Default | Description |
|---|---|---|---|
baseUrl | string | - | URL of the application to test (required) |
apiUrl | string | http://localhost:3700 | URL of the Lastest server |
diffEngine | string | "perceptual" | One of "pixel", "structural", "perceptual" |
threshold | number | 0.02 | Diff sensitivity (0–1) |
viewports | array | Desktop, tablet, mobile | Viewport sizes to capture |
concurrency | number | 4 | Max parallel browser instances |
mask | array | [] | CSS selectors to mask with a solid overlay |
failOnDiff | boolean | false | Exit with code 1 if diffs detected |
API Reference
The Lastest server exposes a REST API for programmatic control. All endpoints accept and return JSON. Authenticate by including an Authorization: Bearer <token> header. Generate API tokens in the dashboard under Settings → API Tokens.
POST /api/tests/run
Triggers a test run for a given project. Returns the run ID which can be polled for status.
Request Body
{"project": "my-app","baseUrl": "http://localhost:3000","diffEngine": "perceptual","viewports": ["desktop", "mobile"]}Response
{"id": "run_8f3a2b1c","status": "running","testsTotal": 42,"createdAt": "2025-12-01T10:30:00Z"}GET /api/tests/:id
Returns the status and results of a specific test run.
Response
{"id": "run_8f3a2b1c","status": "completed","testsTotal": 42,"testsPassed": 40,"testsFailed": 2,"diffs": [{ "id": "diff_a1b2c3", "testName": "homepage-desktop", "diffPercent": 0.034 },{ "id": "diff_d4e5f6", "testName": "checkout-mobile", "diffPercent": 0.12 }],"completedAt": "2025-12-01T10:31:45Z"}GET /api/diffs/:id
Returns detailed information about a specific diff, including links to the baseline, current, and overlay images.
Response
{"id": "diff_a1b2c3","testName": "homepage-desktop","engine": "perceptual","diffPercent": 0.034,"threshold": 0.02,"passed": false,"images": {"baseline": "/api/images/baseline_a1b2c3.png","current": "/api/images/current_a1b2c3.png","overlay": "/api/images/overlay_a1b2c3.png"}}FAQ
Is Lastest really free?
Yes. Lastest is source-available software under FSL-1.1-ALv2 (which converts to Apache 2.0) with no seat limits, no usage caps, and no paid tiers. You self-host it on your own infrastructure. The only cost is the LLM tokens consumed during initial test generation, which you pay directly to your LLM provider. An enterprise support offering is available for teams that need SLAs and dedicated assistance - contact [email protected].
What LLM providers are supported?
Lastest supports OpenAI, Anthropic, and any OpenAI-compatible API (including local models via Ollama or LM Studio). Configure your provider and API key in the .env file or through the dashboard settings.
How does Lastest compare to commercial tools like Percy or Chromatic?
Commercial tools charge per screenshot and host your data on their servers. Lastest is self-hosted, runs on your infrastructure, and has no per-screenshot cost after initial test generation. You also get AI-powered test generation, which commercial tools typically do not offer. The trade-off is that you manage the infrastructure yourself, though the Docker setup makes this straightforward.
Can I use Lastest without the AI test generation?
Yes. You can write test scripts manually and import them into Lastest. The AI generation feature is optional - the diff engine, dashboard, and CI/CD integration all work independently of it.
Which browsers are supported?
Lastest uses Chromium-based browser automation under the hood. Tests run in headless Chromium by default. Firefox and WebKit support is on the roadmap - track progress on the GitHub repository.
How do I handle dynamic content like dates or avatars?
Use the mask configuration option to specify CSS selectors for dynamic elements. Lastest will overlay these regions with a solid fill before comparison, preventing false positives from content that changes between runs. See the Configuration section for syntax details.