Skip to content

migueldeicaza/MailFoundation

Repository files navigation

MailFoundation

MailFoundation Banner

MailFoundation is a Swift package that provides IMAP, POP3, and SMTP client stacks plus mail metadata utilities. It is designed to pair with MimeFoundation for MIME parsing and message construction while providing a focused, protocol-level foundation for mail applications and services.

Origin and goal

This project is a port of the .NET Foundation mail stack originally created by Jeffrey Stedfast MailKit/MimeKit. The goal is to bring those capabilities and API ergonomics to Swift developers, with modern async/await support and a Swift-native type system.

Features

  • IMAP, POP3, and SMTP client stacks with sync and async APIs.
  • Async mail stores and transports (AsyncImapMailStore, AsyncPop3MailStore, AsyncSmtpTransport).
  • SASL authentication including SCRAM, NTLM, GSSAPI, CRAM-MD5, and XOAUTH2.
  • STARTTLS and TLS support via Network framework, POSIX sockets, or OpenSSL.
  • Proxy support (SOCKS4/5, HTTP CONNECT).
  • Search and threading helpers (SearchQuery, MessageThreader, threading references).
  • Retry policies, timeouts, and connection pooling.
  • Protocol logging and authentication secret redaction.

Requirements

  • Swift 6.2+
  • macOS 10.15+ (visionOS 1.0+ per Package.swift)

Installation (Swift Package Manager)

Add the package to your Package.swift dependencies:

dependencies: [
    .package(url: "https://github.com/migueldeicaza/MailFoundation", branch: "main")
]

Then add MailFoundation to your target dependencies:

targets: [
    .target(
        name: "YourApp",
        dependencies: [
            "MailFoundation"
        ]
    )
]

Usage

Async IMAP example

import MailFoundation

let store = try AsyncImapMailStore.make(
    host: "imap.example.com",
    port: 993,
    backend: .network
)
try await store.connect()
_ = try await store.authenticate(user: "user@example.com", password: "secret")

_ = try await store.openInbox(access: .readOnly)
let results = try await store.search(.all)
print("Found \(results.ids.count) messages")

await store.disconnect()

Async SMTP example

import MailFoundation
import MimeFoundation

let transport = try AsyncSmtpTransport.make(
    host: "smtp.example.com",
    port: 587,
    backend: .network
)
try await transport.connect()
_ = try await transport.ehlo(domain: "client.example.com")

_ = try await transport.authenticate(SmtpSasl.plain(
    username: "user@example.com",
    password: "secret"
))

let message = MimeMessage()
message.from.add(MailboxAddress(name: nil, address: "sender@example.com"))
message.to.add(MailboxAddress(name: nil, address: "recipient@example.com"))
message.subject = "Hello"
message.body = TextPart("plain", "Hello, World!")

_ = try await transport.send(message)
await transport.disconnect()

Documentation

Full API documentation is available at https://migueldeicaza.github.io/MailFoundation/.

About

Port of MailKit to Swift

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors