What it does
Resendis an email API for developers. It handles sending emails from your app — you call one function and the email goes out. No SMTP configuration, no mail server management, no deliverability tuning. You focus on what the email says and Resend handles getting it into inboxes.
There are two categories of email your app will send. Transactional emailsare triggered by user actions — welcome emails on signup, purchase receipts after checkout, password reset links, delivery instructions for digital products. These are one-to-one and time-sensitive. Marketing emailsare one-to-many — newsletters, product announcements, campaigns. Resend handles both.
Under the hood, Resend manages deliverability — the hard problem of getting your emails into inboxes instead of spam folders. It handles SPF and DKIM authentication automatically, provides analytics for opens, clicks, and bounces, and integrates natively with React through React Email so you can build templates as components instead of raw HTML strings.
Why we use it
The alternatives are painful. SendGridis complex and enterprise-focused — the dashboard alone has dozens of tabs you'll never touch. Mailgunis API-first but the developer experience feels dated, with verbose configuration and clunky SDKs. Resend is modern, built for developers who use React, and has the cleanest API in the space. One function call. That's it.
The free tier gives you 3,000 emails/month— enough to build your product, launch, and start generating revenue before you pay a cent. React Email lets you build templates with components you already know — no learning a new templating language. Deliverability works out of the box once you verify your domain. You won't outgrow the free tier until you have serious volume, and by then the upgrade is trivial.
Setup checklist
Create a Resend account
Go to resend.com and sign up. The free tier gives you 3,000 emails/month, 100 emails/day, 1 custom domain, and 1 API key. That's enough for all of development, your launch, and early traction — most apps don't send 100 emails a day until they have real paying customers. You can upgrade later when volume grows, but don't pay before you need to.
Verify your domain
Go to Domains > Add Domain in the Resend dashboard. Resend gives you 3 DNS records to add at your domain registrar: an SPF record, a DKIM record, and a verification TXTrecord. These prove to email providers that you're authorized to send from your domain.
Add all three records exactly as shown. Verification takes anywhere from 5 minutes to an hour depending on your registrar's DNS propagation speed. Without a verified domain, your emails will land in spam or get rejected entirely. This step is non-negotiable.
Get your API key
Go to API Keys > Create API Key. Give it a descriptive name (e.g., "production" or "development"). Copy the key immediately — you won't see it again after leaving the page. Add it to your .env.local file as RESEND_API_KEY. This key is server-side only — never expose it in client code or NEXT_PUBLIC_ variables.
Install the SDK
Run npm install resend in your project. Then create a Resend client file at lib/resend.ts. Import Resend from the package, initialize it with your API key from environment variables, and export the client. This gives you a typed client that handles authentication and request formatting for every email you send.
Build your first email template
You have two approaches for templates, and they're not mutually exclusive. HTML stringsare the simplest path — you write the HTML directly in a template literal, interpolate variables with `${name}`, and pass it to resend.emails.send(). This is fine for most projects, especially when starting out. No extra dependencies, no build step, just a function that returns HTML.
React Email is the more powerful approach. Install @react-email/components and build templates as React components using pre-built primitives like <Html>, <Section>, <Text>, and <Button>. These components handle the cross-client compatibility nightmares for you — they output the table-based HTML that email clients actually render correctly. Use render() to convert the component to an HTML string when sending. The advantage: your templates are type-safe, composable, and version-controlled alongside your app code.
For either approach, build templates that match your brand — dark backgrounds, your colors, your logo. Keep the layout simple. Email clients are not browsers — stick to tables for layout, inline styles, and basic HTML. Avoid CSS grid, flexbox, or anything fancy. Test how it renders before sending to customers.
Send your first email
Create a function that calls resend.emails.send() with four fields: from (must match your verified domain), to (the recipient), subject, and html(your template). Test it by sending to yourself. Check that it arrives, looks correct, and doesn't land in spam.
Set up transactional emails
Map out every email your app needs to send. Common ones: welcome email on signup, purchase confirmation after checkout, delivery instructions for digital products, password reset links. Each one is a function that builds the HTML with the relevant data (customer name, order details, reset link) and calls resend.emails.send().
Keep your email functions in a single file like lib/emails.ts so every email trigger in your app calls the same module. This makes it easy to update templates, change the from address, or add logging in one place.
Configure the "from" address
Use a professional format: "YourName <hello@yourdomain.com>" or "YourBrand <noreply@yourdomain.com>". The from address must match your verified domain exactly. If your verified domain is yourdomain.com, you can send from any address at that domain (hello@, support@, noreply@) without additional setup.
Handle errors and rate limits
Wrap every resend.emails.send()call in a try/catch. Emails can fail for many reasons — invalid addresses, rate limits, API outages. Log every failure. You need to know when emails don't send, because your customers won't tell you they didn't get a confirmation.
The free tier allows 10 emails per second. If you're doing bulk sends (like a newsletter), add delays between batches or use Resend's batch APIwhich handles throttling for you. For transactional emails (one at a time in response to user actions), you'll rarely hit rate limits.
Set up delivery tracking
Resend tracks opens and clicks automatically. View them in the dashboard under Emails. For programmatic tracking, set up webhooks at Resend > Webhooks to get notified of bounces and complaints.
Bounces and complaints directly affect your deliverability. If you keep sending to addresses that bounce, email providers will start flagging all your emails as spam. Use webhook events to automatically suppress bad addresses from future sends.
Pro tips
Use React Email for complex templates — install @react-email/components, build templates as React components, and render to HTML with render().
Preview templates locally — run npx react-email dev to see templates in the browser with hot reload as you edit.
Use the batch API for bulk sends — resend.batch.send([...]) sends up to 100 emails in one call, handling throttling for you.
Monitor your domain reputation— high bounce rates damage deliverability for all your emails, not just the ones that bounced. Check the Resend dashboard regularly.
Send email code
// lib/resend.ts import { Resend } from "resend"; const resend = new Resend(process.env.RESEND_API_KEY); export async function sendWelcomeEmail(to: string, name: string) { try { const { data, error } = await resend.emails.send({ from: "YourBrand <hello@yourdomain.com>", to, subject: `Welcome, ${name}!`, html: `<h1>Welcome aboard</h1><p>You're in. Here's what to do next...</p>`, }); if (error) { console.error("Failed to send welcome email:", error); return { success: false, error }; } return { success: true, id: data?.id }; } catch (err) { console.error("Resend API error:", err); return { success: false, error: err }; } }
AI prompt to get started
I need to set up transactional emails with Resend for my Next.js app. Help me create: 1) A Resend client module, 2) HTML email templates for welcome, purchase confirmation, and password reset that match a dark theme with brand color #E8613C, 3) An API route that sends emails, 4) Error handling with retry logic.
Mistakes to avoid
- ✕Not verifying your domain — emails from unverified domains land in spam or get rejected entirely
- ✕Sending from a free email address (gmail, outlook) — always use your custom verified domain
- ✕Not handling send failures — wrap in try/catch, log errors, have a fallback. Silent failures mean customers never get their emails
- ✕Building complex email templates without testing — email clients render HTML differently than browsers. Test in Gmail, Outlook, and Apple Mail
- ✕Not setting up SPF/DKIM/DMARC — Resend handles SPF and DKIM, but add a DMARC record manually for maximum deliverability
- ✕Sending too many emails too fast — respect rate limits, use the batch API for bulk sends