Engine Package
Analyze & Score
Detect CSS compatibility issues and generate per-client compatibility scores, with optional framework-aware fix snippets.
analyzeEmail
Analyzes an HTML email and returns all CSS compatibility warnings across all clients.
The optional framework parameter controls which fix snippets are attached to warnings — it does not change which warnings fire. Analysis always runs on compiled HTML (what email clients actually receive). Fix snippets reference source-level constructs so users know how to modify their framework source code.
function analyzeEmail(html: string, framework?: Framework): CSSWarning[]Parameters
| Parameter | Type | Description |
|---|---|---|
html | string | The email HTML source code |
framework | Framework | Optional: "jsx", "mjml", or "maizzle". Attaches framework-specific fix snippets to warnings |
Returns
An array of CSSWarning objects:
interface CSSWarning {
severity: "error" | "warning" | "info";
client: string; // Client ID (e.g. "gmail-web")
property: string; // CSS property (e.g. "border-radius")
message: string; // Human-readable description
suggestion?: string; // How to fix it
fix?: CodeFix; // Before/after code snippet
line?: number; // Line number in source HTML
selector?: string; // CSS selector where issue was found
}Severity levels
| Severity | Meaning | Score impact |
|---|---|---|
error | Won't render correctly — broken layout or missing content | High |
warning | Degraded appearance — visual issues but content accessible | Medium |
info | Minor difference — cosmetic only | Low |
Example — generic analysis
import { analyzeEmail } from "@emailens/engine";
const warnings = analyzeEmail(emailHtml);
// Filter to errors only
const errors = warnings.filter((w) => w.severity === "error");
console.log(`${errors.length} critical issues found`);
// Group by client
const byClient = Object.groupBy(warnings, (w) => w.client);Example — framework-aware analysis
import { analyzeEmail } from "@emailens/engine";
// Get React Email-specific fix snippets
const warnings = analyzeEmail(compiledHtml, "jsx");
const outlookFlex = warnings.find(
(w) => w.client === "outlook-windows-legacy" && w.property === "display:flex"
);
console.log(outlookFlex.fix.language);
// "jsx"
console.log(outlookFlex.fix.after);
// import { Row, Column } from "@react-email/components";
// <Row>
// <Column>...</Column>
// </Row>generateCompatibilityScore
Generates a 0-100 compatibility score for each email client based on warnings.
function generateCompatibilityScore(
warnings: CSSWarning[]
): Record<string, { score: number; errors: number; warnings: number; info: number }>Parameters
| Parameter | Type | Description |
|---|---|---|
warnings | CSSWarning[] | Warnings from analyzeEmail() |
Returns
A record keyed by client ID. Each value contains:
| Field | Type | Description |
|---|---|---|
score | number | 0-100 compatibility score |
errors | number | Count of error-severity warnings |
warnings | number | Count of warning-severity warnings |
info | number | Count of info-severity warnings |
Example
import { analyzeEmail, generateCompatibilityScore } from "@emailens/engine";
const warnings = analyzeEmail(emailHtml);
const scores = generateCompatibilityScore(warnings);
for (const [clientId, data] of Object.entries(scores)) {
console.log(`${clientId}: ${data.score}/100 (${data.errors}E ${data.warnings}W ${data.info}I)`);
}