{"id":51705796,"url":"https://github.com/krystxf/storybook-vrt","last_synced_at":"2026-07-16T15:41:37.495Z","repository":{"id":365519439,"uuid":"1272461032","full_name":"krystxf/storybook-vrt","owner":"krystxf","description":"Storybook visual regression posted inline on PRs","archived":false,"fork":false,"pushed_at":"2026-06-17T17:24:51.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-17T18:25:05.875Z","etag":null,"topics":["github-actions","storybook","visual-regression"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/krystxf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-17T16:21:09.000Z","updated_at":"2026-06-17T17:24:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/krystxf/storybook-vrt","commit_stats":null,"previous_names":["krystxf/storybook-vrt"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/krystxf/storybook-vrt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krystxf%2Fstorybook-vrt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krystxf%2Fstorybook-vrt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krystxf%2Fstorybook-vrt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krystxf%2Fstorybook-vrt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/krystxf","download_url":"https://codeload.github.com/krystxf/storybook-vrt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krystxf%2Fstorybook-vrt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35549640,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-16T02:00:06.687Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github-actions","storybook","visual-regression"],"created_at":"2026-07-16T15:41:36.742Z","updated_at":"2026-07-16T15:41:37.486Z","avatar_url":"https://github.com/krystxf.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# storybook-vrt\n\nA reusable GitHub Action for **Chromatic-style visual regression on Storybook** — posted as a\n**single, auto-updating PR comment** with before/after/diff images, gated by comment approval.\nNo external services; works in **private repos** (images are committed to a branch in your own\nrepo and embedded via `github.com/\u003crepo\u003e/raw/\u003csha\u003e/…` URLs, which render for repo members).\n\n## Quickstart\n\nAdd one workflow to your repo (e.g. `.github/workflows/visual-regression.yml`):\n\n```yaml\nname: Visual regression\non:\n  pull_request:\n    types: [opened, synchronize, reopened]\n  issue_comment:\n    types: [created, edited, deleted]\n\npermissions:\n  contents: write       # push diff images to the snapshot branch\n  pull-requests: write  # upsert the sticky comment\n  statuses: write       # set the blocking commit status\n\njobs:\n  visual-regression:\n    if: \u003e\n      github.event_name == 'pull_request' ||\n      (github.event.issue.pull_request \u0026\u0026 github.event.comment.user.type != 'Bot' \u0026\u0026\n       contains(github.event.comment.body, 'approve changes'))\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0           # needed to build the base commit\n      - uses: pnpm/action-setup@v4 # your toolchain (or setup-node alone for npm/yarn)\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 24         # \u003e= 24 (or \u003e= 22.18) for native TS type stripping\n          cache: pnpm\n      - run: pnpm install --frozen-lockfile\n      - uses: krystxf/storybook-vrt@v1\n        with:\n          build-command: pnpm build-storybook\n          ignore-story-names: \"All Variants\" # optional; comma-separated, case-insensitive\n```\n\nThat's it. On each push the action screenshots every story (light + dark) for the PR and its\nbase branch, diffs them, and posts/updates one comment. Visual **changes block** the PR until\napproved.\n\n## Approving / revoking\n\nComment on the PR (owner/member/collaborator only), one line per item:\n\n```\napprove changes UI/Button            # every variant of the component\napprove changes UI/Button › Default  # a single story\n```\n\nDeleting (or editing out) an approval comment **revokes** it. Added/removed stories never block.\n\n## Inputs\n\n| Input | Default | Description |\n|---|---|---|\n| `build-command` | `npx storybook build` | Builds Storybook into `static-dir` (run for head and base). |\n| `static-dir` | `storybook-static` | Build output directory. |\n| `themes` | `light,dark` | Comma-separated Storybook themes (`globals=theme:\u003cname\u003e`). |\n| `min-diff-pixels` | `20` | Ignore diffs smaller than this many pixels. |\n| `pixelmatch-threshold` | `0.1` | Per-pixel color sensitivity (0–1). |\n| `ignore-story-names` | `All Variants` | Comma-separated, case-insensitive story-name substrings to skip. |\n| `snapshot-branch` | `vrt-snapshots` | Orphan branch the diff images live on. |\n| `github-token` | `${{ github.token }}` | Token with `contents`/`pull-requests`/`statuses` write. |\n\n## Requirements \u0026 notes\n\n- **Node ≥ 24** (or ≥ 22.18) in the caller — the action runs TypeScript scripts via Node's\n  native type stripping.\n- **`fetch-depth: 0`** in `actions/checkout` so the base commit can be built.\n- The `issue_comment` trigger runs from your repo's **default branch**, so this workflow must be\n  on `main` before approvals take effect.\n- To make the gate *hard-block* merges, add the **`visual-regression`** status as a required check\n  in branch protection (needs GitHub Pro or a public repo for private repositories).\n- Snapshot images accumulate on the `snapshot-branch`; delete that branch anytime to reclaim space\n  (it's recreated on the next run).\n\n## Demo\ncheck out this [demo PR](https://github.com/krystxf/storybook-vrt-example/pull/14)\n\u003cimg width=\"1130\" height=\"1690\" alt=\"image\" src=\"https://github.com/user-attachments/assets/4e5bb22a-a9d6-4dfd-8e91-727bdc53f177\" /\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrystxf%2Fstorybook-vrt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrystxf%2Fstorybook-vrt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrystxf%2Fstorybook-vrt/lists"}