{"_id":"@cascivo/email","_rev":"4-34f60ce5aca7b391e3dd9cb84fa1fa42","name":"@cascivo/email","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@cascivo/email","version":"0.1.0","keywords":["cascivo","design-system","email","html-email","react","transactional-email"],"author":"urbanisierung","license":"MIT","_id":"@cascivo/email@0.1.0","maintainers":[{"name":"urbanisierung","email":"adam.urban@gmail.com"}],"homepage":"https://github.com/cascivo/cascivo/tree/main/packages/email#readme","bugs":"https://github.com/cascivo/cascivo/issues","dist":{"shasum":"793f596a764f145efb145deb6f8431c26e98053b","tarball":"https://registry.npmjs.org/@cascivo/email/-/email-0.1.0.tgz","fileCount":5,"integrity":"sha512-8InjIFDPEbZqWv7CCsAA6cq51ddOuSq7H65Z5qtT953ydCiy0j79dx61gcZDr2EbkRm7cladeuQv0eTIFotAbQ==","signatures":[{"sig":"MEUCIECMaXEH/eo6NTRRRbJ71Enya92+3byLF0jeWu9RzMWPAiEAzA/lJMh2sIW7piT2T2Tvs6rUS1k/5N0oEINKZIeDZxU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":402768},"type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"scripts":{"dev":"vp pack --watch","test":"vp test","build":"vp build && node scripts/flatten-types.mjs && node scripts/check-types-flat.mjs","check":"tsc --noEmit"},"_npmUser":{"name":"urbanisierung","email":"adam.urban@gmail.com"},"repository":{"url":"git+https://github.com/cascivo/cascivo.git","type":"git","directory":"packages/email"},"description":"Render cascivo-themed transactional email — table-based, inline-styled HTML with no client JS. Components: @cascivo/react. Docs offline: npx @cascivo/docs","directories":{},"_nodeVersion":"24.20.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.7","react-dom":"^19.2.7","vite-plus":"^0.2.1","typescript":"^5","@types/node":"^25","@types/react":"^19.2.17","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","@types/react":">=18.0.0"},"peerDependenciesMeta":{"@types/react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/email_0.1.0_1788880337854_0.38403470713889276","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@cascivo/email","version":"0.2.0","keywords":["cascivo","design-system","email","html-email","react","transactional-email"],"author":"urbanisierung","license":"MIT","_id":"@cascivo/email@0.2.0","maintainers":[{"name":"urbanisierung","email":"adam.urban@gmail.com"}],"homepage":"https://github.com/cascivo/cascivo/tree/main/packages/email#readme","bugs":"https://github.com/cascivo/cascivo/issues","dist":{"shasum":"25332c53f846499e3f5d0c235d34408e28185554","tarball":"https://registry.npmjs.org/@cascivo/email/-/email-0.2.0.tgz","fileCount":6,"integrity":"sha512-Kw9zMHGpPRBWmRC6R6NT+YFOfs/RpK2acSsdSjWE8lECRvfdZM2Tm9M0KUxQ8ErENPUCugokkhSeeR4iuI4GJA==","signatures":[{"sig":"MEQCIAn/Se1EEXocFQSD80E1KjK8KXZsS/J3IHpzFPmnRc7NAiA7TO72yqJ76kTD3XGoBl+108J2NeT0za9Sib40kpia9A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDGCXXOFm1mRHK9CZA5LLIXl+qS7GTCBUY/M3S+4VhXVwIhAJUp0aMjTj/LIJMvhN8tfPH89mC0nZwRyob+2srSzYAc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cascivo%2femail@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":429881},"type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"scripts":{"dev":"vp pack --watch","test":"vp test","build":"vp build && node scripts/flatten-types.mjs && node scripts/check-types-flat.mjs","check":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:af4db8d0-694a-4fa0-a259-e1bf33765c10"}},"repository":{"url":"git+https://github.com/cascivo/cascivo.git","type":"git","directory":"packages/email"},"description":"Render cascivo-themed transactional email — table-based, inline-styled HTML, no client JS, zero runtime dependencies. Conformance-linted against the Can I email matrix. Docs offline: npx @cascivo/docs","directories":{},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.7","react-dom":"^19.2.7","vite-plus":"^0.2.1","typescript":"^5","@types/node":"^25","@types/react":"^19.2.17","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","@types/react":">=18.0.0"},"peerDependenciesMeta":{"@types/react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/email_0.2.0_1789414092093_0.7686473233994355","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@cascivo/email","version":"0.3.0","keywords":["cascivo","design-system","email","html-email","react","transactional-email"],"author":"urbanisierung","license":"MIT","_id":"@cascivo/email@0.3.0","maintainers":[{"name":"urbanisierung","email":"adam.urban@gmail.com"}],"homepage":"https://github.com/cascivo/cascivo/tree/main/packages/email#readme","bugs":"https://github.com/cascivo/cascivo/issues","dist":{"shasum":"b0422e4d89a0678fe073b6996dace6becbed0c28","tarball":"https://registry.npmjs.org/@cascivo/email/-/email-0.3.0.tgz","fileCount":6,"integrity":"sha512-35eRK1bRNwjU+mP13buc0Tb3xsgNnMAjQCfkjnRy+gAKlmsk1B2PQUDAQuqWOGnaAt7CSJ1tY62TkB3dlBJjkw==","signatures":[{"sig":"MEUCIQCtKCN1hZZ6AcRl0yTsWa4s9gtw8TmhWoIgUuX1bfow6AIgPHIPNjUzaKsQQgL54W3eqJutnOvwTWctWVjGH2UMG9w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCzUYZq5b036ny/K7gXOz8Kqgxi6eDmChAreRd/amRVZAIgXbvklejI7Je1goUcwuyFR7XMYzIlthq5g/73IaaRQj0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cascivo%2femail@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":435968},"type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"scripts":{"dev":"vp pack --watch","test":"vp test","build":"vp build && node scripts/flatten-types.mjs && node scripts/check-types-flat.mjs","check":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:af4db8d0-694a-4fa0-a259-e1bf33765c10"}},"repository":{"url":"git+https://github.com/cascivo/cascivo.git","type":"git","directory":"packages/email"},"description":"Render cascivo-themed transactional email — table-based, inline-styled HTML, no client JS, zero runtime dependencies. Conformance-linted against the Can I email matrix. Docs offline: npx @cascivo/docs","directories":{},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.7","react-dom":"^19.2.7","vite-plus":"^0.2.1","typescript":"^5","@types/node":"^25","@types/react":"^19.2.17","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","@types/react":">=18.0.0"},"peerDependenciesMeta":{"@types/react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/email_0.3.0_1789483733855_0.9881986133050165","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"_id":"@cascivo/email@0.4.0","bugs":"https://github.com/cascivo/cascivo/issues","dist":{"shasum":"c3a6cf5d34f42083a139d8754f464f782891e4db","tarball":"https://registry.npmjs.org/@cascivo/email/-/email-0.4.0.tgz","fileCount":6,"integrity":"sha512-JxKHx/g+QIJ4fLxVlFCdS63GlWnFsTeCx3XgCoga4FENg8AbOGTfNdGV4H+bkvxuRFOK7PqbNFEFfitHtobllQ==","signatures":[{"sig":"MEUCIQDlRFisiK/8TGR8JvZaznzJZYpz4N0bSdOXR+ahsxMxlQIgTzzqrCAb7Qx6e/nUuueHTi8ri5KvC5AzBi3vmNg1RhY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEzQZEILWQ6QB8DGQl5omlA7Ywtto55Gy6KtOsKkOcvGAiEArx1M4C5o0x2dCpy9Ls4xy2zmZvSsL+uljcoFd3l12fs="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cascivo%2femail@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":437921},"name":"@cascivo/email","type":"module","types":"./dist/index.d.ts","author":"urbanisierung","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"license":"MIT","private":false,"scripts":{"dev":"vp pack --watch","test":"vp test","build":"vp build && node scripts/flatten-types.mjs && node scripts/check-types-flat.mjs","check":"tsc --noEmit"},"version":"0.4.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:af4db8d0-694a-4fa0-a259-e1bf33765c10"}},"homepage":"https://github.com/cascivo/cascivo/tree/main/packages/email#readme","keywords":["cascivo","design-system","email","html-email","react","transactional-email"],"repository":{"url":"git+https://github.com/cascivo/cascivo.git","type":"git","directory":"packages/email"},"description":"Render cascivo-themed transactional email — table-based, inline-styled HTML, no client JS, zero runtime dependencies. Conformance-linted against the Can I email matrix. Docs offline: npx @cascivo/docs","directories":{},"maintainers":[{"name":"urbanisierung","email":"adam.urban@gmail.com"}],"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.7","react-dom":"^19.2.7","vite-plus":"^0.2.1","typescript":"^5","@types/node":"^25","@types/react":"^19.2.17","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","@types/react":">=18.0.0"},"peerDependenciesMeta":{"@types/react":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/email_0.4.0_1789570891485_0.10577444421585414"}}},"time":{"created":"2026-09-08T15:12:17.636Z","modified":"2026-09-16T15:01:32.029Z","0.1.0":"2026-09-08T15:12:17.975Z","0.2.0":"2026-09-14T19:28:12.197Z","0.3.0":"2026-09-15T14:48:53.941Z","0.4.0":"2026-09-16T15:01:31.591Z"},"bugs":"https://github.com/cascivo/cascivo/issues","author":"urbanisierung","license":"MIT","homepage":"https://github.com/cascivo/cascivo/tree/main/packages/email#readme","keywords":["cascivo","design-system","email","html-email","react","transactional-email"],"repository":{"url":"git+https://github.com/cascivo/cascivo.git","type":"git","directory":"packages/email"},"description":"Render cascivo-themed transactional email — table-based, inline-styled HTML, no client JS, zero runtime dependencies. Conformance-linted against the Can I email matrix. Docs offline: npx @cascivo/docs","maintainers":[{"name":"urbanisierung","email":"adam.urban@gmail.com"}],"readme":"<!-- generated by scripts/readme/generate.ts — edit readme.body.md, not this file -->\n\n<div align=\"center\">\n  <a href=\"https://cascivo.com\"><img src=\"https://cascivo.com/logo-mark-img-accent.svg\" width=\"72\" height=\"72\" alt=\"cascivo logo\"></a>\n  <h1>@cascivo/email</h1>\n  <p><strong>Render cascivo-themed transactional email — table-based, inline-styled HTML, no client JS, zero runtime dependencies. Conformance-linted against the Can I email matrix. Docs offline: npx @cascivo/docs</strong></p>\n\n[![npm](https://img.shields.io/npm/v/%40cascivo%2Femail?style=flat-square&color=0079bf)](https://www.npmjs.com/package/@cascivo/email)\n[![downloads](https://img.shields.io/npm/dm/%40cascivo%2Femail?style=flat-square&color=0079bf)](https://www.npmjs.com/package/@cascivo/email)\n[![license](https://img.shields.io/npm/l/%40cascivo%2Femail?style=flat-square&color=0079bf)](https://github.com/cascivo/cascivo/blob/main/LICENSE)\n![types](https://img.shields.io/badge/types-included-0079bf?style=flat-square&logo=typescript&logoColor=white)\n\n[npm](https://www.npmjs.com/package/@cascivo/email) · [cascivo.com](https://cascivo.com) · [Docs](https://cascivo.com/docs) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/cascivo/cascivo)\n\n</div>\n\n---\n\nRender cascivo-themed HTML email — table-based, inline-styled, no client JS, and **no runtime\ndependencies** (only `react/jsx-runtime` and `react-dom/server`, both peers). Your product UI\nand the mail it sends share one design system: the same 12 themes and the same\ntokens, resolved to literal hex for clients that have never heard of `oklch()`.\n\n> **Docs offline?** The full cascivo reference ships as an npm package — `npx -y @cascivo/docs`, no website needed.\n\n## Install\n\n```sh\npnpm add @cascivo/email react react-dom\n```\n\n## Send one\n\n```tsx\nimport { assertSendable, renderEmail, PasswordReset, passwordResetSubject } from '@cascivo/email'\n\nconst message = renderEmail(<PasswordReset resetHref={link} />, {\n  theme: 'dark',\n  subject: passwordResetSubject(),\n  tier: 'strict',\n})\n\nassertSendable(message) // throws on no subject, no preheader, no text part, or a clipped body\nawait transport.send({ html: message.html, text: message.text, subject: message.subject })\n```\n\n`renderEmail` also returns `stats` — raw bytes, **quoted-printable-encoded** bytes (what Gmail\nactually measures when it decides to clip), node count and table depth.\n\n## Prose you do not have at build time\n\n`Markdown` is for copy written by an editor and fetched at send time — a newsletter preamble,\na CMS-driven confirmation letter — where there is nothing to compose into primitives ahead of\ntime.\n\n```tsx\nimport { Markdown, Section } from '@cascivo/email'\n;<Section padding={24}>\n  <Markdown imageWidth={552}>{issue.preamble}</Markdown>\n</Section>\n```\n\nIt parses an allowlisted node set — headings, paragraphs, `**strong**`, `*em*`, `` `code` ``,\nfenced blocks, links, images, ordered and unordered lists, blockquotes, rules — and renders\neach one **through the primitives, never as HTML**. That is what keeps the conformance lint\nmeaningful over a subtree whose content nobody reviewed: raw HTML in the source renders as its\nown literal text, and `href`/`src` are emitted only for `http:`, `https:` and `mailto:`.\nAnything outside the set degrades to text rather than throwing — prose fetched at send time\nmust never be able to fail a send.\n\nFor copy you _do_ know at build time, compose the primitives directly; it is smaller and you\nget the types.\n\n## Theming\n\n```tsx\nimport { PALETTES, renderEmail } from '@cascivo/email'\n\nrenderEmail(<Newsletter />, {\n  theme: { ...PALETTES.light, '--cascivo-color-accent': '#0057a3' },\n})\n```\n\nPass a theme name for one of the 12 shipped themes, or a `Palette` object to\noverride any token.\n\n### Fonts, and the biggest line in your byte budget\n\nEvery text primitive restates `font-family` inline. That is deliberate and load-bearing:\nOutlook Windows renders through Word, which does not carry an inherited `font-family` into\ntable content — and since every layout primitive here is a table, an element that states no\nface renders in Times New Roman there.\n\nIt is also expensive. One reported newsletter spent **15 KB, 20% of the message**, on 162\ncopies of the default stack. The lever is the _length_ of the stack, not the number of copies:\n\n```tsx\nrenderEmail(<Newsletter />, {\n  theme: { ...PALETTES.light, '--cascivo-email-font-sans': 'Arial, Helvetica, sans-serif' },\n})\n```\n\n`--cascivo-email-font-sans`, `-serif` and `-mono` are read by `fontStack()` and apply\neverywhere. They are keys on the palette object, not CSS custom properties — no email client\nsupports those, and declaring them in a stylesheet nothing reads would only cost every\nadopter bytes. They are also separate from the browser-facing `--cascivo-font-*` on purpose:\nthose begin `ui-sans-serif, system-ui`, which resolve to nothing in Outlook Windows, and a\nstack for an inbox is a different decision from a stack for a page. Set one and the default\nis untouched everywhere else.\n\nRun `analyze(message.html)` to see where your own bytes went; `repeatedDeclarations` is\nusually the actionable list.\n\n## Conformance lint\n\n`lint()` checks a finished render against the [Can I email](https://www.caniemail.com) support\nmatrix and reports anything your floor clients cannot handle.\n\n**The matrix is not bundled.** It is ~483 KB of test data that would otherwise sit in every\nadopter's `node_modules`, so you supply it:\n\n```ts\nimport { indexFeatures, lint, CASCIVO_ALLOW, type CanIEmailData } from '@cascivo/email'\n\n// Fetch once and cache it — https://www.caniemail.com/api/data.json (MIT, hteumeuleu/caniemail)\nconst data = (await (\n  await fetch('https://www.caniemail.com/api/data.json')\n).json()) as CanIEmailData\n\nconst findings = lint(message.html, indexFeatures(data), { allow: CASCIVO_ALLOW })\nconst blocked = findings.filter((f) => f.level === 'blocked')\n```\n\n`blocked` means a floor client genuinely does not support it; `caveat` means partial support\nworth knowing about. `CASCIVO_ALLOW` waives the findings the primitives knowingly accept, each\nwith a written reason. Pin the file in your repo if you want the linter's verdict to change\nonly in a reviewed diff rather than on the day upstream retests a client.\n\n## Coming from React Email\n\n```ts\nimport { formatMigration, planMigration } from '@cascivo/email'\n\nconsole.log(formatMigration(planMigration(['Html', 'Body', 'Button', 'Markdown', 'Tailwind'])))\n```\n\nMost of React Email's surface maps one-to-one. `planMigration` names every gap with the reason\nit exists, so you can size the port before writing any of it.\n\n## Install\n\n```sh\npnpm add @cascivo/email\n```\n\n---\n\n[cascivo.com](https://cascivo.com) · [Docs](https://cascivo.com/docs) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/cascivo/cascivo) · AI agents: read [`llms.txt`](https://cascivo.com/llms.txt) (install steps + component index, plain text) or use [`@cascivo/mcp`](https://github.com/cascivo/cascivo/tree/main/packages/mcp) and [`registry.json`](https://github.com/cascivo/cascivo/blob/main/registry.json) · MIT\n\n<div align=\"center\"><a href=\"https://cascivo.com\"><img src=\"https://cascivo.com/logo-mark-img.svg\" width=\"28\" height=\"28\" alt=\"cascivo\"></a></div>\n","readmeFilename":""}