The email development toolkit for the 21st century

Brail provides batteries-included tooling for creating, generating and delivering email templates. It aims to bring email development into the 21st century by providing a modern, developer-friendly experience.

npx @brail/create-app


Idiomatic React

Write email templates using React syntax you know and love.


Built-in Type-safety

Enjoy end-to-end type-safety, from React through to the server.


Framework Agnostic

Brail integrates with your favourite meta-frameworks.

{ }


Enjoy first-in-class DX and rich devtools. Live-reloading out-of-the-box.



Easily theme email templates using a stitches-like API.


Instant APIs

Instantly serve your templates via type-safe APIs and/or SDKs.


Create a template

  1. Create a template view using idiomatic React.
/* πŸ“„ my-template.tsx */
import Brail from "@brail/react";
import z from "zod";
const b = Brail.init();
	/** πŸ‘‡ Create your template */
const MyTemplateView = (props) => {
	return <Email>
					<Typography>Welcome, {}</Typography>
  1. Define validation schema and sending logic (optional).
export default b.template
		/** πŸ‘‡ Define meta schema (optional) */
	.meta(z.object({ to: z.string(), sendGridApiKey: z.string() }))
		/** πŸ‘‡ Define props schema (optional) */
	.props(z.object({ name: z.string() }))
	/** πŸ‘‡ Define a send function (optional) */
	.onSend(async (args) => {
		const { meta, html } = args;
		const res = await sendGrid.send(html, {
			apiKey: meta.sendGridApiKey,
		return { ok: res.status === 200 };
	.view(MyTemplateView); /** πŸ‘ˆ Register template view */

Use your template

You can now generate templates directly...

// Use your template directly
const html = myTemplate.render({/** Props */})
const sendResponse = await myTemplate.send({/** data: {}, meta: {} */})

Or serve them via a tRPC (opens in a new tab) API.

/* πŸ“„ lib/trpc.ts */
import { createTrpcRouter } from "brail/trpc";
import { initTrpc } from "@trpc/server";
const appRouter = createTrpcRouter({
	templates: { myTemplate },
	t: initTrpc.create()
/* πŸ“„ pages/api/trpc/[trpc].ts */
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
// Serve templates via edge runtime function
export default async function handler(req: NextRequest) {
	return fetchRequestHandler({
		endpoint: "/api/trpc",
		router: appRouter,
		createContext: () => ({}),

Keep working with your favourite tools

Brail sits on top of your favourite meta-frameworks and uses tools you already know, including Zod (opens in a new tab) and tRPC (opens in a new tab).

Get started

npx @brail/create-app

Development status


Brail is currently in Beta, as any last bugs are ironed out. We're looking for feedback and contributions.