Resend to platforma do wysyłania transakcyjnych emaili przez API, stworzona przez byłego inżyniera Vercel. Brzmi jak kolejny SendGrid? Nie do końca. Po migracji dwóch projektów Next.js z Nodemailer + SMTP na Resend, mogę powiedzieć jedno: to jest narzędzie, które zostało zaprojektowane tak, jak developer chciałby, żeby działał email — i które wreszcie sprawia, że wysyłanie maili z aplikacji webowej nie jest frustrującym doświadczeniem.
Problem z emailem w web developmencie jest taki, że email to technologia z lat 70. Protokół SMTP, kodowanie MIME, renderowanie HTML w klientach pocztowych — to wszystko jest archaiczne, kruche i pełne pułapek. Większość developerów podchodzi do tematu emaili jak do konieczności zła: „muszę wysłać potwierdzenie zamówienia, więc podepnę SMTP i jakoś to będzie".
A potem „jakoś" oznacza maile lądujące w spamie, formularze kontaktowe które cisną się, bo serwer SMTP nie odpowiada, i zero informacji o tym, czy mail dotarł do odbiorcy. Z moich projektów wynika, że email jest jednym z najczęściej zaniedbywanych elementów infrastruktury aplikacji webowych — a jednocześnie jednym z najbardziej krytycznych z perspektywy użytkownika.
Czym jest Resend i dlaczego powstał
Resend stworzył Zeno Rocha — programista, który wcześniej pracował nad DevEx w Vercel. I to widać w każdym aspekcie narzędzia: czyste API, minimalna konfiguracja, natywna integracja z React.
Resend to usługa API-first do wysyłania emaili transakcyjnych i marketingowych. W przeciwieństwie do starszych platform (SendGrid, Mailgun, Amazon SES), Resend został zbudowany od zera z myślą o nowoczesnym stacku JavaScript/TypeScript:
- SDK dla Node.js/TypeScript — typowany, intuicyjny, bez boilerplate'u
- React Email — companion library pozwalająca budować szablony emaili jako komponenty React (JSX, nie archaiczny HTML z tabelami)
- Webhooks — informacje o dostarczeniu, otwarciu, kliknięciu i odrzuceniu w czasie rzeczywistym
- Wbudowana obsługa domen — konfiguracja DKIM, SPF i DMARC z poziomu dashboardu
Kluczowa filozofia Resend: email powinien być tak prosty do wysłania jak fetch request. I faktycznie — w najprostszej formie wysłanie maila z Next.js wygląda tak:
import { Resend } from 'resend'
const resend = new Resend(process.env.RESEND_API_KEY)
await resend.emails.send({
from: 'Max Digital <kontakt@maxdigital.pl>',
to: 'klient@example.com',
subject: 'Potwierdzenie zapytania',
html: '<p>Dziękuję za kontakt!</p>'
})
Cztery linie kodu. Brak konfiguracji SMTP. Brak problemów z połączeniem. Brak timeoutów.
Nodemailer + SMTP vs. Resend — co się zmienia
Żeby zrozumieć, dlaczego Resend to krok naprzód, trzeba zobaczyć, jak wygląda tradycyjne podejście do emaili w Next.js.
Typowy setup z Nodemailer:
import nodemailer from 'nodemailer'
const transporter = nodemailer.createTransport({
host: 'smtp.hosting.pl',
port: 587,
secure: false,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
})
await transporter.sendMail({
from: '"Max Digital" <kontakt@maxdigital.pl>',
to: 'klient@example.com',
subject: 'Potwierdzenie zapytania',
html: '<p>Dziękuję za kontakt!</p>',
})
Wygląda podobnie? Na papierze tak. W praktyce — różnica jest fundamentalna.
| Aspekt | Nodemailer + SMTP | Resend |
|---|---|---|
| Połączenie | TCP socket do serwera SMTP — timeout, reconnect, TLS handshake | HTTPS POST — standardowy fetch, działa wszędzie |
| Serverless | Problematyczne — SMTP utrzymuje połączenie, serverless je zamyka | Natywne — bezstanowe HTTP request |
| Deliverability | Zależy od reputacji IP serwera SMTP (hosting współdzielony = ryzyko) | Resend zarządza pulami IP z wysoką reputacją |
| Monitoring | Brak — nie wiesz, czy mail dotarł | Dashboard z delivery rate, opens, clicks, bounces |
| Szablony | Surowy HTML string lub silnik szablonów (Handlebars itp.) | React Email — komponenty JSX z podglądem na żywo |
| Cena | SMTP „za darmo" (wliczony w hosting) — ale bez gwarancji deliverability | Darmowe do 100 maili/dzień, potem od $20/mies. |
Największy problem Nodemailera w kontekście Next.js na Vercel: SMTP i serverless to fatalna para. Vercel functions mają krótki czas życia (10–60 sekund), a SMTP wymaga ustanowienia połączenia TCP, handshake TLS i utrzymania sesji. W najgorszym scenariuszu (SMTP serwer nie odpowiada) — Twój formularz kontaktowy wisi 30 sekund i zwraca timeout. Użytkownik widzi błąd i wychodzi.
Resend eliminuje ten problem całkowicie — to zwykły HTTP POST, który zachowuje się identycznie jak każdy inny API call w Twojej aplikacji.
React Email — szablony emaili jako komponenty React
To jest funkcja, która przekonała mnie do Resend bardziej niż cokolwiek innego.
Budowanie szablonów emaili to jedno z najbardziej frustrujących doświadczeń w web developmencie. Klienty pocztowe (Outlook, Gmail, Apple Mail) renderują HTML kompletnie inaczej niż przeglądarki. Nie ma Flexbox. Nie ma Grid. Nie ma nowoczesnego CSS. Jedyne, co działa wszędzie, to zagnieżdżone tabele — jak w 2003 roku.
React Email rozwiązuje ten problem, oferując gotowe komponenty React, które pod spodem generują kompatybilny HTML:
import { Html, Head, Body, Container, Text, Button } from '@react-email/components'
export function WelcomeEmail({ name }: { name: string }) {
return (
<Html>
<Head />
<Body style={{ background: '#f4f4f4', fontFamily: 'sans-serif' }}>
<Container style={{ maxWidth: 560, margin: '0 auto', padding: 20 }}>
<Text style={{ fontSize: 20, fontWeight: 'bold' }}>
Cześć {name}!
</Text>
<Text>Dziękuję za kontakt z Max Digital.</Text>
<Button
href="https://maxdigital.pl"
style={{ background: '#ff014f', color: 'white', padding: '12px 24px', borderRadius: 6 }}
>
Zobacz naszą ofertę
</Button>
</Container>
</Body>
</Html>
)
}
Piszesz JSX, a React Email kompiluje to do HTML z tabelami, który renderuje się poprawnie w Outlook 2016 i w Apple Mail na iPhone jednocześnie. Masz type safety, reużywalne komponenty, i podgląd w przeglądarce podczas tworzenia — identycznie jak przy budowaniu UI w React.
W mojej praktyce React Email skrócił czas tworzenia szablonów emaili z kilku godzin do 20–30 minut. Zamiast kopiować HTML z jakiegoś email buildera, debugować go w Litmusie i modlić się, żeby Outlook go nie rozjechał — piszę komponent i wiem, że zadziała.
Wdrożenie Resend w Next.js — praktyczny setup
Poniżej pełny setup, którego używam w projektach klientów. API route w Next.js App Router obsługująca formularz kontaktowy:
// app/api/contact/route.ts
import { Resend } from 'resend'
import { NextResponse } from 'next/server'
import { ContactEmail } from '@/emails/contact'
const resend = new Resend(process.env.RESEND_API_KEY)
export async function POST(req: Request) {
const { name, email, message } = await req.json()
const { data, error } = await resend.emails.send({
from: 'Formularz kontaktowy <kontakt@maxdigital.pl>',
to: 'samotnekobietki@gmail.com',
replyTo: email,
subject: `Nowe zapytanie od ${name}`,
react: ContactEmail({ name, email, message }),
})
if (error) {
return NextResponse.json({ error: error.message }, { status: 500 })
}
return NextResponse.json({ id: data?.id })
}
Zwróć uwagę na kilka szczegółów:


