Skip to main content

Overview

bun-smtp supports two TLS modes for securing SMTP connections:
  • Implicit TLS — TLS encryption from the first byte (port 465)
  • STARTTLS — Plain connection upgraded to TLS on demand (ports 25, 587)

Implicit TLS

Implicit TLS (also called SMTPS) establishes an encrypted connection immediately. This is typically used on port 465.
1

Set secure: true

Enable implicit TLS mode:
2

Provide certificates

Add your TLS certificate and private key:
3

Listen on port 465

Start the server on the standard SMTPS port:
With Bun, you can use Bun.file() instead of readFileSync for better performance:

STARTTLS

STARTTLS allows clients to upgrade a plain connection to TLS. This is advertised in the EHLO response and is the standard for ports 25 and 587.
When key and cert are provided but secure is not set (or is false), STARTTLS is automatically advertised in the EHLO capabilities.

Hiding STARTTLS

To support STARTTLS without advertising it in EHLO (clients can still use it if they know about it):

Requiring STARTTLS

Force clients to complete STARTTLS before sending AUTH or MAIL commands:
Clients that attempt AUTH or MAIL before upgrading receive:

Development Mode (No Certificate)

When no key or cert is provided, bun-smtp uses a built-in self-signed certificate. This lets you test TLS functionality without certificate setup:
Never use the built-in certificate in production. It’s self-signed and provides no security guarantees. Always use proper certificates from a trusted CA or Let’s Encrypt.
The built-in certificate is a self-signed localhost certificate from the original smtp-server package:
src/smtp-server.ts
Subject: CN=localhost Valid: 2015-02-12 to 2025-02-09

SNI (Server Name Indication)

Serve different certificates for different hostnames using SNI:
sniOptions accepts either a plain object or a Map<string, TLSOptions> for dynamic certificate management.

Dynamic SNI with Map

Use a Map for runtime certificate updates:

Validating the TLS Handshake

Use onSecure to inspect or reject connections after TLS is established:
onSecure is called after both implicit TLS and STARTTLS upgrades. The socket parameter is a Bun Socket, not a Node.js tls.TLSSocket.

TLS Options Reference

Client Certificate Authentication

Require and validate client certificates:
1

Enable client certificates

2

Validate in onSecure

Updating Certificates at Runtime

Rotate certificates without restarting the server:
New connections will use the updated certificates immediately. Existing connections continue using the old certificates until they close.

Port Recommendations

Port 25

MTA-to-MTATraditional SMTP port for server-to-server communication. Usually supports STARTTLS but doesn’t require it.

Port 587

Message SubmissionStandard port for client-to-server communication. Should require STARTTLS and authentication.

Port 465

SMTPSImplicit TLS from connection start. Use secure: true for this port.

Complete Examples