RITWIK LODHIYA
Published on

Migrating from Brevo to Resend in a Next.js App

Authors
  • avatar
    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