GitHub - Giorgi-Kavtaradze/postcraft: 💌 Build and send emails using React · GitHub
Skip to content
Giorgi-KavtaradzePublic

About

💌 Build and send emails using React

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

██████╗  ██████╗ ███████╗████████╗ ██████╗██████╗  █████╗ ███████╗████████╗
██╔══██╗██╔═══██╗██╔════╝╚══██╔══╝██╔════╝██╔══██╗██╔══██╗██╔════╝╚══██╔══╝
██████╔╝██║   ██║███████╗   ██║   ██║     ██████╔╝███████║█████╗     ██║
██╔═══╝ ██║   ██║╚════██║   ██║   ██║     ██╔══██╗██╔══██║██╔══╝     ██║
██║     ╚██████╔╝███████║   ██║   ╚██████╗██║  ██║██║  ██║██║        ██║
╚═╝      ╚═════╝ ╚══════╝   ╚═╝    ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝        ╚═╝

Postcraft React TypeScript Node

🚀 The next generation of writing emails.

Postcraft is a collection of high-quality, unstyled components for creating beautiful, responsive emails with React and TypeScript.

✨ Features  🧰 Tech Stack  🚀 Getting Started  📦 Packages  ✍️ Editor  🔌 Integrations  🛠️ CLI

npm version npm downloads License: MIT PRs Welcome GitHub Stars


✨ Overview

Postcraft is a collection of high-quality, unstyled components for creating beautiful email templates using React and TypeScript. We handle inconsistencies across Gmail, Apple Mail, Outlook, and other email clients — so you can focus on content.

💡 Why Postcraft? We believe email is an extremely important communication medium. It's time to stop developing emails like it's 2010 and rethink how email can be done in 2026 and beyond.

✨ Feature Matrix

🧱
Component-based
Reusable React
components
🎨
Tailwind CSS
Email-safe utility
presets
📱
Responsive
Works on every
screen size
🌙
Dark mode aware
Automatic theme
handling
✍️
Visual Editor
Drag-and-drop
@postcraft/editor
🔌
Provider Ready
Resend, Nodemailer,
SendGrid, & more
🧪
Fully Typed
First-class
TypeScript support
🚀
CLI Included
postcraft dev /
postcraft export

🧰 Technologies

This monorepo is built with the following stack.

Languages & runtime

TypeScript    React    Node.js

Email & product libraries

Tailwind CSS    TipTap    ProseMirror    Radix UI    Socket.IO    esbuild    Babel

Apps & sites

Next.js    Mintlify    Framer Motion    Three.js    React Three Fiber    Supabase    Resend    Zod    Lucide

Monorepo, build & quality

pnpm    Turborepo    Vite    Biome    Vitest    Playwright    Testing Library    GitHub Actions

💡 All logos above are the official brand marks of each respective project. Hover over any icon to see the technology name.


📦 Packages

This monorepo is organized into the following packages:

Package Version Description
postcraft npm Core React components for building email templates
@postcraft/render npm Transform React components into HTML email templates
@postcraft/editor npm Rich text editor built on Tiptap & ProseMirror
create-postcraft npm Scaffold a new Postcraft project in seconds
@postcraft/ui npm Shared UI components used across the monorepo
@responsive-email/postcraft npm Responsive email layout components

� How It Works

Component Authoring Flow

flowchart LR
    Compose["Compose email in JSX"] --> Tailwind["<Tailwind> wraps tree & scans className"]
    Tailwind --> Inline["Inline-able rules → element style attributes"]
    Tailwind --> Head["Non-inline-able rules → <style> in <Head>"]
    Tailwind --> Downlevel["Downlevel for Gmail, Outlook, Apple Mail"]
    Inline --> Render["Rendered to email-ready HTML"]
    Head --> Render
    Downlevel --> Render
    Render --> Send["Send via Resend, Nodemailer, SendGrid, ..."]
Loading

CLI Preview & Export Flow

flowchart LR
    Cli["postcraft dev / postcraft export"] --> Scan["Scan ./emails directory"]
    Scan --> Meta["Resolve files, dirs & dependencies"]
    Meta --> Build["esbuild-bundle templates"]
    Build --> Render["Render each template to HTML / plain text"]
    Dev["postcraft dev"] --> Server["Start Next.js preview server"]
    Server --> WS["Socket.IO hot-reload on file change"]
    WS --> Live["Live preview in browser at localhost:3000"]
    Export["postcraft export"] --> Out["Write static .html output to ./out"]
Loading

Visual Editor Flow

flowchart LR
    Edit["Drag-and-drop email in @postcraft/editor"] --> JSON["ProseMirror / TipTap JSON document"]
    JSON --> Serialize["EmailNode / EmailMark serializer"]
    Serialize --> Postcraft["Render to Postcraft components"]
    Postcraft --> Compose["composeEmail() → HTML + plain text"]
    Compose --> Export["Export or send"]
Loading

Dual Runtime Rendering Flow

flowchart LR
    ReactComp["React email component"] --> Runtime{"Runtime?"}
    Runtime -->|"Node.js"| RenderNode["@postcraft/render (node)"]
    Runtime -->|"Edge / Browser"| RenderEdge["@postcraft/render (edge / browser)"]
    RenderNode --> ReadableStream["react-dom/server ReadableStream"]
    RenderEdge --> ReadableStream
    ReadableStream --> Html["DOCTYPE-ready HTML string"]
    ReadableStream --> Text["Plain text alternative"]
    Html --> Providers["Send via any ESP"]
    Text --> Providers
Loading

Monorepo Architecture Overview

flowchart TB
    Browser["Browser / Next.js preview"]
    Core["postcraft core components"]
    Editor["@postcraft/editor rich text editor"]
    Renderer["@postcraft/render React → HTML"]
    Tailwind["Email-safe Tailwind CSS engine"]
    TipTap["TipTap + ProseMirror"]
    Responsive["@responsive-email/postcraft layouts"]
    Ui["@postcraft/ui shared UI"]
    Cli["postcraft CLI"]
    Providers["Resend · Nodemailer · SendGrid · Mailgun · Postmark · AWS SES · Plunk · Scaleway · MailerSend"]

    Browser -->|"Preview templates"| Core
    Cli -->|"dev / export / build / start"| Browser
    Cli -->|"esbuild-bundle + render"| Renderer
    Editor -->|"EmailNode / EmailMark"| Core
    Editor -->|"Document model"| TipTap
    Core -->|"Inline styles & <head> rules"| Tailwind
    Core -->|"Shared primitives"| Ui
    Responsive -->|"Compose"| Core
    Renderer -->|"HTML / plain text"| Providers
    Ui -->|"Preview server"| Browser
Loading

🚀 Getting Started

Prerequisites

  • Node.js >= 20.0.0
  • pnpm >= 11.0.0 (or npm / yarn / bun)

Quick Start

Scaffold a new project in seconds:

npx create-postcraft@latest
cd my-email-project
npm install
npm run dev

The dev server starts at http://localhost:3000 with a live preview interface for your email templates.

Manual Installation

Add Postcraft to an existing project:

npm install postcraft
# or
pnpm add postcraft
# or
yarn add postcraft

Your First Email

import {
  Html,
  Head,
  Body,
  Container,
  Heading,
  Text,
  Button,
  Preview,
  Tailwind,
  pixelBasedPreset,
} from "postcraft";

interface WelcomeEmailProps {
  name: string;
  verificationUrl: string;
}

const tailwindConfig = {
  presets: [pixelBasedPreset],
};

export default function WelcomeEmail({
  name,
  verificationUrl,
}: WelcomeEmailProps) {
  return (
    <Html lang="en">
      <Tailwind config={tailwindConfig}>
        <Head />
        <Body className="bg-gray-100 font-sans">
          <Preview>Welcome to Postcraft — Verify your email</Preview>
          <Container className="max-w-xl mx-auto p-8">
            <Heading className="text-2xl font-bold text-gray-900">
              Welcome, {name}!
            </Heading>
            <Text className="text-base text-gray-600 mt-4">
              Thanks for signing up. Please verify your email address to get
              started.
            </Text>
            <Button
              href={verificationUrl}
              className="bg-blue-600 text-white px-6 py-3 rounded-md block text-center no-underline box-border mt-6"
            >
              Verify Email Address
            </Button>
          </Container>
        </Body>
      </Tailwind>
    </Html>
  );
}

WelcomeEmail.PreviewProps = {
  name: "Giorgi",
  verificationUrl: "https://postcraft.dev/verify/abc123",
} satisfies WelcomeEmailProps;

Rendering to HTML

Convert your React email component to an HTML string ready for sending:

import { render } from "@postcraft/render";
import { WelcomeEmail } from "./emails/welcome";

const html = await render(
  <WelcomeEmail name="Giorgi" verificationUrl="https://example.com/verify" />,
);
const text = await render(
  <WelcomeEmail name="Giorgi" verificationUrl="https://example.com/verify" />,
  { plainText: true },
);

🧩 Components

A set of standard, cross-client compatible components to help you build beautiful emails without dealing with table-based layouts.

Layout

Component Description
Html Root HTML wrapper with lang attribute
Head Email head element for meta, styles, fonts
Body Main body wrapper
Container Centered content wrapper (max-width: 37.5em)
Section Interior content block for grouping
Row Horizontal row for multi-column layouts
Column Column within a Row

Content

Component Description
Preview Inbox preview text (always first in Body)
Heading h1–h6 heading elements
Text Paragraph text blocks
Button Styled call-to-action link button
Link Inline hyperlinks
Img Responsive image component
Hr Horizontal divider

Specialized

Component Description
Tailwind Tailwind CSS support for emails
Font Custom web font loading
Markdown Render Markdown content in emails
CodeBlock Syntax-highlighted code blocks
CodeInline Inline code formatting

✍️ Visual Editor

Postcraft provides a rich text email editor built on TipTap and ProseMirror. It serializes content to Postcraft components and exports email-ready HTML and plain text.

Features

Feature Description
🧠 Bubble Menu Contextual formatting toolbar on selection
🎛️ Inspector Property editing panel for selected elements
⚡ Slash Commands Type / to quickly insert elements
🎨 Theming Built-in themes (basic, minimal) with CSS customization
📐 Column Layouts Drag-and-drop multi-column email structures
🔗 Link Editing Inline link management
📤 Email Export composeEmail() to export email-ready HTML
🖼️ Image Upload Built-in image upload support

Installation & Quick Start

npm install @postcraft/editor
import { EmailEditor, type EmailEditorRef } from "@postcraft/editor";
import "@postcraft/editor/themes/default.css";
import { useRef } from "react";

export function MyEditor() {
  const ref = useRef<EmailEditorRef>(null);

  return (
    <EmailEditor
      ref={ref}
      content="<p>Start typing your email...</p>"
      theme="basic"
    />
  );
}

Entry Points

Import Contents
@postcraft/editor Main EmailEditor component and top-level API
@postcraft/editor/core Serializer, types, and event bus
@postcraft/editor/extensions 35+ TipTap extensions for email elements
@postcraft/editor/ui Bubble menus, slash command, inspector
@postcraft/editor/plugins ProseMirror plugins
@postcraft/editor/utils Shared utilities

🔌 Integrations

Emails built with Postcraft can be sent with any email service provider:

Provider Example
Resend examples/resend
Nodemailer examples/nodemailer
SendGrid examples/sendgrid
MailerSend examples/mailersend
Mailgun examples/mailgun
Postmark examples/postmark
AWS SES examples/aws-ses
Plunk examples/plunk
Scaleway examples/scaleway

Example: Sending with Resend

import { Resend } from "resend";
import { WelcomeEmail } from "./emails/welcome";

const resend = new Resend(process.env.RESEND_API_KEY);

const { data, error } = await resend.emails.send({
  from: "Acme <onboarding@resend.dev>",
  to: ["user@example.com"],
  subject: "Welcome to Acme!",
  react: (
    <WelcomeEmail name="Giorgi" verificationUrl="https://example.com/verify" />
  ),
});

🛠️ CLI Reference

Postcraft ships with a powerful CLI to streamline your email development workflow.

Command Description
postcraft dev Start live preview server (default: ./emails, port 3000)
postcraft dev --dir <path> --port <port> Start server with custom options
postcraft export Export all templates to static HTML in ./out
postcraft export --dir <path> --outDir <path> --pretty --plainText Export with options
postcraft build Build the preview app for production deployment
postcraft start Run the built preview app
postcraft resend setup Connect CLI to Resend via API key
postcraft resend reset Remove stored Resend API key

🏗️ Monorepo Structure

postcraft/
├── apps/
│   ├── demo/                    # Demo email templates showcase
│   ├── docs/                    # Documentation site (Mintlify)
│   └── web/                     # Marketing website (Next.js)
├── benchmarks/                  # Performance benchmarks
│   └── tailwind/
├── examples/                    # Email service provider integrations
│   ├── aws-ses/
│   ├── mailersend/
│   ├── mailgun/
│   ├── nodemailer/
│   ├── plunk/
│   ├── postmark/
│   ├── resend/
│   ├── scaleway/
│   └── sendgrid/
├── packages/
│   ├── create-email/            # Scaffolding CLI (npx create-postcraft)
│   ├── editor/                  # Rich text visual editor
│   ├── postcraft/               # Core email components & CLI
│   ├── render/                  # React → HTML renderer
│   ├── responsive-email-postcraft/  # Responsive email components
│   ├── tsconfig/                # Shared TypeScript configs
│   └── ui/                      # Shared UI components (preview server)
├── playground/                  # Interactive component playground
├── scripts/                     # Build & release automation scripts
└── skills/                      # AI agent skills for email development
    └── postcraft/

Setting Up Your Environment

# Clone the repository
git clone https://github.com/GiorgiKavtaradze-prog/postcraft.git
cd postcraft

# Install all dependencies
pnpm install

# Build all packages
pnpm build

# Run all tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Lint the codebase
pnpm lint

# Auto-fix linting issues
pnpm lint:fix

Linking the CLI Globally

To avoid rebuilding after every change when working on the CLI:

# Link the dev version globally
pnpm link ./dev -g

# Use it just like the regular CLI
postcraft-dev [command] [flags]

🤝 Contributing

We welcome contributions from the community! Please read our Contributing Guide before getting started.


🛡️ Security

Please read our Security Policy to learn how to report security vulnerabilities responsibly.


📄 License

This project is licensed under the MIT License — see the LICENSE.md file for details.


Built with ❤️ by Giorgi Kavtaradze and the Postcraft community

About

💌 Build and send emails using React

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages