
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@storybook-visual-regression/addon
Advanced tools
Fully functional Storybook addon for visual regression testing with built-in API server
A fully functional Storybook addon that integrates visual regression testing directly into your Storybook UI.
✅ FULLY FUNCTIONAL: This addon includes a built-in API server that runs alongside Storybook, allowing you to execute visual regression tests directly from the Storybook UI!
How it works:
- The addon's preset starts an API server (port 6007) when Storybook loads
- The server runs in the same Node.js process as Storybook
- When you click "Test Story", the browser calls the API, which spawns the CLI tool
- Results stream back to the UI in real-time via Server-Sent Events
- No separate backend service needed!
visual-regression/config.json or svr.config.jsstorybook-visual-regression CLInpm install --save-dev @storybook-visual-regression/addon
Add the addon to your .storybook/main.js or .storybook/main.ts:
module.exports = {
addons: [
// ... other addons
'@storybook-visual-regression/addon',
],
};
This addon requires the @storybook-visual-regression/cli CLI tool to be installed:
npm install --save-dev @storybook-visual-regression/cli
Make sure Playwright browsers are installed:
npx playwright install chromium
The addon will use the default configuration from your svr.config.js file if it exists. You can create one with:
npx @storybook-visual-regression/cli init
You can configure the addon through Storybook's main configuration:
.storybook/main.js or .storybook/main.ts:
module.exports = {
addons: [
// ... other addons
{
name: '@storybook-visual-regression/addon',
options: {
port: 6008, // Custom API server port
cliCommand: 'npx @storybook-visual-regression/cli', // Custom CLI command
},
},
],
};
Basic Configuration:
// .storybook/main.js
module.exports = {
addons: ['@storybook-visual-regression/addon'],
};
Custom Port:
// .storybook/main.js
module.exports = {
addons: [
{
name: '@storybook-visual-regression/addon',
options: {
port: 6008,
},
},
],
};
Custom CLI Command:
// .storybook/main.js
module.exports = {
addons: [
{
name: '@storybook-visual-regression/addon',
options: {
cliCommand: 'npx @storybook-visual-regression/cli',
},
},
],
};
Docker CLI Command (for cross-platform consistency):
// .storybook/main.js
module.exports = {
addons: [
{
name: '@storybook-visual-regression/addon',
options: {
cliCommand: 'docker run --rm -v $(pwd):/app storybook-visual-regression',
},
},
],
};
Note: When using Docker commands with host.docker.internal URLs, the addon automatically replaces host.docker.internal with localhost in the terminal output, making URLs clickable from your host machine.
Default Configuration:
@storybook-visual-regression/cli⚠️ Important: Font Rendering Differences
If you're running visual regression tests in GitHub Actions (Linux) but developing locally on macOS or Windows, you may encounter font rendering differences that cause false positives. This happens because:
Solution: Use Docker for Consistency
To ensure consistent font rendering across all platforms, use the Docker CLI command:
// .storybook/main.js
module.exports = {
addons: [
{
name: '@storybook-visual-regression/addon',
options: {
cliCommand: 'docker run --rm -v $(pwd):/app storybook-visual-regression',
},
},
],
};
Docker Setup:
Build the Docker image:
docker build -t storybook-visual-regression .
Use in GitHub Actions:
# .github/workflows/visual-regression.yml
- name: Run Visual Regression Tests
run: |
docker run --rm \
-v ${{ github.workspace }}:/app \
-w /app \
storybook-visual-regression
Use locally (optional):
# Same command works on macOS, Windows, and Linux
docker run --rm -v $(pwd):/app storybook-visual-regression
This ensures identical font rendering across all environments.
You can also use environment variables as a fallback:
# Custom port
VR_API_PORT=6008 npm run storybook
# Custom CLI command
VR_CLI_COMMAND="npx @storybook-visual-regression/cli" npm run storybook
# Both custom
VR_API_PORT=6008 VR_CLI_COMMAND="npx @storybook-visual-regression/cli" npm run storybook
Once installed, you'll see visual regression controls in your Storybook UI:
The Visual Regression panel shows:
After running a test, the panel displays:
For failed tests, you'll see:
When a test fails due to intentional changes:
The addon consists of four main components working together:
preset.ts) - Node.js module that starts the API server when Storybook loadsmanager.tsx) - React component running in Storybook UI, provides panel and toolbarpreview.ts) - Runs in story iframe, handles communication and CLI spawningserver.ts) - HTTP server that manages test execution and file servingpreset.ts)manager.tsx)preview.ts)server.ts)User clicks "Test Story" button in toolbar
↓
Manager emits 'TEST_STORY' event via Storybook channel
↓
Preview receives event, gets current story ID
↓
Preview spawns CLI: @storybook-visual-regression/cli test --json --grep "story-id"
↓
CLI executes Playwright test, outputs JSON results
↓
Preview parses JSON, extracts image paths
↓
Preview emits 'TEST_RESULT' event with results
↓
Manager updates UI with test status and diff images
User clicks "Test All Stories" button
↓
Manager emits 'TEST_ALL_STORIES' event
↓
Preview spawns CLI: @storybook-visual-regression/cli test --json
↓
CLI runs all tests, outputs comprehensive JSON results
↓
Preview parses results, emits multiple 'TEST_RESULT' events
↓
Manager updates UI with progress and individual results
User clicks "Update Baseline" after failed test
↓
Manager emits 'UPDATE_BASELINE' event with story ID
↓
Preview spawns CLI: @storybook-visual-regression/cli update --grep "story-id"
↓
CLI updates baseline, outputs confirmation
↓
Preview emits 'BASELINE_UPDATED' event
↓
Manager refreshes test result display
The built-in API server provides these endpoints:
POST /api/test - Execute individual story testPOST /api/test-all - Execute all story testsPOST /api/update - Update baseline for specific storyGET /api/images/:path - Serve test result imagesGET /api/diff/:path - Serve diff imagesGET /api/expected/:path - Serve expected baseline imagesGET /health - Health check endpointGET /api/status - Current test execution statusGET /api/logs - Real-time test execution logsTestResultsContext.tsx)results: Array of test results for all storiesisRunning: Boolean indicating if tests are currently runninglogs: Array of log messages for real-time displayaddResult(): Add new test resultupdateResult(): Update existing test resultclearResults(): Clear all resultsaddLog(): Add log messageThe addon uses Storybook's channel API for communication:
// Events emitted by Manager
const EVENTS = {
TEST_STORY: 'visual-regression/test-story',
TEST_ALL_STORIES: 'visual-regression/test-all-stories',
UPDATE_BASELINE: 'visual-regression/update-baseline',
CLEAR_RESULTS: 'visual-regression/clear-results',
} as const;
// Events emitted by Preview
const RESULT_EVENTS = {
TEST_RESULT: 'visual-regression/test-result',
TEST_PROGRESS: 'visual-regression/test-progress',
TEST_COMPLETE: 'visual-regression/test-complete',
BASELINE_UPDATED: 'visual-regression/baseline-updated',
} as const;
The addon spawns CLI processes with carefully constructed arguments:
// Individual story test
const args = [
'@storybook-visual-regression/cli',
'test',
'--json',
'--grep',
storyId,
'--output',
outputDir,
'--workers',
'1', // Single worker for individual tests
];
// Batch test
const args = [
'@storybook-visual-regression/cli',
'test',
'--json',
'--output',
outputDir,
'--workers',
'4', // Multiple workers for batch tests
];
The addon expects JSON output from the CLI:
{
"status": "passed|failed|error",
"startTime": 1697548800000,
"duration": 5432,
"totalTests": 1,
"passed": 1,
"failed": 0,
"tests": [
{
"storyId": "components-button--primary",
"title": "Components / Button",
"name": "Primary",
"status": "passed|failed|error",
"duration": 2341,
"attachments": [
{
"name": "screenshot",
"path": "visual-regression/results/test-results/screenshot.png",
"type": "image/png"
}
]
}
]
}
The addon handles different image types and paths:
visual-regression/snapshots/ComponentName/StoryName.pngvisual-regression/results/test-results/screenshot.pngvisual-regression/results/test-results/screenshot-diff.pngThe API server serves images with proper MIME types and caching headers:
// Serve image with proper headers
res.setHeader('Content-Type', 'image/png');
res.setHeader('Cache-Control', 'public, max-age=3600');
res.setHeader('Access-Control-Allow-Origin', '*');
cd addon
npm install
npm run build
To develop the addon locally:
Link the addon to your project:
cd addon
npm link
cd your-project
npm link @storybook-visual-regression/addon
Build in watch mode:
cd addon
npm run watch
Start your Storybook:
npm run storybook
The addon can be extended with:
Symptoms: Clicking test buttons does nothing, no progress indicators appear
Causes & Solutions:
@storybook-visual-regression/cli is installed
npm install --save-dev @storybook-visual-regression/cli
npx playwright install chromium
lsof -i :6007chmod +x node_modules/.bin/storybook-visual-regression
Symptoms: Test results show broken images or "Image not found" errors
Causes & Solutions:
visual-regression/ directory exists--output /absolute/path/to/visual-regressionfile:// URLs
chmod -R 644 visual-regression/
Symptoms: No visual regression panel or toolbar buttons visible
Causes & Solutions:
.storybook/main.js includes the addon
module.exports = {
addons: ['@storybook-visual-regression/addon'],
};
Symptoms: Tests start but fail with errors
Causes & Solutions:
# In your config file
{
"waitTimeout": 60000,
"webserverTimeout": 180000,
"mutationTimeout": 2000
}
# Use fewer workers
--workers 2
# Try Firefox or WebKit
--browser firefox
Symptoms: Tests run slowly or UI becomes unresponsive
Causes & Solutions:
--workers 2
--threshold 0.3 # Allow more pixel differences
--full-page false # Capture viewport only
Symptoms: Baseline updates fail or don't persist
Causes & Solutions:
chmod -R 755 visual-regression/snapshots/
Symptoms: API server fails to start or respond
Causes & Solutions:
kill -9 $(lsof -t -i:6007)NODE_OPTIONS="--max-old-space-size=4096" npm run storybook
Symptoms: Tests fail with "command not found" or "permission denied"
Causes & Solutions:
npm install --save-dev @storybook-visual-regression/cli
chmod +x node_modules/.bin/storybook-visual-regression
Enable debug logging to troubleshoot issues:
# Enable debug mode in CLI
npx storybook-visual-regression test --debug
# Check browser console for addon errors
# Open Developer Tools → Console tab
# Check Storybook terminal for server errors
# Look for error messages in the terminal where Storybook is running
"Cannot find module '@storybook-visual-regression/cli'"
npm install --save-dev @storybook-visual-regression/cli"Port 6007 is already in use"
"ECONNREFUSED"
"Test timeout exceeded"
"Permission denied"
When reporting issues, include:
npx storybook --versionpackage.jsonnode --versionMIT
Contributions are welcome! This is an example addon that demonstrates integration patterns. Feel free to:
For issues related to:
FAQs
Fully functional Storybook addon for visual regression testing with built-in API server
We found that @storybook-visual-regression/addon demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.