React Email vs Resend vs Loops for SaaS Email 2026
SaaS Email Is Two Different Problems
SaaS email splits into two categories with different requirements:
-
Transactional email — triggered by user actions: welcome emails, password resets, receipts, notifications. These must be reliable, fast, and correctly delivered.
-
Marketing email — sequences, drip campaigns, newsletters: onboarding flows, feature announcements, re-engagement. These need segmentation, scheduling, and analytics.
Most SaaS boilerplates handle transactional email. Marketing sequences are usually added later.
TL;DR
- React Email: The template layer. Write email templates with React and TypeScript. Works with any sending provider.
- Resend: The sending provider for transactional email. Best DX, developer-focused, generous free tier. Works with React Email.
- Loops: Marketing email automation for SaaS. Replaces Mailchimp for developer-built product sequences.
These are not competitors — they work together: React Email templates + Resend for transactional, Loops for marketing.
Key Takeaways
- React Email has 18K+ GitHub stars — the standard for email templates in Next.js apps
- Resend free tier: 3,000 emails/month, 100/day — sufficient for early-stage SaaS
- Loops targets SaaS products specifically — onboarding sequences tied to user events
- Most boilerplates use Resend as the default sending provider (ShipFast, OpenSaaS, Makerkit)
- Nodemailer (SMTP) is still viable for self-hosted setups but Resend is better DX
- SendGrid and Postmark are established alternatives with more deliverability controls
React Email: Beautiful Templates with React
React Email provides React components for building HTML email templates:
npm install react-email @react-email/components
Creating Email Templates
// emails/welcome.tsx
import {
Html, Head, Body, Container, Heading, Text, Button, Hr, Preview
} from '@react-email/components';
interface WelcomeEmailProps {
userName: string;
dashboardUrl: string;
}
export function WelcomeEmail({ userName, dashboardUrl }: WelcomeEmailProps) {
return (
<Html>
<Head />
<Preview>Welcome to MySaaS, {userName}!</Preview>
<Body style={{ backgroundColor: '#f6f9fc', fontFamily: 'Arial, sans-serif' }}>
<Container style={{ maxWidth: '600px', margin: '0 auto', padding: '40px 20px' }}>
<Heading style={{ color: '#1a1a1a', fontSize: '28px' }}>
Welcome to MySaaS!
</Heading>
<Text style={{ color: '#444', fontSize: '16px', lineHeight: '24px' }}>
Hi {userName},
</Text>
<Text style={{ color: '#444', fontSize: '16px', lineHeight: '24px' }}>
Your account is ready. Start building with MySaaS today.
</Text>
<Button
href={dashboardUrl}
style={{
backgroundColor: '#3b82f6',
color: '#fff',
padding: '12px 24px',
borderRadius: '6px',
textDecoration: 'none',
display: 'inline-block',
}}
>
Go to Dashboard
</Button>
<Hr style={{ borderColor: '#e1e1e1', margin: '32px 0' }} />
<Text style={{ color: '#888', fontSize: '14px' }}>
You received this email because you signed up for MySaaS.
</Text>
</Container>
</Body>
</Html>
);
}
# Preview emails in browser during development:
npx react-email dev
# Opens localhost:3000 showing all emails in /emails folder
Resend: Transactional Email API
Resend is the sending provider built for developers, built by the React Email team:
npm install resend
// lib/email.ts
import { Resend } from 'resend';
import { render } from '@react-email/render';
const resend = new Resend(process.env.RESEND_API_KEY!);
export async function sendWelcomeEmail(to: string, userName: string) {
const html = await render(
<WelcomeEmail
userName={userName}
dashboardUrl={`${process.env.NEXT_PUBLIC_URL}/dashboard`}
/>
);
await resend.emails.send({
from: 'MySaaS <noreply@mysaas.com>', // Requires domain verification
to,
subject: `Welcome to MySaaS, ${userName}!`,
html,
});
}
export async function sendPasswordReset(to: string, resetUrl: string) {
const html = await render(
<PasswordResetEmail userName={to} resetUrl={resetUrl} />
);
await resend.emails.send({
from: 'MySaaS <noreply@mysaas.com>',
to,
subject: 'Reset your password',
html,
});
}
// Batch sending (for notifications):
export async function sendBulkNotifications(
recipients: Array<{ email: string; data: object }>
) {
await resend.batch.send(
recipients.map(({ email, data }) => ({
from: 'MySaaS <noreply@mysaas.com>',
to: email,
subject: 'New activity',
html: render(<NotificationEmail {...data} />),
}))
);
}
Domain Setup (Required for Production)
# In Resend dashboard: Add your domain
# Add DNS records:
# SPF: v=spf1 include:amazonses.com ~all
# DKIM: (provided by Resend)
# DMARC: v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com
Resend pricing: free up to 3,000 emails/month (100/day); $20/mo for 50,000/month.
Loops: Marketing Email for SaaS
Loops is purpose-built for SaaS onboarding sequences and triggered marketing emails:
npm install loops
// lib/loops.ts
import LoopsClient from 'loops';
const loops = new LoopsClient(process.env.LOOPS_API_KEY!);
// Create a contact when user signs up:
export async function createLoopsContact(user: {
id: string;
email: string;
name: string;
plan: string;
}) {
await loops.createContact(user.email, {
userId: user.id,
firstName: user.name.split(' ')[0],
plan: user.plan,
createdAt: new Date().toISOString(),
});
}
// Trigger an event (starts automations):
export async function trackLoopsEvent(
email: string,
eventName: string,
properties?: Record<string, string>
) {
await loops.sendEvent(email, eventName, undefined, properties);
}
// In auth callback, after user signs up:
await createLoopsContact({ id, email, name, plan: 'free' });
await trackLoopsEvent(email, 'signup');
// This triggers your "Onboarding Day 1" automation in Loops
// When user upgrades:
await loops.updateContact(email, { plan: 'pro' });
await trackLoopsEvent(email, 'upgraded', { plan: 'pro' });
// Triggers "Upgrade Success" sequence
Loops Sequences
In the Loops dashboard, you create visual sequences:
- Day 0: Welcome email (immediate)
- Day 1: "Getting started" tips
- Day 3: Feature spotlight
- Day 7: Case study / social proof
- Day 14: Check-in (if they haven't activated)
- Day 30: Review request (if they are active)
Loops pricing: free up to 2,500 contacts; $49/mo for 10,000.
Full Email Stack for SaaS
// The recommended full stack:
// 1. Transactional: React Email + Resend
// 2. Marketing: Loops
// lib/email/index.ts
export {
sendWelcomeEmail,
sendPasswordReset,
sendInvoiceEmail,
sendNotification,
} from './transactional'; // Uses Resend
export {
trackSignup,
trackUpgrade,
trackFeatureUsed,
updateContact,
} from './marketing'; // Uses Loops
// After user signs up (in auth callback):
await sendWelcomeEmail(user.email, user.name); // Resend: immediate welcome
await trackSignup(user.email, { plan: user.plan }); // Loops: start sequence
Alternative Sending Providers
| Provider | Free Tier | Best For |
|---|---|---|
| Resend | 3K/mo | Developer-focused, React Email native |
| Postmark | 100/mo | Deliverability-critical transactional |
| SendGrid | 100/day | Volume, legacy apps |
| Mailgun | 5K/mo (trial) | High volume, EU region |
| AWS SES | 62K/mo (from EC2) | Maximum scale, AWS apps |
| Nodemailer | N/A | Self-hosted SMTP relay |
Which Boilerplates Use What?
| Boilerplate | Email Provider |
|---|---|
| ShipFast | Resend or Mailgun |
| OpenSaaS | Resend |
| Makerkit | Resend |
| SaaSBold | Resend or Nodemailer |
| T3 Stack | None (add manually) |
React Email templates are used across most modern boilerplates.
Methodology
Based on publicly available documentation from React Email, Resend, and Loops, pricing pages, and boilerplate analysis as of March 2026.
Setting up email for your SaaS? StarterPick helps you find boilerplates pre-configured with Resend, React Email, and transactional email infrastructure.