- Published on
Migrating from Brevo to Resend in a Next.js App
- Authors
- Name
- Ritwik Lodhiya
I originally used Brevo (formerly Sendinblue) to handle contact form submissions on my site, and it worked fine locally, but I kept running into issues with it when deployed to Vercel. Resend offers a much simpler developer experience — built for frameworks like Next.js and Vercel.
Here’s how I made the switch.
📦 Installing Resend
npm install resend
🛠️ Brevo: What I Had Before
import { TransactionalEmailsApi, SendSmtpEmail } from '@getbrevo/brevo'
const api = new TransactionalEmailsApi()
api.setApiKey('apiKey', process.env.BREVO_API_KEY!)
await api.sendTransacEmail(new SendSmtpEmail({
to: [{ email: 'hello@rlodhiya.dev' }],
sender: { email: 'system@rlodhiya.dev', name: 'RL-System' },
subject: 'Contact Form',
htmlContent: '<p>Message</p>',
}))
🔁 Replaced with Resend
import { Resend } from 'resend'
const resend = new Resend(process.env.RESEND_API_KEY)
await resend.emails.send({
from: 'RL-System <system@rlodhiya.dev>',
to: ['hello@rlodhiya.dev'],
subject: 'Contact Form',
html: '<p>Message</p>',
})
📬 Reusable HTML Builder
// message-builder.ts
export function buildGetInTouchHtml({ fullName, message }: GetInTouchArgs) {
return `<div><p><strong>${fullName}</strong>: ${message}</p></div>`
}
Both Brevo and Resend now use this for consistency.
🧠 Generic EmailService Wrapper
I created a service that reads from EMAIL_PROVIDER
in .env
and routes the request to the correct implementation. This allows for an easy fallback, or potential future experimentation with Brevo.
const service = new EmailService()
await service.sendGetInTouchMessage(args)
✅ Why I Switched
Resend feels tailor-made for modern React and serverless projects. Type-safe, clean, and no extra ceremony. It also plays nicely with my Vercel deployment.
It's looking good so far! Try it out: Contact Me