A biblioteca padrão do Node.js não inclui um cliente SMTP nativo. O Nodemailer preenche essa lacuna: ele gerencia a negociação TLS, o pool de conexões, a codificação MIME e os anexos dos e-mails enviados.
Como instalar e configurar o Nodemailer?
Instale pelo npm:
npm install nodemailer
Um transporte armazena os dados de conexão SMTP. Você aponta para um host e uma porta e passa as credenciais em auth:
import nodemailer from "nodemailer";
const transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 587,
secure: false, // true for port 465, false for 587 (STARTTLS)
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
A porta 587 com secure: false usa STARTTLS, que atualiza a conexão para TLS após o handshake. A porta 465 exige secure: true. Mantenha o nome de usuário e a senha em variáveis de ambiente, nunca no código-fonte.
Como enviar uma mensagem?
Chame sendMail com o envelope e o conteúdo. Ele retorna uma promise, então envolva em async/await com um try/catch para que um envio com falha não derrube o processo:
async function main() {
try {
const info = await transporter.sendMail({
from: '"Your App" <you@yourdomain.com>',
to: "recipient@example.org",
subject: "Your receipt",
text: "Thanks for your order. This is the plain-text version.",
html: "<p>Thanks for your order.</p>",
});
console.log("Sent:", info.messageId);
} catch (err) {
console.error("Send failed:", err);
}
}
main();
Sempre envie text e html juntos. Alguns clientes renderizam a parte de texto simples, e uma mensagem sem alternativa em texto tende a pontuar pior nos filtros de spam.
Como adicionar anexos?
Passe um array attachments. Cada entrada pode ler de um caminho, um buffer ou um stream:
await transporter.sendMail({
from: "you@yourdomain.com",
to: "recipient@example.org",
subject: "Your invoice",
text: "Invoice attached.",
attachments: [
{
filename: "invoice.pdf",
path: "./invoices/invoice-1042.pdf",
},
{
filename: "note.txt",
content: "Generated at runtime, no file needed.",
},
],
});
Como testar sem enviar e-mail de verdade?
O Nodemailer vem com o Ethereal, um serviço SMTP falso que captura mensagens em vez de entregá-las. Você recebe uma URL de pré-visualização para cada envio, o que é ideal para desenvolvimento local:
const testAccount = await nodemailer.createTestAccount();
const transporter = nodemailer.createTransport({
host: "smtp.ethereal.email",
port: 587,
secure: false,
auth: {
user: testAccount.user,
pass: testAccount.pass,
},
});
const info = await transporter.sendMail({
from: "you@yourdomain.com",
to: "test@example.org",
subject: "Preview only",
text: "This never leaves Ethereal.",
});
console.log("Preview:", nodemailer.getTestMessageUrl(info));
O Ethereal serve para inspecionar o que você construiu. Ele não diz nada sobre se uma caixa de entrada real aceitaria a mensagem.
Envie com Bird
SMTP funciona, mas usá-lo em produção significa operar um servidor de e-mail (ou alugar um), aquecer IPs e monitorar reputação por conta própria. Uma HTTP API resolve isso para você. Não há socket SMTP para manter aberto, e o provedor gerencia a infraestrutura de entregabilidade. Com a Bird de e-mail API, o mesmo envio é uma única chamada:
import { BirdClient } from "@messagebird/sdk";
const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });
const { data, error } = await bird.email
.send({
from: "onboarding@messagebird.dev",
to: ["delivered@messagebird.dev"],
subject: "Hello from Node",
html: "<p>It works.</p>",
})
.safe();
O remetente onboarding@messagebird.dev e o endereço sandbox delivered@messagebird.dev confirmam a integração antes de você apontar para um destinatário real. Runtimes serverless, como as funções da Vercel e outros ambientes de servidor JavaScript, usam esse caminho via HTTPS quando não conseguem manter conexões SMTP abertas.
Perguntas frequentes
O Nodemailer funciona no navegador?
Não. O Nodemailer é uma biblioteca do lado do servidor e depende dos módulos de rede do Node. Navegadores não podem abrir conexões SMTP, e colocar credenciais no código do cliente as exporia. Envie a partir de um backend.
Por que enviar texto e HTML juntos?
Uma mensagem multipart permite que cada cliente escolha a parte que consegue renderizar, e a alternativa em texto simples melhora a leitura dos filtros de spam. Omitir text é um motivo comum para e-mails caírem no spam.
Devo usar SMTP ou uma HTTP API?
SMTP funciona bem para baixo volume e ferramentas internas. Para envio em produção em escala, uma HTTP API elimina o servidor que você teria que operar e inclui o tratamento de entregabilidade. Muitas equipes usam Nodemailer em desenvolvimento e uma API em produção.
Nodemailer é uma escolha sólida para falar SMTP a partir do Node. Quando você preferir não operar o servidor de e-mail por trás dele, leia o guia de envio de e-mail para ver a alternativa API de ponta a ponta.