
Every product team eventually hits the same wall with email: a welcome.html file ballooning into a 1,200-line monolith, copy-pasted styles across templates that never quite match, a marketing tweak that breaks billing emails, and an A/B test that takes a week to ship because the "templating engine" lives in a folder no one wants to touch.
Email is one of the last places in modern product engineering where we still tolerate this. We componentized our UI years ago. We componentized our backends. But our transactional and lifecycle emails are still strings of HTML glued together inside a service.
At Bit, we manage every email template - welcome, billing, organization invites, password resets, notifications - as independent, versioned, composable components. Each piece of an email (a title, a paragraph, a CTA button, a card, a footer) is its own component. Each template (welcome, payment-failed, scope-invite) composes those pieces.
This post walks through how we got there, and how you can do the same.