SMTP
hono-email/smtp provides a connector-based SMTP sender. You choose a runtime connector, instantiate SmtpTransport, and pass it to sendEmail().
Example
Section titled “Example”import CloudflareConnector from 'hono-email/smtp/cloudflare'import { Body, Html, Text, sendEmail } from 'hono-email'import { SmtpTransport } from 'hono-email/smtp'
const dkimPrivateKey = `-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----`
const smtp = new SmtpTransport({ connector: CloudflareConnector, hostname: 'smtp.example.com', port: 587, secure: 'starttls', connectionTimeout: 10_000, greetingTimeout: 10_000, socketTimeout: 30_000, auth: { username: 'smtp-user', password: 'smtp-password', }, dkim: { domainName: 'example.com', keySelector: 'mail', privateKey: dkimPrivateKey, }, pool: { maxConnections: 2, maxMessages: 100, }, limits: { maxAttachmentSize: 10 * 1024 * 1024, },})
try { await smtp.verify()
const receipt = await sendEmail({ adapter: smtp, from: 'sender@example.com', to: ['recipient@example.com', 'second@example.com'], subject: 'Welcome', envelope: { from: 'bounces@example.com', }, jsx: ( <Html> <Body> <Text>Hello from hono-email.</Text> </Body> </Html> ), attachments: [ { filename: 'invoice.txt', content: 'Invoice text', contentType: 'text/plain', }, { filename: 'logo.png', href: 'https://example.com/assets/logo.png', cid: 'logo', contentDisposition: 'inline', }, ], })
if (!receipt.successful) { console.error(receipt.errorMessages) }} finally { await smtp.close()}For the full list of configuration options, see the SMTP Options API Reference.
Runtime connectors
Section titled “Runtime connectors”| Entry point | Runtime |
|---|---|
hono-email/smtp/cloudflare |
Cloudflare Workers |
hono-email/smtp/node |
Node.js |
hono-email/smtp/deno |
Deno |
hono-email/smtp/bun |
Bun |
Important runtime notes
Section titled “Important runtime notes”- SMTP transport uses Web Streams internally. Runtime-specific socket support is supplied by the connector.
- Cloudflare Workers does not allow outbound SMTP connections on port
25. Use submission ports such as465or587. - Bun’s TCP API supports direct TLS connections, but the Bun connector does not support STARTTLS upgrade. Use port
465withsecure: trueon Bun.
Connection pooling
Section titled “Connection pooling”SmtpTransport reuses SMTP sessions until smtp.close() is called. The default pool size is 1, so sends on the same transport share one TCP connection sequentially.
- Set
pool.maxConnectionsto allow multiple concurrent SMTP sessions. - Set
pool.maxMessagesto retire a session after a fixed number of messages. - If a session fails during send, that session is discarded. The message is not retried automatically.
Delivery controls
Section titled “Delivery controls”await smtp.verify()checks connection setup, TLS negotiation, and authentication without sending a message.dkimcan be configured onSmtpTransportor overridden per message to add aDKIM-Signatureheader before SMTP delivery.envelopelets you override the SMTP envelope sender and recipients without changing the visibleFrom/Toheaders.to,cc,bcc, andenvelope.toaccept single addresses or arrays. SMTP sends oneRCPT TOcommand per resolved recipient and reports partial recipient rejection inreceipt.rejected.
Options
Section titled “Options”connector Required
Section titled “connector ”Type: SmtpConnector
Runtime-specific TCP socket connector. Import one for your runtime:
| Entry point | Runtime |
|---|---|
hono-email/smtp/node |
Node.js |
hono-email/smtp/bun |
Bun |
hono-email/smtp/deno |
Deno |
hono-email/smtp/cloudflare |
Cloudflare Workers |
hostname Required
Section titled “hostname ”Type: string
SMTP server hostname.
port Required
Section titled “port ”Type: number
SMTP server port. Use 587 for STARTTLS submission, 465 for implicit TLS.
secure Optional
Section titled “secure ”Type: boolean | 'starttls' · Default: 'starttls'
TLS mode:
| Value | Behavior |
|---|---|
'starttls' |
Upgrade to TLS after connecting (STARTTLS). |
true |
Implicit TLS from the start of the connection. |
false |
Plain-text connection with no TLS. |
auth Optional
Section titled “auth ”Type: { type?: 'plain' | 'login'; username: string; password: string }
SMTP authentication credentials. type defaults to 'plain'.
dkim Optional
Section titled “dkim ”Type: EmailDkimOptions
DKIM signing options. See Email Types.
clientName Optional
Section titled “clientName ”Type: string
Hostname sent in the EHLO/HELO greeting. Defaults to the connector’s resolved hostname.
connectionTimeout Optional
Section titled “connectionTimeout ”Type: number
Milliseconds to wait for the TCP connection to be established.
greetingTimeout Optional
Section titled “greetingTimeout ”Type: number
Milliseconds to wait for the server greeting after connecting.
socketTimeout Optional
Section titled “socketTimeout ”Type: number
Milliseconds of inactivity before the socket is considered timed out.
pool Optional
Section titled “pool ”Type: { maxConnections?: number; maxMessages?: number }
Connection pool settings.
maxConnections— maximum concurrent SMTP sessions. Default:1.maxMessages— retire a session after this many messages. Default: unlimited.
limits.maxAttachmentSize Optional
Section titled “limits.maxAttachmentSize ”Type: number
Maximum attachment size in bytes.