31 puntos por hongminhee 2025-07-14 | 6 comentarios | Compartir por WhatsApp

Hola. Quería compartir una biblioteca de envío de correo electrónico que hice personalmente.

¿Por qué la hice?

Últimamente, al trabajar en varios proyectos, terminé usando distintos runtimes como Node.js, Deno y Bun, y me resultaba incómodo tener que buscar una biblioteca diferente o volver a configurar todo cada vez para la parte de envío de correos. En especial, en Deno o Bun muchas bibliotecas de correo para Node.js no funcionaban correctamente.

Por eso pensé que sería bueno tener una biblioteca de correo que, “si la escribes una vez, funcione en cualquier lugar”, y así fue como terminé creando Upyo.

Características principales

Compatibilidad cross-runtime

Funciona con el mismo código en Node.js, Deno, Bun y edge functions. No hace falta una configuración distinta ni cambios de código según el runtime.

Cero dependencias

Como personalmente prefiero evitar que se arrastren muchas dependencias, la hice con cero dependencias. Por ejemplo, incluso el transporte SMTP fue desarrollado directamente, sin usar el paquete smtp.

API simple

Está diseñada para que puedas enviar correos con unas pocas líneas, sin configuraciones complejas:

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 imeir-imnida." },  
});  
  
const transport = new MailgunTransport({  
  apiKey: process.env.MAILGUN_KEY,  
  domain: process.env.MAILGUN_DOMAIN,  
});  
  
const receipt = await transport.send(message);  

Independencia del proveedor

Soporta varios servicios de correo como SMTP, Mailgun y SendGrid, y aunque cambies de proveedor, el código de la aplicación se mantiene igual. Solo necesitas cambiar el Transport. (La próxima versión también incluirá soporte para Amazon SES).

Amigable para pruebas

Ofrece MockTransport, con el que puedes probar la lógica de correo sin enviar emails reales. Así puedes hacer pruebas durante el desarrollo sin preocuparte por mandar correos por error.

Cosas que todavía faltan

  • El soporte para STARTTLS en el transporte SMTP todavía no está implementado
  • SMTP todavía no está soportado en edge functions (solo se pueden usar transportes basados en HTTP API)
  • Aún está en una etapa temprana de desarrollo, por lo que la API puede cambiar

Cómo probarlo

Se puede usar en distintos 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  

Además de @upyo/smtp, los paquetes de transporte disponibles son @upyo/mailgun, @upyo/sendgrid, @upyo/ses y @upyo/mock, y se planea agregar más en el futuro.

Documentación: https://upyo.org
Código: https://github.com/dahlia/upyo

Cierre

Aunque es un proyecto que empezó por una necesidad personal, quise compartirlo porque creo que podría ayudar a quienes estén enfrentando una situación parecida. Aún está en la versión 0.1.0, pero planeo seguir mejorándolo de forma constante.

¡Toda retroalimentación o contribución es bienvenida en cualquier momento!


Upyo es un nombre tomado de la palabra coreana “upyo”, que significa sello postal. La idea es la de enviar emails como si se enviaran cartas con un sello.

6 comentarios

 
davidshim 2025-08-13

Es un proyecto con el que me identifico porque ya he pasado por la experiencia de cambiar la API dos o tres veces. También parece que hicieron un muy buen trabajo dejando el sitio y la documentación limpios y bien armados. Cuando operas un servicio, a veces un proveedor de correo se cae y necesitas implementar otro como failover; estaría bueno que también hubiera código para manejar los transport con un concepto de pool. También estaría bueno que diera soporte a resend.com. Si para cuando lo aplique todavía no está, intentaré contribuir yo mismo~!

 
hongminhee 2025-08-13

¡Gracias por los comentarios! ¡Intentaré agregar PoolTransport y ResendTransport muy pronto!

 
nemorize 2025-07-15

¿Qué tal si cambiamos “郵票” por “sello postal” en el símbolo?
Ahora mismo también se ve realmente perfecto y bonito, así que lo digo con un poco de cuidado..

 
zinisuni 2025-07-15

Oh~ está bueno~ bien, bien

 
cgl00 2025-07-15

¿Es un proyecto de una sola persona?? Qué impresionante..

 
hongminhee 2025-07-15

Sí, hasta ahora todavía lo he hecho yo solo. 😅