Skip to content

Latest commit

 

History

114 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Perfect - SMTP 简体中文

Swift 6.2 Platforms macOS 12+ License Apache 2.0

Perfect-SMTP is a from-scratch Swift 6.2 / SwiftNIO SMTP client. It is not a wrapper around libcurl or any other mail library — it drives the SMTP wire protocol itself, including its own STARTTLS state machine, connection pooling, DKIM signing, and MTA-STS policy enforcement.

It ships three delivery strategies (relay through an existing SMTP host, hand off to a local MTA like Postfix/sendmail, or resolve MX records and deliver directly), so you can pick the one that matches how you already operate mail, or let Perfect-SMTP be the terminal MTA itself.

This is a complete rewrite of the pre-2026 libcurl-based Perfect-SMTP. If you used the old EMail/SMTPClient/Recipient API, see Migrating from the old Perfect-SMTP in the user guide — this is not a drop-in upgrade. The old version is preserved on the legacy branch.

This package is domain-agnostic by design — it has no Lasso-specific code and no Lasso dependency. It is, however, a core dependency: Perfect-Lasso — a Swift reimplementation of the Lasso language, still in active development and not yet production-ready, though validated against real code from multiple production e-commerce sites — depends on this package directly to implement its email_send tag, which sends real outbound email during that validation testing. (There is a separate, unrelated in-progress target called LassoPerfectSMTP being built inside the Perfect-Lasso repo on another branch — that is not this package and does not depend on it.)

Features

  • Hand-rolled SMTP client on SwiftNIO — its own STARTTLS upgrade sequence with byte-precise buffer discipline against injection/downgrade attacks, connection pooling with circuit breaking, and PIPELINING support.
  • DKIM signing (RFC 6376) — RSA-SHA256 and Ed25519-SHA256 (RFC 8463), including dual-signing, with automatic oversigning of security-sensitive headers and a DMARC-alignment lint.
  • Three delivery strategiesRelayTransport (an ESP or existing SMTP relay), LocalMTATransport (hand off to sendmail/Postfix on the same host), and DirectMXTransport (resolve MX records and deliver directly, with its own retry queue and circuit breaker).
  • MTA-STS (RFC 8461) policy discovery, caching, and enforcement for direct-MX delivery, plus opportunistic STARTTLS by default.
  • SASL authenticationPLAIN, LOGIN, and XOAUTH2 (required by Gmail/Workspace, increasingly required by Microsoft 365).
  • Deliverability headersList-Unsubscribe/List-Unsubscribe-Post (RFC 8058), Precedence, Auto-Submitted — the headers Gmail and Yahoo have required for bulk senders since November 2025.
  • Bulk/list-server ready — a bounded-concurrency batch send and an AsyncSequence-based streaming send for sending to millions of recipients without materializing them all in memory.
  • Structured delivery results — every send returns a per-recipient outcome (delivered, queued for retry, permanently failed, expired, ambiguous, or a transport-level failure) instead of a single pass/fail.

For anything beyond the basics below, see the full user guide.

Requirements

  • Swift 6.2 toolchain (swift-tools-version: 6.2, .swiftLanguageMode(.v6))
  • macOS 12 or later (Package.swift declares platforms: [.macOS(.v12)])

Installation

Add the package to your Package.swift. No tagged releases exist yet, so pin a branch or a specific commit rather than a version range:

.package(url: "https://github.com/PerfectlySoft/Perfect-SMTP.git", branch: "main")

and depend on the PerfectSMTP product (it re-exports PerfectSMTPCore, which you only need directly if you want to compose/sign messages without sending them):

.target(
    name: "YourTarget",
    dependencies: [
        .product(name: "PerfectSMTP", package: "Perfect-SMTP"),
    ]
)

Quick start

Send one email through an existing SMTP relay (a corporate MTA or an ESP like SendGrid/Postmark/SES):

import PerfectSMTP
import NIOPosix

let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)

let transport = RelayTransport(
    config: RelayConfig(
        host: "smtp.example.com",
        port: 587,
        tls: .startTLS,
        auth: .plain(username: "postmaster@example.com", password: "secret")
    ),
    group: group
)
let mailer = SMTPMailer(transport: transport)

var message = EmailMessage(from: EmailAddress(displayName: "Ops", address: "ops@example.com"))
message.to = [EmailAddress(address: "user@dest.com")]
message.subject = "Hello from Perfect-SMTP"
message.textBody = "Hi there!"

let results = try await mailer.send(message, envelopeFrom: .address("ops@example.com"))
for result in results {
    print(result.recipient, result.outcome)
}

try await group.shutdownGracefully()

That's it for the basic case. For DKIM signing, direct-MX delivery, authentication options, bulk sending, and deliverability headers, see the user guide.

Testing

swift test

346 tests (188 in PerfectSMTPTests, 158 in PerfectSMTPCoreTests) run with no external services and no environment variables — this includes tests that open real loopback sockets (a STARTTLS handshake and a full DirectMX delivery each run against an in-process fake SMTP server on 127.0.0.1), but nothing here talks to the real network or a real mail server.

Note: the original rewrite plan (Documentation/swift6-nio-rewrite-plan.md §4.1/§5) describes an additional SMTP_TESTS=1-gated live-integration tier against a MailHog/smtp4dev CI service container. That tier was never built — there is no such environment variable referenced anywhere in Tests/, and this repository has no CI workflow files at all. If you need to verify against a real SMTP server, point a RelayTransport or DirectMXTransport at a local MailHog/smtp4dev instance yourself; see Testing your integration in the user guide.

License

Apache License 2.0 — see LICENSE.

About

SMTP Client for Perfect. Completely updated for Swift 6, modern concurrency and standards using open source tools from the Swift ecosystem.

Topics

Resources

Stars

23 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages