What I built
An email template editor where you describe what you want and the AI builds it.
Generate:
- "Create a welcome email for new users"
- Full template in 5 seconds — header, personalized greeting, CTA, footer
Iterate:
- "Make the button green"
- "Add a section about our mobile app"
- "Show a discount code only for new users"
Then edit visually or in code. Chat → Visual → Code. Same template.
Why this works (and most AI editors don’t)
Most AI-to-email tools generate raw HTML. You get a blob of code, maybe it works, probably it breaks in Outlook, and you can’t easily edit it.
This editor does something different: the AI generates editor structure, not HTML.
Specifically, it outputs TipTap JSON that maps to React Email components:…
What I built
An email template editor where you describe what you want and the AI builds it.
Generate:
- "Create a welcome email for new users"
- Full template in 5 seconds — header, personalized greeting, CTA, footer
Iterate:
- "Make the button green"
- "Add a section about our mobile app"
- "Show a discount code only for new users"
Then edit visually or in code. Chat → Visual → Code. Same template.
Why this works (and most AI editors don’t)
Most AI-to-email tools generate raw HTML. You get a blob of code, maybe it works, probably it breaks in Outlook, and you can’t easily edit it.
This editor does something different: the AI generates editor structure, not HTML.
Specifically, it outputs TipTap JSON that maps to React Email components:
{
"type": "doc",
"content": [
{
"type": "emailSection",
"content": [
{
"type": "emailHeading",
"attrs": { "level": 1 },
"content": [
{ "type": "text", "text": "Welcome, " },
{ "type": "variable", "attrs": { "name": "firstName", "fallback": "there" } },
{ "type": "text", "text": "!" }
]
}
]
}
]
}
This structure is:
- Editable — click any element, change it visually
- Validated — only known node types allowed, hallucinations get caught
- Portable — serialize to React Email, HTML, or plain text
The AI architecture
Constrained generation
The system prompt tells Claude exactly which node types exist:
const VALID_NODES = [
'emailSection',
'emailHeading',
'emailText',
'emailButton',
'emailImage',
'emailDivider',
'emailSpacer',
'emailRow',
'emailColumn',
'variable',
'conditional'
]
Each node has a spec: what props it accepts, what’s required, examples of valid output.
Claude can only use these nodes. If it tries to invent emailCarousel or fancyWidget, the validator rejects it before it hits the editor.
Iterative editing
When you say "make the button green", the AI receives:
- Your message
- The current template JSON
- Instruction to make targeted edits, not regenerate everything
So it finds the button node, updates style.backgroundColor, returns the modified JSON. Fast and predictable.
Brand kit integration
The system prompt includes the user’s brand kit:
Primary Color: #5046e5
Font Family: Inter, sans-serif
Button Style: rounded (4px radius)
Company Name: Acme Inc
Logo URL: https://...
Generated templates automatically use these defaults. Less manual fixing.
The stack
Editor: TipTap (ProseMirror-based)
Email output: React Email
AI: Vercel AI SDK + Claude Sonnet
State: Zustand
Framework: Next.js 16
Database: PostgreSQL + Drizzle
UI: shadcn/ui + Tailwind
Why TipTap?
TipTap lets you define custom nodes for your domain. Each React Email component (<Button>, <Section>, <Heading>) gets a corresponding TipTap node with its own schema and rendering.
The editor doesn’t know it’s building emails — it just knows it has nodes with certain attributes. The serializer handles the React Email conversion at export time.
Why React Email?
It outputs HTML that actually works in email clients. Outlook, Gmail, Apple Mail — the hard stuff is handled. And the component model maps cleanly to editor nodes.
Is this vibe coding?
Here’s what I had before writing any code:
- Database schema (templates, versions, blocks, brand kits, AI conversations)
- State management design
- API routes spec
- Component architecture
- Full list of TipTap extensions needed
- AI system prompt and validation strategy
The AI didn’t write any of that. I did — based on almost two years at SendGrid seeing what breaks in email infrastructure.
AI helped me implement fast. Describe a component, get 80% of the code, fix edge cases, move on. But the architecture? The constraints that make the AI output actually usable? That’s experience.
The unlock: build at the speed of your ideas.
If you have the ideas, AI is a multiplier. If you don’t, you get fast spaghetti.
What this is part of
This editor is one piece of Wraps.
The problem: AWS SES is cheap (~$1/10k emails) but painful. 90% of developers abandon during domain verification.
The alternative: SaaS tools (Resend, Postmark) have great DX but cost 10-100x more and lock you in.
Wraps: SaaS-quality developer experience, but deploys to YOUR AWS account. You own it. You pay AWS directly. If you stop paying us, your email keeps working.
The template editor lets you build emails with AI, edit visually, and send tests through your own SES.
More coming: SMS, background jobs, team dashboard, real-time collaboration.
Questions?
Happy to go deeper on:
- The TipTap → React Email serialization
- How the AI validation works
- The conditional block implementation
- Anything else
Roast the architecture in the comments.