Framecheck is in beta. Sorry for any rough edges. If something doesn’t look right, tell us at support@framecheck.dev or visit Help and we’ll fix it.

Docs

Getting started

Setup takes place in the app, which walks you through each step and remembers where you stopped. This page explains what happens along the way.

What you need

A Storybook is a collection of isolated component examples, called stories. Framecheck tests this built collection, rather than crawling a public website.

  • A GitHub repository with a Storybook that builds to static files (for example with a build-storybook script)
  • Storybook 8.6 or newer (tested with 8.6, 9 and 10). Storybook 7 is not supported.
  • GitHub Actions, or another CI system that can run a Node.js command
  • Permission to install a GitHub App on the repository, or an organisation owner who can approve it
  • For Smart Snapshots, build Storybook with --stats-json (Storybook 8 or later, Vite builder), so pull requests capture only the stories they could change. Without it, every story is captured.

Don’t use Storybook yet? Set up Storybook first, or ask us whether your setup fits before creating an account.

What you connect and upload

Choose which repositories the GitHub App can access. Your CI builds Storybook and uploads the static files needed to render your stories, which can include compiled code, assets and fixture data. Use mock data and keep secrets and personal customer data out of stories.

Company members can access their project’s results. Links created by Open Storybook can be used by anyone holding the link until they expire, so share them carefully. Read the privacy notice for permissions, access and retention, or ask support before connecting.

Your code and data

What we receive
Your built Storybook from CI: compiled code and assets, plus any source maps you include. Commit details, not a checkout of your repository.
What we read on GitHub
Only repositories you choose: the file list, pull request details and a few config files (package.json, workflows, .npmrc, Node version files, .storybook/main) to set up CI. Never other file contents.
What we write
A check on each pull request, and a comment on pull requests with visual changes or failures (you can turn comments off). Write access to code and workflows is used only to open the one-file setup pull request, on its own branch.
Where it’s stored
AWS in London (eu-west-2).
How long
Uploaded builds: 30 days. Screenshots and run history: while the project exists.

Data and retention · support@framecheck.dev

Quickstart

  1. Sign up with your email

    Confirm your email address and choose a password. The privacy notice explains what is kept.

  2. Name your company

    Your company holds your projects, members and billing. Choose the default pull request policy here; you can change it later.

  3. Install the GitHub App

    Install the Framecheck GitHub App on the repositories you want to test. It is what lets Framecheck post checks on your pull requests.

  4. Choose your Storybook repository

    Pick the repository from the list. This creates a project, which follows your default branch, and starts your trial. Choose carefully: the trial allows one project in total, and deleting it does not allow a replacement. Previously connected GitHub organisations and personal accounts are not eligible for another trial. Trial eligibility details.

  5. Start your Starter trial

    Your first eligible connection starts 30 days with 35,000 snapshots and the £84 fee waived. No card or subscription is needed. There is no automatic subscription at the end. Pricing details

  6. Add Framecheck to CI

    Select Open pull request and Framecheck opens a pull request that adds one GitHub Actions workflow. Then copy the project’s upload token and add it to the repository as the FRAMECHECK_TOKEN secret (the setup page links straight to GitHub’s secret page). Merge it once its check passes. Other CI systems use the same upload token.

  7. Set your first baseline

    Your first pull request captures every story; accept it, and merging it sets your baseline. A baseline is the approved set of images used as the reference for later comparisons. Your first run shows new stories because there is no approved version to compare against yet.

Your first review

Open a run and select a changed story. Compare the previously approved image with the new image. Accept an intentional change; if the layout is broken, fix it in your code and run again. Accepting a change approves the new appearance—it does not repair the component.

Before uploading, make sure stories work without your local development server. Bundle fonts and images, mock external services and use predictable fixture data. Capture workers cannot use your local credentials or reach a service running only on your laptop.

Runs allow up to 5,000 visual snapshots across all screen sizes and browsers, with a 45-minute deadline. Accessibility adds billed checks without increasing that visual limit. Runs share capacity and can queue; paid runs take priority over trials. Estimate your run and monthly usage.

When you’re ready to continue

Choose Starter or Pro in Billing whenever you are ready, including before using the trial. Subscribing ends the trial immediately and starts the full paid allowance. After 30 days, a paid subscription is needed to run again even if purchased credit remains. Compare plans.

Open the story behind a screenshot

Use Live on a supported run to open the component example and inspect its behaviour, or Open Storybook to explore that uploaded build. These links use the saved Storybook, so external services still need to be available. This is separate from hosting Storybook on your own custom domain.

After setup

  • Turn on accessibility checks in the project’s settings if you want them. Each check counts as a snapshot.
  • Invite teammates by email, as viewers, members or admins.
  • Top up your credit and set a spend limit from the company’s billing settings.

Already set up? Sign in

Accept main automatically

A project setting, off by default, that company admins turn on under Project settings → General. When a run on your default branch finishes with nothing rejected, its changes are accepted and it becomes the baseline, without anyone reviewing it. Pull requests are never accepted this way.

Stories that errored

A story that errored is never accepted. When only a few stories errored (one story, or up to 2% of the run and at most 10), the rest of the run still becomes the baseline and each errored story keeps its previous image. The run, its GitHub check and the audit log say so, and the project lists the stories still erroring until a later run captures them. When more stories errored, the run waits for a person, who can choose “Accept all except errored”.

The upload token risk

Anyone with the project’s upload token can upload a Storybook for a commit on your default branch. With this setting on, that capture becomes the baseline without review. Keep the FRAMECHECK_TOKEN secret, and rotate it straight away if it may have leaked.

Rotate the upload token

  1. In Project settings → Upload tokens, select Rotate and copy the new token. If the project already has 2 active tokens, revoke one it no longer uses first.
  2. Replace the FRAMECHECK_TOKEN secret in your CI.
  3. Select Revoke on the old token. Rotate keeps it working so CI has no downtime; revoking stops it immediately.

Everything is recorded

Turning the setting on or off, and every automatic acceptance, is recorded in the company’s audit log (Company settings → Activity).

Unstable stories

When a changed story is captured a second time in the same run and that capture is different from the first and matches your accepted baseline, the change did not reproduce, so Framecheck puts the story in the Unstable group on the run page, labelled “not blocking”. It does not fail the pull request check, and the baseline keeps its previous image unless someone accepts it. You can still open, accept or reject it; a rejection fails the check as usual, and every decision on an unstable story is recorded in the audit log.

The second capture runs on the same worker seconds later: it shows the difference did not reproduce that time, not that the change can never be real. A story whose captures differ from each other but never match the baseline keeps blocking, and so does one that was not checked (for example because the run’s re-capture limit was used up: “Not checked for consistency”). A capture that was not made as requested (such as an unknown viewport) blocks whatever its stability. Automatic acceptance, “Accept all” and carried approvals never accept an unstable story.

Unstable stories and quarantine

The Unstable group is about one capture in one run and needs no setup. Quarantine is a standing project decision about a story that keeps being unstable: it applies to every run until an admin (or the automatic rule) releases it. A quarantined story is shown as quarantined, not in the Unstable group.

Making a story stable

The usual causes are the real clock, random values, JavaScript-driven animation, animated GIFs and data that arrives late. Mock the date and random values, pause animations in the story, and serve fixed data (for example with MSW) so every capture renders the same pixels.

Accessibility checks

Off until a company admin turns them on under Project settings → Accessibility. Every captured story is checked with axe-core for WCAG A and AA issues. Automated checks find some problems, not all, and are not a WCAG compliance certification.

Report only, unless you choose to block

New projects start in Report only: issues are listed on the run and the GitHub check, and the check never fails because of them. Choose Block pull requests to make new issues at or above the level you pick follow your PR check policy.

Your starting point is set automatically

The first complete run on your default branch becomes the accessibility baseline, including any issues it found (they are listed as known issues). This happens only when every story was checked and the run came from your default branch: uploaded from GitHub Actions without a token (OIDC), or, with an upload token, only when “Accept main automatically” is on and GitHub confirms the commit. An existing baseline is never replaced this way. The run says “Accessibility baseline set automatically from run #N”, and the audit log records it.

Before the baseline exists

Pull requests still list what they find, but nothing is compared and the accessibility part of the check is neutral under every policy: “accessibility baseline not set yet”. A branch that started before the baseline was set is treated the same way; merge or rebase your default branch into it to compare. Checks that could not finish still show as incomplete.