Vitest’s HTML reporter is excellent — interactive, fast, and genuinely useful for debugging. But it generates local files. When your teammate asks “what failed?”, you can’t just send them a link. You end up screenshotting terminal output or walking them through downloading CI artifacts.
The Sharing Problem
After vitest run, your HTML report lands in a local directory. To share it with your team, you need to get that file to them somehow. Here’s what most teams do:
Common (Bad) Solutions
1. CI artifacts
- GitHub Actions keeps artifacts for 90 days max, other CI systems are shorter
- Finding the right artifact means clicking through workflow runs
- Recipient downloads a zip, extracts it, opens
index.htmllocally - QA might not even have CI access
2. Email or Slack the file
- “Here’s the test report” with a zip attachment
- Recipient has to download, extract, open in browser
- Version confusion when multiple runs are in flight
3. Upload to S3 manually
- Works, but someone has to set up the bucket, permissions, and cleanup
- Manual step every time — gets skipped when things are busy
4. Paste terminal output
- Loses all the interactive HTML goodness
- Hard to parse in a Slack thread
- Can’t reference it later
Better: Hosted Vitest Reports with Shareable Links
The fix is straightforward: upload your Vitest reports to a hosting service after every CI run. Every test run gets a permanent URL that anyone on your team can open.
What This Looks Like
- CI runs your Vitest tests
- Reports upload automatically
- You get a URL like
https://app.gaffer.sh/reports/abc123 - Share it in Slack, GitHub PRs, Jira — anywhere
- Anyone with access sees the full interactive report
No downloads. No manual steps. No expiring artifacts.
Setting Up Vitest Report Sharing with Gaffer
Step 1: Configure Vitest Reporters
Make sure you’re generating output Gaffer can parse. CTRF gives the richest analytics:
npm install vitest-ctrf-json-reporter --save-devimport { defineConfig } from 'vitest/config'
export default defineConfig({ test: { reporters: ['default', 'vitest-ctrf-json-reporter'], }})Gaffer also accepts Vitest’s built-in HTML and JSON reporters if you prefer those.
Step 2: Add the Upload Step to CI
GitHub Actions:
- name: Run tests run: npm test
- name: Upload to Gaffer if: always() uses: gaffer-sh/gaffer-uploader@v1 with: gaffer_api_key: ${{ secrets.GAFFER_UPLOAD_TOKEN }} report_path: ./test-results commit_sha: ${{ github.sha }} branch: ${{ github.ref_name }}GitLab CI:
test: script: - npm ci - npm test after_script: - | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: $GAFFER_UPLOAD_TOKEN" \ -F "files=@ctrf-report.json" \ -F 'tags={"commitSha":"'"$CI_COMMIT_SHA"'","branch":"'"$CI_COMMIT_REF_NAME"'"}'Step 3: Share the Link
After upload, Gaffer returns a URL. Share it anywhere — Slack, GitHub PR comments, Jira tickets. Recipients see the full report in their browser.
For people outside your organization, you can generate a public share link with configurable expiration. They view the full interactive report without needing a Gaffer account.
Slack and Webhook Notifications
Instead of checking CI manually, get notified when tests finish:
Slack integration:
- Pass/fail summary posted to your channel
- Direct link to the full report
- Filter by branch — only notify on
main, skip feature branches
Webhooks:
- Send test results to any endpoint
- Integrate with your existing alerting or workflow tools
- Trigger custom actions on failure
No more “did the tests pass?” messages. Your team sees failures as they happen, with a link to investigate.
GitHub Integration
Commit statuses show test results directly on PRs. No clicking through to CI logs — you see pass/fail right on the commit.
What About Flaky Tests?
Vitest’s --retry flag handles flaky tests within a single run. Gaffer tracks flakiness across runs — identifying tests that sometimes pass and sometimes fail over time. Different problem, complementary solution.
Get Started
Gaffer’s free tier includes 500 MB of storage with 7-day retention. Paid plans offer extended retention up to 90 days.