Resend: Transactional Email Done Right in 2026

Production-ready Resend setup guide with real error handling, React Email templates, and battle-tested patterns for indie hackers.

TL;DR

Resend eliminates email infrastructure headaches with a developer-first API, React-based templating, and reliable delivery. This guide covers production patterns, common pitfalls, and the exact errors you'll debug.

Why Resend Wins for Indie Hackers

Transactional email has historically meant choosing between fragile SMTP servers, vendor lock-in, or complex infrastructure. Resend (verify pricing in official docs for current rates) solves this by:

  • React Email templates - write JSX, not HTML string concatenation
  • Type-safe API - catch errors at build time, not in production
  • Generous free tier - 100 emails/day during development
  • Zero infrastructure - no servers, no SMTP credentials to rotate
  • The tradeoff? You're dependent on their uptime. For indie projects, this is usually the right bet.

    Getting Started: Setup That Won't Bite You Later

    Installation

    ```bash npm install resend react-email ```

    You'll need both packages. resend is the API client, react-email provides the template components and preview server.

    Environment Setup

    ```bash

    .env.local

    RESEND_API_KEY=re_xxx_your_key_here ```

    Critical: Never commit API keys. Use environment variables in all environments (development, staging, production). Verify the current API key format in [official docs](https://resend.com/docs/api-reference/introduction).

    Production Pattern: Welcome Email with Error Handling

    Here's a pattern that handles real failure modes:

    ```typescript // lib/email.ts import { Resend } from 'resend'; import WelcomeEmail from '@/emails/welcome';

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

    export async function sendWelcomeEmail({ email, name, }: { email: string; name: string; }) { try { const data = await resend.emails.send({ from: 'onboarding@yourdomain.com', to: email, subject: 'Welcome to StillNotAThing', react: <WelcomeEmail name={name} />, });

    // Always check the response if (data.error) { console.error('[Resend] Send failed:', data.error); // Log to Sentry, DataDog, etc. throw new Error(Email delivery failed: ${data.error.message}); }

    console.log('[Resend] Email sent:', data.data?.id); return { success: true, id: data.data?.id }; } catch (error) { if (error instanceof Error) { console.error('[Resend] Exception:', error.message); } throw error; } } ```

    Common Console Errors You'll Hit

    Error 1: Missing API Key ``` Error: RESEND_API_KEY is not defined at new Resend (index.js:1:45) ``` Fix: Verify .env.local exists and your environment loads it before the function runs.

    Error 2: Invalid Domain ``` Error: Email not sent. Invalid from address. Please add and verify your domain. at Object.<anonymous> (resend.ts:15:19) ``` Fix: You must verify domain ownership in Resend dashboard before sending from custom domains. Use onboarding@resend.dev for testing.

    Error 3: Rate Limiting (Production) ``` Error: Too many requests. Please wait before sending more emails. ``` Fix: Implement exponential backoff with a queue. See [implementing reliable queues](/?guide=queue-patterns) for production safety.

    React Email Templates: Write JSX, Not HTML

    This is Resend's killer feature. Your template is a React component:

    ```typescript // emails/welcome.tsx import { Body, Button, Container, Head, Hr, Html, Img, Link, Preview, Row, Section, Text, } from 'react-email';

    interface WelcomeEmailProps { name: string; }

    export default function WelcomeEmail({ name }: WelcomeEmailProps) { return ( <Html> <Head /> <Preview>Welcome to StillNotAThing</Preview> <Body style={main}> <Container style={container}> <Section style={box}> <Text style={heading}>Welcome, {name}! πŸš€</Text> <Hr style={hr} /> <Text style={paragraph}> You've joined a community of indie hackers shipping real products. </Text> <Button pX={20} pY={12} style={button} href="https://yourdomain.com/dashboard" > Start Building </Button> </Section> <Text style={footer}> Questions? Reply to this email. </Text> </Container> </Body> </Html> ); }

    const main = { backgroundColor: '#ffffff', fontFamily: '-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif', };

    const container = { border: '1px solid #eaeaea', borderRadius: '5px', margin: '40px auto', padding: '20px', width: '465px', };

    const box = { padding: '0 0 20px', };

    const hr = { borderColor: '#dddddd', marginTop: '20px', marginBottom: '20px', };

    const paragraph = { color: '#525f7f', fontSize: '16px', lineHeight: '1.5', textAlign: 'left' as const, };

    const heading = { fontSize: '24px', fontWeight: 'bold', margin: '16px 0', };

    const button = { backgroundColor: '#000', borderRadius: '4px', color: '#fff', fontSize: '16px', fontWeight: 'bold', textDecoration: 'none', textAlign: 'center' as const, display: 'block', };

    const footer = { color: '#999999', fontSize: '12px', lineHeight: '1.5', }; ```

    This gives you type safety, reusability, and templates that live in version control.

    Testing Emails Locally

    ```bash

    Start the React Email preview server

    npx react-email preview ```

    Visit localhost:3000 to see all templates rendered. This catches rendering bugs before production.

    Verification Checklist Before Shipping

  • [ ] Domain verified in Resend dashboard
  • [ ] API key stored in environment variables (never hardcoded)
  • [ ] Error handling wraps all resend.emails.send() calls
  • [ ] Emails tested in preview server
  • [ ] Rate limiting/queuing implemented if sending >100/day
  • [ ] Logging/monitoring connected to catch silent failures
  • [ ] DKIM/SPF records confirmed as healthy
  • What am I missing?

    Resend's feature set evolves constantly. Readers: did we miss critical error patterns you've hit? Better queue implementations? Advanced templating tricks? Drop corrections and additions in the commentsβ€”this guide improves with your input.

    See Also

  • [Official Resend Docs](https://resend.com/docs)
  • [React Email Components](https://react.email)
  • [Better error handling in async operations](/?guide=async-error-patterns)
  • [Building production email queues](/?guide=queue-patterns)
  • πŸ”₯ 0d
    LIVE
    ↓ PlanetScale rage spiking β€’βš  Vercel pricing complaints ‒↑ Railway gaining fast ‒↑ Supabase happiness rising ‒↑ Resend loved by devs ‒↓ PlanetScale rage spiking β€’βš  Vercel pricing complaints ‒↑ Railway gaining fast ‒↑ Supabase happiness rising
    DEVELOPER PAIN RADAR // Loading...

    Developers complain.
    Opportunities appear.

    We track what developers are struggling with today β€” and what opportunities that creates.

    β€”
    guides today
    β€”
    avg happiness
    πŸ”₯ Pain
    πŸ“– Guides
    πŸ”­ Explore
    πŸ‘€ Mine
    πŸ”₯ Pain Radar β€” rage scores today
    β†— share
    πŸ’‘ Opportunity Feed β€” pain = market gap
    πŸ“ˆ Tool Momentum
    all scores β†’
    πŸ“– Latest Guide
    all guides β†’
    πŸ“– All Guides
    πŸ“Š Tool Scores
    + Submit
    πŸ“° Hacker News
    βž• Submit a Tool
    ← back