DEV Community

Cover image for Marco: A privacy-first, offline-first email client built on IMAP
Marco App
Marco App

Posted on

Marco: A privacy-first, offline-first email client built on IMAP

I'm Isaac. I've been building Marco (https://marcoapp.io) for about a year now. It's a cross-platform email client built in React Native with Expo, and I want to share the journey because it's been one of the hardest things I've ever built.

How it started

I switched from Android to iPhone last year and moved custom domain email from Gmail to iCloud. That meant actually using the Apple Mail app on iOS and macOS. After a few weeks of buggy UX and discovering that Apple Mail on iOS sends emails in a different font size than on macOS (not configurable), I went looking for alternatives. I spent two weeks evaluating every email client I could find. They all fell into three buckets: legacy and ugly, free but selling your data, or genuinely great but £250+/year. I'd love to use Superhuman, but I can't justify that for personal email. There's a gap, and nobody seems to be filling it.

The email client graveyard

The more we researched, the more dead email startups we found. Tempo, Big Mail, Caley.io, and countless abandoned open source attempts. Most lasted about 1-2 years. Two things kill them: building an email client is absurdly complex, and Google's OAuth security review for email scopes is eye-wateringly expensive.

Why IMAP-first matters

Almost every email startup builds on the Gmail API. It's convenient, but it locks you into Google. We went IMAP-first, which guarantees interoperability with essentially any email provider in the world. IMAP is also ancient, weird, and full of edge cases. Fun times, and a lot to learn.

The offline-first odyssey

This is where I nearly lost my mind. We committed to full offline support early on (read, reply, delete, organise emails on a plane with no wifi). Sounds straightforward until you realise Marco deals with hundreds of thousands of entities and 100MB+ of data per account.

We went through five offline-first solutions in about three months:

WatermelonDB → Worked initially, but uses an in-memory JS database (LokiJS) to work around IndexedDB performance issues. Holding your entire 100MB+ database in memory is... not great. Maintenance has slowed down too.

Triplit → Best-in-class DX, genuinely lovely API. But subscriptions timed out with under 100k entities. We crashed their server many times. Rooting for this team though.

InstantDB → No TypeScript types, no sort/ordering, no webhooks. Queries that took 2-5ms in WatermelonDB took 200-500ms here. They have since improved their product a lot. I think many of these issues are now resolved.

PowerSync → Most mature option on paper, but self-hosting requires a MongoDB replica set on top of Postgres WAL integration. Their frontend serialises everything between threads as JSON, so rendering 50 emails took 200ms+.

Replicache → Finally. It's just a KV store on top of IndexedDB. No clever relational layer, no graph model. Blazing fast. We built a custom in-memory index layer on top for queries. It just went fully open source too. Conceptually similar to WatermelonDB, without the RAM drawbacks.

The root cause of all these problems: every offline-first web solution is ultimately a hack on top of IndexedDB, which is just a key-value store. Bolting a relational model onto a KV store starts cracking around 10-50k rows. We have millions.

Where we are now

Marco has 2,000+ organic users, is bootstrapped (no VC), and runs on iOS, macOS, and web. The stack is React Native, Expo, Tanstack DB/Query, and Postgres on the backend. Privacy-first: we don't sell data, we don't scan emails for ads.

I'm a three-time founder and former CTO. I've built and scaled products before, but email is genuinely the hardest domain I've worked in. As someone in the email community told me: "There are very few people working on email, but there are a lot of people who want someone to be working on email."

Happy to answer questions about IMAP, offline-first architecture, the email client landscape, or anything else.

https://marcoapp.io

Top comments (0)