Skip to content

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

Back to all issues
Software
3 min read
On this page

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 👋

Get next Wednesday’s issue

The next focused idea arrives by email. Free, and easy to leave at any time.

Free, no spam, unsubscribe anytime. See the privacy policy.