Olá. Resolvi criar e compartilhar uma biblioteca de envio de e-mails.
Por que ela foi criada?
Recentemente, ao trabalhar em vários projetos, acabei usando diferentes runtimes como Node.js, Deno e Bun, e era incômodo ter que procurar uma biblioteca diferente ou refazer a configuração toda vez na parte de envio de e-mails. Especialmente no Deno e no Bun, muitas bibliotecas de e-mail feitas para Node.js frequentemente não funcionavam direito.
Por isso, pensei que seria ótimo ter uma biblioteca de e-mail que “você escreve uma vez e funciona em qualquer lugar”, e assim nasceu o Upyo.
Principais características
Compatibilidade cross-runtime
Funciona com o mesmo código em Node.js, Deno, Bun e edge functions. Não é necessário fazer configurações diferentes nem alterar o código para cada runtime.
Zero dependências
Pessoalmente, não gosto muito de bibliotecas que trazem várias dependências junto, então fiz o projeto com zero dependências. Por exemplo, até o transporte SMTP foi desenvolvido diretamente, sem usar o pacote smtp.
API simples
Foi projetada para permitir o envio de e-mails em poucas linhas, sem configurações complexas:
import { createMessage } from "@upyo/core";
import { MailgunTransport } from "@upyo/mailgun";
const message = createMessage({
from: "sender@example.com",
to: "recipient@example.com",
subject: "Hello from Upyo!",
content: { text: "gan danhan imeiripnida." },
});
const transport = new MailgunTransport({
apiKey: process.env.MAILGUN_KEY,
domain: process.env.MAILGUN_DOMAIN,
});
const receipt = await transport.send(message);
Independência de provedor
Oferece suporte a vários serviços de e-mail, como SMTP, Mailgun e SendGrid, e mesmo que você troque de provedor, o código da aplicação permanece o mesmo. Basta trocar o Transport. (Na próxima versão também haverá suporte ao Amazon SES.)
Amigável para testes
Fornece um MockTransport que permite testar a lógica de e-mail sem enviar mensagens reais. Assim, você pode testar sem se preocupar em disparar e-mails de verdade por engano durante o desenvolvimento.
Pontos que ainda faltam
- O suporte a STARTTLS no transporte SMTP ainda não foi implementado
- SMTP ainda não é compatível com edge functions (somente transportes baseados em HTTP API são possíveis)
- Como ainda está em estágio inicial de desenvolvimento, a API pode mudar
Como experimentar
Pode ser usado em vários runtimes:
npm add @upyo/core @upyo/smtp
pnpm add @upyo/core @upyo/smtp
yarn add @upyo/core @upyo/smtp
deno add --jsr @upyo/core @upyo/smtp
bun add @upyo/core @upyo/smtp
Além de @upyo/smtp, os pacotes de transporte incluem @upyo/mailgun, @upyo/sendgrid, @upyo/ses e @upyo/mock, e outros devem ser adicionados no futuro.
Documentação: https://upyo.org
Código: https://github.com/dahlia/upyo
Encerrando
Embora tenha começado como um projeto para uma necessidade pessoal, achei que poderia ser útil compartilhar com quem talvez esteja passando por preocupações parecidas. Ainda está na versão 0.1.0, mas pretendo continuar melhorando o projeto de forma constante.
Feedback e contribuições são sempre bem-vindos!
Upyo é um nome inspirado na palavra coreana “upyo”, que significa selo postal. A ideia é enviar e-mails como se estivesse enviando cartas com selo.
6 comentários
É um projeto com o qual consigo me identificar, porque já passei pela experiência de mudar a API 2 ou 3 vezes. Parece que o site e a documentação também foram feitos de forma bem limpa e caprichada. Quando se opera um serviço, às vezes um provedor de e-mail específico sai do ar e é preciso montar outro serviço de e-mail como failover; acho que seria legal ter também um código que opere os transports com um conceito de pool. Seria ótimo se também houvesse suporte ao resend.com. Se ainda não estiver disponível quando eu for aplicar depois, vou tentar contribuir eu mesmo~!
Obrigado pelo feedback! Vou tentar adicionar
PoolTransporteResendTransportem breve!Que tal trocar o “郵票” do símbolo por “selo”?
Mesmo agora já está realmente perfeito e bonito, então fico até um pouco cauteloso em sugerir isso..
Oh~ legal~ muito bom
É um projeto de uma pessoa só?? Impressionante..
Sim, por enquanto fui eu que fiz tudo sozinho. 😅