Writing

Why local-first is the only sensible architecture for a bookmarking app

When I launched DoubleMemory on Show HN, Pocket had just announced it was closing. Before it, Omnivore and UpNext had closed, Delicious and Readability long before, and Instapaper had gone back to indie after changing hands. All of them were cloud-hosted services. That pattern got me reflecting: maybe a local-first architecture is better positioned to last in this space.

A year and a half later I don't think it is just better positioned. For an app whose whole job is to keep what you saved, I think local-first is the only architecture that makes sense.

The job of a bookmarking app

A bookmarking app has an unusual job. You don't open it to finish something today. You put things in so they are still there in a year, or five, when you finally want them. Its most important feature is that it outlives your reading list.

So the question to ask of its architecture isn't how fast it ships features. It's what has to keep running for your library to still be there, and who pays for that.

Why hosted services keep dying

A hosted read-it-later service keeps every saved page, image and highlight on its own servers, and that pile only grows. Every summary, tag and search it runs on its own machines is billed per item, per user, forever. Its costs grow with every user it gains.

In my not-so-scientific comparison at launch, a hosted competitor's server bill landed around a million dollars a year, against nothing for DoubleMemory beyond what iCloud already runs. The exact number doesn't matter. The shape does: the more people use a hosted service, the more it costs to keep alive.

That is a trap. To keep up, the service needs VC money, ads or data deals, and then a pivot, a sale or a shutdown on someone else's schedule. Your library goes with it. It isn't that the people building these services did anything wrong. The architecture makes a calm, long-lived bookmarking app very hard to run as a business.

Why self-hosting isn't the answer

Every time a read-it-later app closes, someone says: if only it were open source, I could self-host it. I understand the instinct. Self-hosting fixes ownership. Nobody can shut your library down but you.

But it keeps the server and makes you its operator. Someone has to run the box, keep it updated and patched, back it up, renew the certificate, and expose it to the internet so your phone can reach it. For a list of links. It is a tried and proven paradigm, and it is the right answer for some people. For most people it trades one fragile dependency, a company, for another, their own spare weekend.

The thing worth keeping from self-hosting is the ownership, not the server.

Local-first: the library is on your device

Local-first, a term from Ink & Switch, flips the arrangement. Your library lives on your device first. The app reads and writes it there, so saving, browsing and search are instant and work in a tunnel. Sync is a convenience on top, not the thing everything depends on.

For a bookmarking app this lines everything up:

  • It's fast. Nothing waits on a round trip to a server.
  • It works offline. Saving and search don't need a connection, and recent items keep their reader view.
  • It's yours. There is no server of mine holding your saves, so there is nothing of yours for me to lose, sell or shut down.
  • It lasts. Once installed, the app doesn't depend on anything I run. DoubleMemory keeps working unless Apple shuts down iCloud or you delete it.
  • It's portable. Owning your library includes being able to leave with it. You can export the whole library any time, and bring one in from Safari, Pocket, Readwise, Omnivore, mymind or any JSON, with import tools that run in your browser and never upload your data.

Why not just keep it all as plain files, then? I wrote about that separately in Why not files over app?

Why iCloud

Local-first still needs sync, and sync usually means a server. Apple worked this out with CloudKit before almost anyone else: your library syncs through your own private iCloud, under the Apple Account you are already signed in with on every Mac, iPhone and iPad.

That means no server for me to run and no bill that grows with users. You keep paying Apple for your storage, the way you already do. I can't read your library; it is in your iCloud, not mine. The web app works the same way: you sign in with your Apple Account and it talks straight to your private iCloud, with nothing of mine in between.

It keeps privacy simple too. I never collect, store or process your library, so there is no copy of it on my side to secure, move across borders or hand over. It sits under Apple's iCloud terms instead: for people in the EU, the UK and Switzerland, Apple's privacy policy names Apple Distribution International in Ireland as the controller of their personal data, and iCloud accounts in mainland China are stored in China.

Why no account

An account is a server, a database of emails and passwords, a sign-up form, a reset flow and a breach waiting to happen. It exists so a service can know who you are on its machines. If there are no machines of mine, there is nothing to sign up for.

So DoubleMemory has no account. You open it and start saving. Your Apple Account already does the one job an account would do here, which is keeping your devices in sync.

Why this let one person build DoubleMemory

The part I didn't expect is how much the architecture gives back. Building on the platform instead of a server, a lot of hard work is already done:

  • Previews. When you save a link, Apple generates the rich preview for thousands of different kinds of links, and the app caches it. A hosted service would write custom code per site or settle for one generic card.
  • Capture. No browser extensions to build and maintain for every browser and store. Capture is ⌘C twice, the share sheet, the Services menu, drag and drop, Shortcuts and Siri, all things the system already provides.
  • AI. Auto Tags, Listen and Ask Memory run on your device with Apple Intelligence. Keeping AI on device isn't just more private; it's the only way AI features don't turn into a per-user bill.
  • Search and system features. Spotlight, Siri and Shortcuts come with the platform.

Put together, a new user costs close to nothing. That is why the core of DoubleMemory can stay free, why the subscription only has to fund the features that help you get value back out of what you saved, and why the app is default-alive. It doesn't need a growth curve to survive.

The tradeoffs

This architecture has costs, and I'd rather name them. The native apps are Apple only: Mac, iPhone and iPad. The web app fills the gap: it runs in any browser, including on Android and Linux, and installs there as an app (a PWA), so your library comes with you to those devices too. It depends on iCloud, so if you don't use iCloud, it isn't for you yet. And sync works the way CloudKit works, not the way a custom server could.

I think those are the right tradeoffs for an app whose job is to keep what you save. A bookmarking app should outlive your reading list, and the only way to be sure of that is for it not to depend on its maker staying in business.

If you want the longer story of how it started, I wrote about it in Why I created DoubleMemory.