β€’

tech

Your friendly introduction to local-first

In the last year I explored everything local-first (I even built a sync engine). It all comes down to storage and syncing: client database and finding a way to keep it up to date.


Sandro Maglione

Sandro Maglione

Software

Localfirstconf this week, second edition ✈️

What did change in "just" 1 year? Well, a lot.

Let me give the simplest overview of local-first after (more than) 1 year of personal explorations πŸ‘‡


Local-first, but how?

If you are new to the concept of "local-first", here is my one-liner:

Database on the client πŸͺ„

Simple idea, huge implications.

Let's move one step at the time πŸšΆβ€β™‚οΈβ€βž‘οΈ

Client database

Nothing fancy. You simply store data on the user device, in whatever way possible.

You can consider "client database" as a Glorified Cacheℒ️:

Instead of reading data from the cloud, the UI reads from a local database πŸ’πŸΌβ€β™‚οΈ

That's the first (huge) chuck required to enable local-first (and sync engines in general). What form of storage you choose will dictate most of your final API:

  • Local/Session storage (πŸ‘Ž)
  • IndexedDB
  • SQLite (with OPFS)
  • PgLite

A lot of research in progress to "solve" client storage, no solution stands out (yet) πŸ€”

OPFS is still early, limited support in browsers, and overall painful. Therefore, my experiments with SQLite are limited and mostly unsuccessful.

Pglite is growing (features, popularity, ecosystem). I would suggest giving it a try.

IndexedDB has always been a pain. But, since it's the only "real" long-term storage in the browser, I went on a quest to make it better with effect.

I worked on a new IndexedDb module for @effect/platform-browser (PR).

More articles and tutorials coming for this πŸ”œ

Sync

So, the UI reads from a client database. It has no awareness of any "cloud".

Problem: the data is "trapped" on the user device 😬

Local-first is also about collaboration. Therefore, we need a way to "update" the client about the latest news from other users.

In practice, something must be running on the background to upload/download updates.

That's the role of a sync engine ⚑️

A lot of research here as well. Two main techniques I explored:

  • CRDT (Conflict-Free Replicated Data Type)
  • Event sourcing

It's a distributed system problem, aka it's hard 🀯

Many technologies to watch:

Local-first all the way in

Figure out client storage + syncing and you already get most of the benefits:

  • Offline support
  • Fast UI
  • Great developer experience
  • Collaboration

But local-first goes a few steps further, aiming for a full user-centric experience.

Privacy

"Complete" privacy is only achievable when all the data lives on the user device.

Collaboration open a whole new set of challenges. Data ownership, authentication, encryption, with all sort of edge cases arise in a distributed model.

Longevity + User control

The user owns his data, completely. A local-first app should allow to export locally all the data (in usable formats), and remove it completely from the intermediate syncing cloud.

Server independence

A user is not locked over a single "sync server". I should be able to keep the same client/UI, and only point to a different sync provider.

Local-first aims to achieved the best UX for the user, full control and no lock-in πŸš€

We are getting there

I am in Berlin this week for localfirstconf.

I am writing this before the conference, so you must wait next week for my full report 🫑

But, I can already tell you that the local-first movement is growing. With 3 days of conference, 2 days packed of talks, and many new solutions available.

A staggering progress in just one year (since the previous localfirstconf). Clear signs that you should consider betting on local-first (just like I am doing 🫑)


Meanwhile, my Effect Days 2025 talk is out on Youtube:

This is your 10 minutes get started with frontend effect.

See you next πŸ‘‹

Start here.

Every week I dive headfirst into a topic, uncovering every hidden nook and shadow, to deliver you the most interesting insights

Not convinced? Well, let me tell you more about it