Your Chromatic visual regression gate had been protecting the design system for months. Then a refactor introduced a token in the Chromatic configuration that expanded to an empty string in the CI environment. The chromatic CLI ran, found zero changed stories, published an empty snapshot set, and exited 0. Every subsequent PR merged without a visual review — because Chromatic thought there was nothing to review.
Visual testing tools protect against unintended UI changes. But who protects you when the visual testing tool itself goes quiet? This tutorial shows you how to use Vigilmon heartbeat monitors to detect when your Chromatic CI step stops running, stops publishing, or stops catching changes.
What You'll Cover
- Heartbeat monitoring for Chromatic publish runs in CI
- Detecting when Chromatic publishes zero-story snapshots silently
- Alerting on Chromatic runs that are skipped due to CI configuration drift
- Monitoring Chromatic TurboSnap to catch when it incorrectly skips stories
- CI integration for GitHub Actions and GitLab CI
- Multi-branch monitoring (main baseline vs. PR checks)
Prerequisites
- Chromatic configured in your Storybook project (
npm install --save-dev chromatic) - A Chromatic project token
- A free account at vigilmon.online
The Problem: What Chromatic's Status Checks Can't Catch
Chromatic integrates with your GitHub/GitLab status checks to block PRs with unreviewed visual changes. This works well for changes — but it can't protect you when:
- The CI job that runs
chromaticis accidentally removed or given awhen: nevercondition - A missing or corrupted
CHROMATIC_PROJECT_TOKENcauses the CLI to exit 0 with a warning - TurboSnap incorrectly marks all stories as unchanged and snapshots none of them
- The Storybook build fails before Chromatic is invoked, and the CI step is marked as skipped
- A scheduled baseline rebuild is dropped after a pipeline migration
From Chromatic's perspective, PRs that never trigger a run simply have no status check — they don't fail, they're just missing. Teams may merge those PRs assuming the check passed.
Vigilmon's heartbeat monitors treat a missing check as an alert condition.
Step 1: Create a Heartbeat Monitor in Vigilmon
- Log in to Vigilmon and click New Monitor → Heartbeat.
- Name it
Chromatic — Main Baseline Publish. - Set Expected interval to match your main-branch build cadence. If you merge to main multiple times per day, use 4 hours; for teams that merge daily, use 25 hours.
- Set Grace period to 30 minutes to absorb Storybook build time.
- Save and copy the Ping URL —
https://vigilmon.online/api/heartbeat/<unique-id>.
Step 2: Ping Vigilmon After a Successful Chromatic Publish
Add the heartbeat call as a CI step that fires after chromatic exits with code 0. The step should only run for your baseline branch (usually main or master) to avoid noise from PR runs.
GitHub Actions
# .github/workflows/chromatic.yml
name: Chromatic Visual Tests
on:
push:
branches: [main]
pull_request:
jobs:
chromatic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for TurboSnap change detection
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Publish to Chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
exitZeroOnChanges: true
autoAcceptChanges: "main"
- name: Ping Vigilmon heartbeat (main branch only)
if: success() && github.ref == 'refs/heads/main'
run: |
curl -fsS -X POST "${{ secrets.VIGILMON_CHROMATIC_HEARTBEAT_URL }}" \
--max-time 10 --retry 3 --retry-delay 5
The github.ref == 'refs/heads/main' guard ensures only baseline publishes trigger the heartbeat, not PR snapshots.
GitLab CI
# .gitlab-ci.yml
chromatic:publish:
stage: test
image: node:20
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
variables:
CHROMATIC_PROJECT_TOKEN: $CHROMATIC_PROJECT_TOKEN
before_script:
- git fetch --unshallow # Required for TurboSnap
- npm ci
script:
- npx chromatic --project-token "$CHROMATIC_PROJECT_TOKEN" --exit-zero-on-changes --auto-accept-changes
- |
curl -fsS -X POST "$VIGILMON_CHROMATIC_HEARTBEAT_URL" \
--max-time 10 --retry 3 --retry-delay 5
echo "Vigilmon heartbeat sent"
Step 3: Detect Zero-Story Snapshots
When Chromatic publishes but captures zero stories (misconfigured Storybook, TurboSnap over-pruning), it exits 0 but has done nothing useful. Add a guard that checks the publish output before sending the heartbeat:
- name: Publish to Chromatic
id: chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
exitZeroOnChanges: true
autoAcceptChanges: "main"
- name: Verify snapshot count
run: |
SNAPSHOT_COUNT="${{ steps.chromatic.outputs.storybookCount }}"
if [ -z "$SNAPSHOT_COUNT" ] || [ "$SNAPSHOT_COUNT" -eq "0" ]; then
echo "ERROR: Chromatic published 0 stories — TurboSnap or Storybook config issue"
exit 1
fi
echo "Chromatic published $SNAPSHOT_COUNT stories"
- name: Ping Vigilmon heartbeat
if: success() && github.ref == 'refs/heads/main'
run: |
curl -fsS -X POST "${{ secrets.VIGILMON_CHROMATIC_HEARTBEAT_URL }}" \
--max-time 10 --retry 3 --retry-delay 5
The snapshot count gate catches the silent zero-story case before the heartbeat is sent.
Step 4: Nightly Baseline Rebuild Monitoring
Teams using Chromatic's --force-rebuild for scheduled baseline refreshes need a separate heartbeat:
# .github/workflows/chromatic-nightly.yml
name: Chromatic Nightly Baseline Rebuild
on:
schedule:
- cron: "0 4 * * 1-5" # 04:00 UTC Monday–Friday
jobs:
chromatic-rebuild:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Rebuild Chromatic baseline
run: |
npx chromatic \
--project-token "$CHROMATIC_PROJECT_TOKEN" \
--force-rebuild \
--auto-accept-changes \
--exit-zero-on-changes
env:
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
- name: Ping Vigilmon heartbeat
if: success()
run: |
curl -fsS -X POST "${{ secrets.VIGILMON_CHROMATIC_NIGHTLY_HEARTBEAT_URL }}" \
--max-time 10 --retry 3 --retry-delay 5
Create a second Vigilmon heartbeat monitor (Chromatic — Nightly Rebuild) with a 25-hour interval and 1-hour grace period to cover weekday runs.
Step 5: Multi-Monitor Setup
| Monitor | Name | Interval | What it catches |
|---|---|---|---|
| Heartbeat | Chromatic — Main Baseline Publish | 4–25 h | Missed main-branch publishes |
| Heartbeat | Chromatic — Nightly Rebuild | 25 h | Scheduled baseline rebuild failures |
| HTTP | Chromatic — Project URL | 5 min | Chromatic service outage affecting reviews |
For the HTTP monitor, use your project's Chromatic review URL and set a keyword check on a string that appears in Chromatic's review UI (e.g., chromatic).
Step 6: Configure Alert Channels
In Vigilmon, go to Notifications → New Channel and configure:
- Email — immediate alert to your design systems or frontend platform team
- Slack webhook — ping your
#visual-regressionor#design-system-alertschannel
Sample missed-heartbeat notification:
🔴 MISSED HEARTBEAT: Chromatic — Main Baseline Publish
Last ping: 27 hours ago
Expected interval: 25 hours
Recovery notification:
✅ HEARTBEAT RECOVERED: Chromatic — Main Baseline Publish
Gap: 27 hours
What You're Now Catching
| Silent failure mode | How Vigilmon detects it |
|---|---|
| CI job that runs Chromatic is deleted | No ping arrives → alert after grace period |
| Missing CHROMATIC_PROJECT_TOKEN | CLI exits 0 with warning, no heartbeat sent → alert |
| Storybook build fails before Chromatic runs | No heartbeat → alert |
| TurboSnap skips all stories (zero snapshots) | Snapshot count guard fails, no heartbeat → alert |
| Nightly baseline rebuild job is dropped | No ping at expected interval → alert |
| Chromatic service outage | HTTP monitor detects 5xx or keyword missing → alert |
Chromatic catches the visual regressions your code reviewers miss — but only when it actually runs. Vigilmon's heartbeat monitors give you the external signal Chromatic can't provide about itself: a definitive alert when your visual testing pipeline hasn't produced a baseline in longer than expected.
Add Vigilmon to your Chromatic pipeline today — register free at vigilmon.online.