Resend: Transactional Email Done Right in 2026

Production-ready guide to Resend's email API. Real patterns, common errors, and why indie hackers prefer it over alternatives.

TL;DR

Resend is a developer-first transactional email service built for modern apps. It handles SMTP complexity, provides React email templates, and scales reliably. Current version offers free tier with 100 emails/day. Setup takes 15 minutes; common errors involve domain verification and API key scope.

---

Why Transactional Email Matters

Every indie product needs reliable email: password resets, order confirmations, notifications. Most developers default to AWS SES (complex) or SendGrid (expensive). Resend fills the gap for teams wanting simplicity without compromise.

Transactional email differs from marketing email. You're not sending campaigns—you're sending critical, user-triggered messages. Deliverability, authentication, and speed matter intensely.

---

What Resend Gets Right

1. Developer Experience

Resend's API is genuinely minimal. No SMTP configuration. No XML parsing. Just JavaScript.

```javascript import { Resend } from 'resend';

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

await resend.emails.send({ from: 'onboarding@example.com', to: 'user@gmail.com', subject: 'Welcome to our app', html: '<p>Your account is ready.</p>', }); ```

That's it. No class instantiation boilerplate. No callback hell. Async/await native.

2. React Email Templates

Resend maintains [React Email](https://react.email), an open-source library for building emails as React components. Version 0.0.x (verify in official docs for latest):

```javascript import { Button, Container, Text } from 'react-email'; import * as React from 'react';

const WelcomeEmail = ({ userName, resetLink }) => ( <Container> <Text>Hi {userName},</Text> <Text>Click below to reset your password:</Text> <Button href={resetLink}>Reset Password</Button> </Container> );

export default WelcomeEmail; ```

Then render and send:

```javascript import { render } from 'react-email'; import WelcomeEmail from './emails/welcome';

const html = render( <WelcomeEmail userName="Alice" resetLink="https://app.com/reset?token=xyz" /> );

await resend.emails.send({ from: 'noreply@example.com', to: 'alice@gmail.com', subject: 'Reset your password', react: <WelcomeEmail userName="Alice" resetLink={...} />, }); ```

No HTML hand-coding. Type-safe. Testable.

3. Built-in Authentication

Resend handles DKIM, SPF, and DMARC setup automatically. Domain verification is one-click in the dashboard (takes 5-10 minutes for DNS propagation).

4. Production Features

  • Reply-to tracking: Catch when users reply to transactional emails
  • Scheduled sends: Queue emails for later
  • Batch API: Send up to 500 emails per request
  • Webhooks: Bounces, complaints, deliveries in real-time
  • ---

    Common Errors You'll Hit

    Error 1: Missing Domain Verification

    ``` ResendError: Invalid from address. Please add and verify the domain first. ```

    Fix: Go to Resend dashboard → Domains → Add your domain. Add CNAME records DNS. Wait for propagation (not instant).

    Error 2: API Key Scope Issues

    ``` UnauthorizedError: API key does not have permission to perform this action. ```

    Fix: Regenerate your API key in the dashboard. Old keys sometimes persist in .env.local. Verify RESEND_API_KEY is loaded correctly:

    ```javascript if (!process.env.RESEND_API_KEY) { throw new Error('Missing RESEND_API_KEY environment variable'); } ```

    Error 3: Invalid JSX in React Email

    ``` TypeError: Invalid use of JSX outside render function at <WelcomeEmail /> ```

    Fix: Ensure you're using react prop, not html prop:

    ```javascript // ✗ Wrong await resend.emails.send({ from: 'test@example.com', to: 'user@gmail.com', html: <WelcomeEmail />, // JSX not valid here });

    // ✓ Correct await resend.emails.send({ from: 'test@example.com', to: 'user@gmail.com', react: <WelcomeEmail />, // Proper prop }); ```

    ---

    Production Pattern: Email Queue

    Don't send email synchronously in request handlers. Queue it.

    ```javascript // app/api/signup.ts (Next.js example) import { Resend } from 'resend'; import { db } from '@/lib/db'; import { queue } from '@/lib/queue'; // Bull, RQ, or custom

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

    export async function POST(req) { const { email, name } = await req.json();

    // 1. Create user in DB const user = await db.users.create({ email, name });

    // 2. Queue email (returns immediately) await queue.add('send-welcome-email', { userId: user.id, email: user.email, name: user.name, });

    // 3. Return success to client return Response.json({ success: true }); }

    // workers/send-welcome-email.ts queue.process('send-welcome-email', async (job) => { const { userId, email, name } = job.data;

    try { await resend.emails.send({ from: 'welcome@example.com', to: email, subject: 'Welcome!', react: <WelcomeEmail name={name} />, });

    // Log success await db.emailLogs.create({ userId, type: 'welcome', status: 'sent', }); } catch (error) { console.error('Email send failed:', error); throw error; // Bull will retry } }); ```

    Benefit: User gets instant response. Email sends asynchronously. Failures retry automatically.

    ---

    Cost & Limits

    Free tier (verify in official docs for current numbers):

  • 100 emails/day
  • No credit card required
  • Full API access
  • Paid: Starts ~$20/month for higher volume. Per-email pricing drops with scale.

    For indie products with <10k monthly active users, the free tier is generous.

    ---

    Comparison: Why Resend Over Alternatives

    | Service | Setup Time | API Simplicity | React Templates | Pricing | |---------|-----------|----------------|-----------------|----------| | Resend | 15 min | ⭐⭐⭐⭐⭐ | Yes | $0-20/mo | | SendGrid | 30 min | ⭐⭐⭐ | No | $20+/mo | | AWS SES | 60 min | ⭐⭐ | No | Pay-per-email | | Mailgun | 30 min | ⭐⭐⭐ | No | $35+/mo |

    Resend wins on developer experience. Other services are stronger for high-volume campaigns (>100k/mo).

    ---

    Next Steps

    1. Create account: [resend.com](https://resend.com) 2. Add domain: Complete DNS verification 3. Install SDK: npm install resend (verify latest version in official docs) 4. Test send: Use the code above 5. Monitor deliverability: Check webhooks and bounce rates

    See also: [authentication best practices](/?guide=api-security) and [scaling database queries](/?guide=database-optimization) for related patterns.

    ---

    What am I missing?

    Have you used Resend in production? Spotted issues with the domain setup flow? Built custom middleware around it? Comments below—especially if you've hit errors not covered here or found better patterns for batching sends.

    ---

    References

  • [Resend Official Docs](https://resend.com/docs)
  • [React Email Library](https://react.email)
  • [Resend GitHub](https://github.com/resendlabs/resend)
  • 🔥 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