What is this?
@playwright-labs/reporter-email is a Playwright reporter that emails your team the test results after each CI run. This release adds 4 new templates built on shadcn/ui.
The core challenge
shadcn/ui is not email-compatible out of the box. Three things break:
- Radix UI — shadcn uses Radix for interactive behaviour (Select, Dialog, etc.). Radix calls browser APIs (
window, document) at import time. @react-email/render runs in Node.js with none of these.
- CSS variables — shadcn default config generates
hsl(var(--foreground)). Email clients don't support CSS variables.
- JSX transform conflict — in a Playwright project, esbuild replaces React's JSX with Playwright's own internal representation. That breaks
@react-email/render.
Fixes
Radix: Rewrote all primitives as plain HTML. SelectItem is a <div> with a conditional ✓ span. Button is an <a> tag. No Radix import anywhere.
CSS variables: Set "cssVariables": false in components.json. shadcn then generates bg-slate-900 (concrete value) instead of bg-background (CSS variable).
JSX transform: Added /* @jsxImportSource react */ pragma to every .tsx component file. esbuild respects per-file pragma overrides, so React's JSX runtime is used instead of Playwright's.
New templates
base-chart — pass-rate bar

import { PlaywrightReportShadcnChartEmail }
from "@playwright-labs/reporter-email/templates/shadcn/base-chart";
<PlaywrightReportShadcnChartEmail result={result} testCases={testCases} >
Adds a stacked horizontal bar showing the percentage of passed / failed / skipped tests. Pure CSS, no images.

import { PlaywrightReportShadcnButtonEmail }
from "@playwright-labs/reporter-email/templates/shadcn/base-button";
<PlaywrightReportShadcnButtonEmail
result={result}
testCases={testCases}
reportUrl="https://ci.example.com/report/42"
>
A footer with "View Full Report" and optionally "View N Failure(s)". Buttons are <a> tags styled with shadcn button variants.
base-themes — 6 color themes
import { PlaywrightReportShadcnThemesEmail }
from "@playwright-labs/reporter-email/templates/shadcn/base-themes";
<PlaywrightReportShadcnThemesEmail result={result} testCases={testCases} theme="green" >
Themes: slate | zinc | rose | blue | green | orange. Each changes the accent bar, headings, and row backgrounds.
Import only what you need
Each template is a separate bundle under dist/templates/shadcn/. Individual imports:
// Only loads base-select bundle, nothing else
import { PlaywrightReportShadcnSelectEmail }
from "@playwright-labs/reporter-email/templates/shadcn/base-select";
Or use the barrel for multiple templates:
import {
PlaywrightReportShadcnChartEmail,
PlaywrightReportShadcnThemesEmail,
} from "@playwright-labs/reporter-email/templates/shadcn";
Requires "moduleResolution": "bundler" in tsconfig.json to resolve the exports subpaths.
Run the preview locally
git clone https://github.com/vitalics/playwright-labs
cd playwright-labs && pnpm install
pnpm --filter @playwright-labs/reporter-email build
cd packages/reporter-email/examples && pnpm email:preview
Opens at http://localhost:3000. Edit any file in emails/ and the server hot-reloads.
GitHub: https://github.com/vitalics/playwright-labs
npm: @playwright-labs/reporter-email