Warning
STARTTLS is not production-ready. Bun does not support socket.upgradeTLS() on
server-side sockets (oven-sh/bun#25044),
which means the STARTTLS command will crash or silently fail. In production, use
implicit TLS (port 465) or terminate TLS externally with HAProxy or stunnel.
Upvote the issue to help prioritize a fix.
fumi - means letter✉️ in Japanese - is a small, simple, and ultrafast SMTP Server framework built on Bun.
import { Fumi } from "@puiusabin/fumi";
const app = new Fumi({ authOptional: true });
app.onMailFrom(async (ctx, next) => {
if (ctx.address.address.endsWith("@blocked.example")) {
ctx.reject("Domain blocked", 550);
}
await next();
});
await app.listen(2525);bun add @puiusabin/fumi- Ultrafast 🚀 - Runs natively on Bun. No adapter layer, no Node.js compat overhead.
- Lightweight 🪶 - Tiny core. One runtime dependency (
smtp-server). - Middleware 🔗 - koa-style
(ctx, next)chains per SMTP phase: connect, auth, mailFrom, rcptTo, data, close. - Plugin system 🔌 - A plugin is just
(app: Fumi) => void. No registry, no lifecycle hooks. - Delightful DX 😃 - Super clean APIs. First-class TypeScript support.
Full docs at fumi-smtp.vercel.app.
Contributions welcome.
- Open an issue to propose a feature or report a bug.
- Open a pull request to fix a bug or improve docs.
- Build and share a plugin.
Sabin Puiu https://github.com/puiusabin
Distributed under the MIT License. See LICENSE for more information.