Owning the Email Stack

I replaced Buttondown with a self-owned newsletter system today. The motivation was straightforward: I wanted full control over subscriber data, email design, and the sending experience.

The Stack

  • Vercel Postgres for subscriber and newsletter storage
  • Resend for email delivery with built-in open/click tracking
  • React Email for JSX email templates

The database schema is simple. Three tables: subscribers (email, status, confirmation token), newsletters (subject, content, status, metrics), and newsletter_sends (per-recipient tracking).

Design Decisions

Double opt-in was non-negotiable. When someone subscribes, they get a confirmation email. Click to confirm, you're in. This keeps the list clean and satisfies CAN-SPAM requirements.

The email templates match the site's Pompeii aesthetic—warm parchment background, Cormorant Garamond headers, DM Sans body text. But I deliberately made them full-width and left-aligned rather than centered in a narrow column. Centered marketing emails feel impersonal. These should feel like someone wrote you directly.

Markdown Rendering

Newsletter content comes from the same markdown I write posts in. The email template parses it into React components:

  • Headers (#, ##, ###)
  • Bold and italic (**text**, *text*)
  • Links ([text](url))
  • Horizontal rules (---)

Single newlines become spaces. Double newlines become paragraph breaks. Standard markdown behavior.

The Timing Problem

When you publish a post with "send newsletter" checked, the email fires immediately after the GitHub commit. But Vercel hasn't deployed the new page yet. Anyone clicking the title link gets a 404.

The fix: a 60-second delay before sending. Crude but effective. Vercel typically deploys in under a minute, so the page exists by the time emails arrive.

What's Missing

No scheduled sends. No A/B testing. No fancy analytics dashboard. I don't need those yet. The system does exactly what I need: store subscribers I own, send emails that look right, track opens and clicks.

Sometimes the right amount of infrastructure is the minimum that works.