Catch email client compatibility issues before your users do. Validates HTML and CSS against caniemail data for 30+ email clients including Gmail, Outlook, Apple Mail, and Yahoo.
$ npx @email-lint/core check welcome.html
welcome.html
12:5 error cursor not supported (4/4 variants) [gmail]
18:3 warning background-image not supported (2/6 variants: windows, windows-mail) [outlook]
24:10 warning <picture> not supported (4/4 variants) [gmail]
✖ 1 error, 2 warnings
# Lint an HTML email
npx @email-lint/core check welcome.html
# Lint a React Email component (renders to HTML automatically)
npx @email-lint/core check src/emails/welcome.tsx
# Check only Gmail compatibility
npx @email-lint/core check welcome.html --preset gmail,outlooknpm install @email-lint/corecaniemail parses your HTML and CSS and hands back structured errors and warnings, with helpers to group and format them. email-lint is the linter on top: it decides which of those you should care about, and gets the answer into your terminal and your CI:
- Collapses by family — 4 Gmail variants become one line:
(4/4 variants) [gmail] - Smart severity —
cursoris cosmetic (info, not error). Gmail forcestarget="_blank"on all links — if you already use it, that's info too - React Email aware — Suppresses false positives from framework internals (preview blocks, preload images, forced
target="_blank") - CI-ready — Exits 1 on errors, 0 when only warnings remain. GitHub Actions formatter shows inline annotations on PR diffs
- TSX support — Point it at a
.tsxcomponent, it renders and lints in one step
npm install @email-lint/react-emailimport { lintComponent } from '@email-lint/react-email';
const result = await lintComponent(<Welcome name="Jane" />);
// Framework-aware filtering enabled by defaultOr use the CLI directly — it auto-detects .tsx files:
email-lint check src/emails/welcome.tsx# GitHub Actions
- name: Lint emails
run: npx @email-lint/core check 'src/emails/**/*.html' --format github# Any CI — exit code 1 on errors
email-lint check src/emails/ --format jsonimport { expect, test } from 'vitest';
import { lintComponent } from '@email-lint/react-email';
import { Welcome } from './emails/welcome';
test('Welcome email has no compatibility errors', async () => {
const result = await lintComponent(<Welcome name="Jane" />);
expect(result.errorCount).toBe(0);
});
test('Welcome email passes Gmail checks', async () => {
const result = await lintComponent(<Welcome name="Jane" />, { preset: 'gmail' });
expect(result.success).toBe(true);
});| Package | Description | |
|---|---|---|
@email-lint/core |
Linter engine + CLI | |
@email-lint/react-email |
React Email integration |
pnpm install
pnpm build
pnpm testMIT