Local-First: What It Actually Means for Email
“Local-first” is one of those phrases that means something specific to the people who coined it and something much vaguer to everyone else.
When the local-first software people talk about local-first, they usually mean: your data lives on your machine first, and the cloud is a sync layer that reconciles changes. Conflict resolution is a first-class concern. The network is optional.
That is a real thing. It’s also complicated.
Here’s what local-first means for Spondr.
Not That
Spondr does not do offline-first conflict resolution. If your laptop dies, you still need Gmail. The local database is not trying to be a complete mirror of your email that reconciles with the server when you reconnect.
If that is what you are looking for, there are products that do that. They tend to have complicated sync engines and interesting failure modes when conflicts happen.
This
Local-first in Spondr’s sense means: the UI starts locally. Everything you see, search, scroll through, and act on lives in a local SQLite database and a local full-text search index.
When you open Spondr, it does not wait for the network. Search is instant because the index is local. Thread navigation is instant because the metadata is local. The app feels like it lives on your machine.
That is the goal. Fast, snappy, responsive. This is not because we optimized latency, but because we eliminated it for the common cases.
Gmail Is Still the Source of Truth
Here’s where it gets practical.
When you write a draft, it goes to Gmail first. Then syncs back to the local store. When you send something, Gmail gets it. When you delete something, Gmail deletes it.
The local database is a performance layer, not an alternative store. It is fast because it is local, not because it has a clever sync engine.
This sidesteps an entire class of problems. No conflict resolution. No “my local changes got lost” bugs. No ambiguity about where your data actually lives.
Gmail is the source of truth. The local layer makes it feel good.
There is one exception worth noting. Composing and responding to email offline is a requirement for any email client. If you lose connection mid-draft, you should not lose your work. That case requires a small amount of local draft storage and sync logic to reconcile when you reconnect. It is being built as an exception to the Gmail-first rule, not a departure from it.
Why Not Just Use the Web Client?
Fair question. Gmail’s web client has the same data, same source of truth, same everything.
The difference is feel.
Web apps have to round-trip everything. Search means a server call. Thread switching means a server call. Loading means waiting. The network is always in the loop, and network means latency.
Desktop apps with local data do not have that problem. The data is there. The index is there. The interaction is local.
That sounds minor until you use it for a week and then try to go back.
There is also what you can do with a desktop client that Gmail simply cannot. One-click bulk archive everything from a sender. One-click mark a whole batch as read. Sweep through old threads that are cluttering your inbox. These are workflow things. Gmail has gotten better, but it still requires more clicks and more navigation than a native client with keyboard shortcuts and batch operations.
The Tradeoff That Wasn’t Hard
You might think “local-first” means a complicated architecture with a sync engine that has to stay in sync with Gmail in real time.
It does not have to be that. Not if you are willing to accept a simple constraint: writes go to Gmail first, then come back to the local store.
That constraint eliminates all the hard parts. No two sources of truth. No conflict resolution. No eventual consistency to reason about.
The app gets to be fast because it reads locally, and correct because it writes to Gmail.
That’s the bet.
If you want to see what a local-first email client for Linux feels like, try Spondr.