# MailCore 2: an asynchronous IMAP, POP and SMTP library for iOS, macOS, Android, Windows and Linux

> MailCore 2 wraps IMAP, POP and SMTP behind an asynchronous Objective-C API with an RFC822 parser and HTML rendering. It is aimed at app developers who need mail inside a native client, and its build story is the part that decides whether you adopt it.

**MailCore/mailcore2** — MailCore 2 provide a simple and asynchronous API to work with e-mail protocols IMAP, POP and SMTP. The API has been redesigned from ground up.

- Repository: https://github.com/MailCore/mailcore2
- Stars: 2,698 · Forks: 649
- Language: C++
- License: NOASSERTION
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/mailcore-mailcore2

## What MailCore 2 replaces for a native mail client

Writing an IMAP client from scratch means implementing a line-oriented protocol with untagged responses, UID-based addressing, folder listing, flags, and a body structure parser that understands MIME. MailCore 2 packages that work behind session objects. The README lists POP, IMAP and SMTP support, an RFC822 parser and generator, asynchronous APIs, HTML rendering of messages, and iOS and Mac support. The API is Objective-C, with Java class documentation also published, and the repository ships build directories for Android, Linux, Windows and Mac alongside the Apple targets. That combination is the point: one library, several platforms, one protocol implementation.

The audience is app developers. The Swift example in the README constructs an MCOIMAPSession, sets hostname, port, username, password and connectionType, then requests a fetch operation. Nothing in that flow is server-side: you configure a session against a real mail server and consume results in a completion block. If you are building a backend service that ingests mail, this is the wrong shape of tool, because the library assumes a client that owns a connection and a user's credentials.

## How the asynchronous operation model actually works

The README is explicit that all fetch requests are made asynchronously through a queue. The mechanism is a two-step handshake. You ask the session for an operation object, passing the parameters of the request, and then you call start on that object. The operation object is what initiates the connection. The README states that the block passed to start is executed on the main thread when the fetch completes, while the actual fetching from IMAP happens on a background thread. That split is the core design decision: network work off the main thread, callbacks on it.

The callback signature carries three values: an error, the fetched messages, and vanished messages. The error is checked first in the sample, and the fetched result is printed afterwards. Vanished messages correspond to the IMAP extension that reports messages removed from a mailbox, which matters when you keep a local cache and need to delete entries rather than just add them.

The request is scoped by folder and by a UID set. In the Swift example the UID set is constructed as MCOIndexSet(range: MCORange(location: 1, length: UInt64.max)), which spans the whole mailbox, and requestKind is set to .headers so only headers come back. That requestKind parameter is where the cost lives: headers are cheap, full bodies are not, and the library makes you choose per operation rather than guessing.

## Installing MailCore 2 and fetching headers from Gmail

The README does not give a single installation command. It routes you to per-platform instructions: build-mac/README.md for iOS and OSX, build-android/README.md for Android, build-windows/README.md for Windows, and build-linux/README.md for Linux. There is also a Package.swift at the repository root and two podspecs, mailcore2-ios.podspec and mailcore2-osx.podspec, in a cocoapods/ directory. Read the build README for your platform before anything else; the top-level README will not get you to a working library.

Once the library is linked, the first real use is a session plus one fetch. The README gives this Swift example:

```swift
let session = MCOIMAPSession()

session.hostname       = "imap.gmail.com"
session.port           = 993
session.username       = "ADDRESS@gmail.com"
session.password       = "123456"
session.connectionType = .TLS
```

Port 993 with .TLS is the implicit TLS IMAP port, so the connection is encrypted from the first byte. The README notes an Objective-C version of the same example on the project wiki.

The fetch itself is requested from the session and started with a completion block. The README shows the folder as "INBOX" and the UID set as the full range, with requestKind set to .headers:

```swift
let folder = "INBOX"
let uids   = MCOIndexSet(range: MCORange(location: 1, length: UInt64.max))

if let fetchOperation = session.fetchMessagesOperation(withFolder: folder, requestKind: .headers, uids: uids) {
  fetchOperation.start { error, fetchedMessages, vanishedMessages in
    if let error = error {
      print("Error downloading message headers: \(error.localizedDescription)")
    }
    print("The post man delivereth: \(fetchedMessages.debugDescription)")
  }
}
```

What you should see is either a localized error description or a debug dump of the header list. Two things to note before copying this. First, the credentials are hardcoded in the sample and the password is a placeholder; the README offers no keychain or token guidance. Second, Gmail rejects plain password authentication for many account configurations, so expect to adapt the authentication step even though the sample does not mention it.

## Where MailCore 2 stops being the right tool

The release history is the sharpest constraint. The most recent release listed is 0.6.4 from 2020-08-01, preceded by 0.6.3 in 2018 and 0.6.2 in 2016. That is a slow cadence by any measure. The repository is not archived and the last push was on 2026-07-29, so work continues on master, but the tagged releases a package manager will resolve to are years old. If your policy requires adopting a tagged release rather than a branch, you are adopting code from 2020.

The licence is the second constraint. The README says MailCore 2 is BSD-Licensed, but the repository metadata reports the licence as NOASSERTION, meaning GitHub could not classify the LICENSE file. Those two statements are not the same, and the discrepancy is worth resolving by reading LICENSE directly rather than trusting either summary. This is not legal advice, just a note that the machine-readable licence field and the README disagree.

The third constraint is authentication. The documented example uses a username and password over TLS. Modern providers increasingly require OAuth or app-specific credentials, and the README does not document an OAuth flow. If your target accounts are behind that requirement, you will be extending the library or handling the token exchange yourself before the session object is useful.

Finally, the README does not document rollback, migration between versions, or a deprecation policy. There is a TODO.md in the repository root, which suggests the maintainers track open work publicly, but the README itself gives no upgrade path.

## MailCore 2 against the original MailCore and against writing your own IMAP layer

The README states the API has been redesigned from the ground up, and one of the related searches is MailCore2 vs mailcore, so the comparison is worth making concrete. The visible difference in the README is the asynchronous operation model: in MailCore 2 you request an operation object from a session and call start with a completion block, with network work on a background thread and the callback on the main thread. The README describes this as conceptually more complex than the original MailCore, which is an unusually direct admission in a project's own introduction. The trade is explicit: more ceremony per call, in exchange for not blocking the thread that draws your interface.

The alternative to MailCore 2 is not another library so much as a different layer. If your application runs on a server, an interpreted-language mail library or a direct IMAP client in your runtime of choice avoids the native build entirely and gives you a debugging loop you can step through. MailCore 2's value is concentrated in the Apple and Android targets, where shipping a native library is the normal distribution model. On Linux or Windows, where the README still points you at build instructions, that advantage is weaker and you are paying the C++ build cost for a protocol implementation you could get elsewhere. The repository layout supports this reading: build-mac, build-android, build-windows and build-linux each carry their own instructions, and deps/ and .gitmodules indicate external dependencies pinned into the tree.

## Maintenance, upgrades and what the licence field leaves open

The last push was on 2026-07-29, so the repository is receiving changes. That is not the same as a maintained release line: the newest tagged release is 0.6.4 from 2020-08-01. Anyone pinning to a release is running code that predates the current master by roughly six years of commits, and the README offers no changelog or upgrade notes to tell you what moved between 0.6.4 and master. Budget for reading commit history if you need that answer, because the documentation does not provide it.

Upgrade cost also depends on the dependency tree. The repository has a deps/ directory and a .gitmodules file, so at least some dependencies are vendored or pinned as submodules. When you build, those pins are what you get. Moving to a newer master means moving those pins too, and the README does not describe how the dependencies are versioned or how to update them safely.

On licensing, the README says BSD-Licensed while the repository's licence field reads NOASSERTION. Practically, that means the automated tooling that scans your dependency tree may flag the package or fail to classify it, and you will need to read LICENSE to answer the question. The README's own summary is a starting point, not a substitute for the file.

## Conclusion

Adopt MailCore 2 when you are building a native mail client in Objective-C, Swift or Java and want IMAP, POP and SMTP plus an RFC822 parser behind one asynchronous API. Do not adopt it if you need a maintained server-side mail stack, a documented release cadence or a licence you can classify without reading LICENSE yourself. Before committing, verify that build-mac/README.md or build-android/README.md matches your toolchain, that the pinned dependency revisions in deps/ still resolve, and that the 0.6.4 release is the version your package manager actually resolves to.

## FAQ

### Which platforms and languages does MailCore 2 support?

The README lists iOS and Mac support and an Objective-C API, with Java class documentation also published. The repository carries build directories for Android, Linux and Windows as well, each with its own build README.

### How do I install MailCore 2 for iOS or Android?

The README does not give a single install command. It points to build-mac/README.md for iOS and OSX and build-android/README.md for Android, and the repository also contains mailcore2-ios.podspec, mailcore2-osx.podspec and a Package.swift at the root.

### Is the MailCore 2 API asynchronous?

Yes, the README states that all fetch requests are made asynchronously through a queue. You request an operation object from the session, call start with a completion block, and the network work happens on a background thread while the block runs on the main thread.

### What licence is MailCore 2 released under?

The README says MailCore 2 is BSD-Licensed, but the repository's licence field reports NOASSERTION, so the two do not agree. Read the LICENSE file in the repository to resolve it.

## Sources

- [Issues](https://github.com/MailCore/mailcore2/issues)
- [MailCore/mailcore2 on GitHub](https://github.com/MailCore/mailcore2)
- [README](https://github.com/MailCore/mailcore2/blob/master/README.md)
- [Releases](https://github.com/MailCore/mailcore2/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mailcore-mailcore2
