This is the model I want from 90% of the software out there, just give me a reasonable price to buy it, make the product good, and don't marry it to the cloud so much that its unusable w/out it.
There are also a lot of added benefits to this model in general beyond the data privacy (most are mentioned in the article), but not all the problems are solved here. This is a big space that still needs a lot of tooling to make things really easy going but the tech to do it is there.
Finally, the best part (IMHO) about local-first software is it brings back a much healthier incentive structure - you're not monetizing via ads or tracking users or maxing "engagement" - you're just building a product and getting paid for how good it is. To me it feels like its software that actually serves the user.
https://news.ycombinator.com/item?id=19804478 - May 2019, 191 comments
https://news.ycombinator.com/item?id=21581444 - Nov 2019, 241 comments
https://news.ycombinator.com/item?id=23985816 - Jul 2020, 9 comments
https://news.ycombinator.com/item?id=24027663 - Aug 2020, 134 comments
https://news.ycombinator.com/item?id=26266881 - Feb 2021, 90 comments
https://news.ycombinator.com/item?id=31594613 - Jun 2022, 30 comments
https://news.ycombinator.com/item?id=37743517 - Oct 2023, 50 comments
* Download all your data from Microsoft's "OneDrive" cloud storage, which if not disabled, is the default storage method in a new Windows install.
* Verify that all your files are now stored locally.
* Click the gear icon, go to "Settings -> "Account" -> "Unlink this PC," right-click, "Unlink account".
* Remove Microsoft's OneDrive app from your system -- full removal is the only way to prevent perpetual harassment and reactivation. Go to "Apps" -> "Apps & features" (or "Installed apps" on Windows 11) -> "Microsoft OneDrive", right-click, "Uninstall."
* Optional extra step: cancel your Microsoft 365 subscription and install LibreOffice (free, open-source).
Remember this -- cloud storage only has advantages for Microsoft and law enforcement (which have a number of easy ways to gain access to your documents compared to local storage). For a Windows user, cloud storage is the ultimate Dark Pattern.I held off on playing with Typst for years because I was under the (incorrect) impression that the only way to use it was with their web editor. I'm sure that their editor is completely fine, but I am pretty entrenched in Neovim and Pandoc had been serving me well.
Once I found out that Typst has a command line version that I can use directly, it became more appealing, because I'm pretty sick of cloud shit.
Wanting to be able to run AI fully privately, and offline is the reason we created Cactus:
https://github.com/cactus-compute/cactus
Fully open-source, cross-platform & blazing-fast; lets you plug in private AI into any app on your phone.
There was a great panel discussion this year from a number of the co-authors of the the paper linked, discussing what is Local-first software in the context of dev tools and what they have learnt since the original paper. It's very much worth watching: https://youtu.be/86NmEerklTs?si=Kodd7kD39337CTbf
The community are very much settling on "Sync" being a component of local first, but applicable so much wider. Along with local first software being a characteristic of end user software, with dev tools - such as sync engines - being an enabling tool but not "local first" in as much themselves.
The full set of talks from the last couple of years are online here: https://youtube.com/@localfirstconf?si=uHHi5Tsy60ewhQTQ
It's an exciting time for the local-first / sync engine community, we've been working on tools that enable realtime collaborative and async collaborative experiences, and now with the onset of AI the market for this is exploring. Every AI app is inherently multi user collaborative with the agents as actors within the system. This requires the tech that the sync engine community has been working on.
I’ve been building the offline-first (or local-first) app Brisqi[0] for a while now, it was designed from the ground up with the offline-first philosophy.
In my view, a local-first app is designed to function completely offline for an indefinite period. The local experience is the foundation, not a fallback and cloud syncing should be a secondary enhancement, not a requirement.
I also don’t consider apps that rely on temporary cache to be offline-first. A true offline-first app should use a local database to persist data. Many apps labeled as “offline-first” are actually just offline-tolerant, they offer limited offline functionality but ultimately depend on reconnecting to the internet.
Building an offline-first app is certainly more challenging than creating an online-only web app. The syncing mechanism must be reliable enough to handle transitions between offline and online states, ensuring that data syncs to the cloud consistently and without loss. I’ve written more about how I approached this in my blog post[1].
[1] https://blog.brisqi.com/posts/how-i-designed-an-offline-firs...
But once you get past toy examples, you start wanting to support operations like "edit", and there generally isn't a way to infer the user's intent there. Like, if my cookie recipe starts with 100g of sugar, and I modify it on my phone to use 200g of sugar, and I modify it on my desktop to use 150g of honey instead of 100g of sugar, there are a bunch of ways to reconcile that:
1. Stick with 200g of sugar, drop the 1.5x honey substitution.
2. Stick with 150g of honey, drop the 2x.
3. Merge them - 300g of honey.
4. Merge them - 150g of honey and 50g of sugar.
There's no way for any automated system to infer my intent there. So you've got to either:
1. Ask the user to resolve the conflict. This means you have to build out the whole "resolve this merge conflict for me" UI and the promise of "conflict-free" has not been fulfilled.
2. Arbitrarily choose an option and silently merge. This risks badly surprising the user and losing changes.
3. Arbitrarily choose an option, but expose the fact that you've auto-resolved a conflict and allow the user to manually re-resolve. This requires even more UI work than option 1.
4. Constrain your data model to only allow representing intents that can be deterministically resolved. In practice I think this is too severe of a constraint to allow building anything other than toy apps.
IMO #1 and #3 are the least-bad options, but I don't think they're consistent with the expectations you'd have for CRDTs after reading this article.
(FWIW, https://automerge.org/docs/reference/documents/conflicts/ is the relevant documentation for their Automerge library. It looks like they've chosen option 3.)
Connected appliances and cars have got to be the stupidest bit of engineering from a practical standpoint.
But it is a nightmare when it goes wrong: the conclusion I've reached is that it is out of reach to regular people who don't want the Byzantine support load that could accompany something going wrong. They want turnkey. They want simple. They aren't interested in operating services, they're interested in using them.
The FLOSS model of self hosting doesn't really offer a reliable way of getting this: most businesses operating this way are undercapitalised and have little hope of ever being any other way. Many are just hobbies. There are a few exceptions, but they're rare and fundamentally the possibility of needing support still exists.
What is needed, imo, is to leverage the power of centralised, professional operations and development, but to govern it democratically. This means cooperatives where users are active participants in governance alongside employees.
I've done a little work towards this myself, in the form of a not-yet-seen-the-light-of-day project.
What I'd love to see is a set of developers and operators actually getting paid for their work and users getting a better deal in terms of cost, service, and privacy, on their own (aggregate) terms. Honestly, I'd love to be one of them.
Does anyone think this has legs to the same extent as local-first or self hosting? Curious to know people's responses.
The problems with closed-source software (lack of control, lack of reliability) were solved with a new business model: open source development, which came with new licenses and new ways of getting revenue (maintenance contracts instead of license fees).
In the same way, we need a business model solution to cloud-vendor ills.
Imagine we create standard contracts/licenses that define rights so that users can be confident of their relationship with cloud-vendors. Over time, maybe users would only deal with vendors that had these licenses. The rights would be something like:
* End-of-life contracts: cloud-vendors should contractually spell out what happens if they can't afford to keep the servers running.
* Data portability guarantees: Vendors must spell out how data gets migrated out, and all formats must be either open or (at minimum) fully documented.
* Data privacy transparency: Vendors must track/audit all data access and report to the user who/what read their data and when.
I'm sure you can think of a dozen other clauses.
The tricky part is, of course, adoption. What's in it for the cloud-vendors? Why would they adopt this? The major fear of cloud-vendors is, I think, churn. If you're paying lots of money to get people to try your service, you have to make sure they don't churn out, or you'll lose money. Maybe these contracts come only with annual subscription terms. Or maybe the appeal of these contracts is enough for vendors to charge more.
I've been working on Relay [0] (realtime multiplayer for Obsidian) and we're trying to follow tailscale's approach by separating out the compute/document sync from our auth control plane.
This means thats users still subscribe to our service (and help fund development) and do authn/authz through our service, but we can keep their data entirely private (we can't access it).
[0] https://relay.md
In practice, it’s hard! You’re effectively responsible for building a sync engine, handling conflict resolution, managing schema migration, etc.
This said, tools for local-first software development seem to have improved in the past couple years. I keep my eye on jazz.tools, electric-sql, and Rocicorp’s Zero. Are there others?
We do use online services like firebase for auth, and some service to fetch commodity prices etc, but rest of the data is stored in browser storage (sqlite) and backed to local disk (and soon dropbox). We also syncs data across devices, always encrypting data in transit.
I think it's the way to go, for most personal data applications.
It’s based on NixOS to provide as much as possible out of the box and declaratively: https, SSO, LDAP, backups, ZFS w/ snapshots, etc.
It’s a competitor to cloud hosting because it packages Vaultwarden and Nextcloud to store most of your data. It does provide more services than that though, home assistant for example.
It’s a competitor to YUNoHost but IMO better (or aims to be) because you can use the building blocks provided by SelfHostBlocks to self-host any packages you want. It’s more of a library than a framework.
It’s a competitor to NAS but better because everything is open source.
It still requires the user to be technical but I’m working on removing that caveat. One of my goals is to allow to install it on your hardware without needing nix or touching the command line.
The backend for my personal notes, tasks, bookmarks, calendar and feeds are files in directories synced with Syncthing across devices.
I ended there after going from one app to another and being tired of all this.
It is self hosted with no server backend (beyond a Syncthing on a NAS or VPS, optional). It is very reliable and works without Internet connection.
I could have put everything in sqlite too and sync it one way or another, but it seemed already too complicated for my requirements.
I can't share it beyond my close relatives but I had the same problem with people using Google or Microsoft before.
The user-friendliness challenge is real though. Setting up Audiobookshelf [1] is more work than "just sign up," but once you have it running, the local-first client becomes much cleaner to build. No user accounts, no subscription billing, no scaling concerns. Simple pricing too: buy once, own forever. No monthly fees to access your own audiobooks.
> Cloud apps like Google Docs and Trello are popular because they enable real-time collaboration with colleagues, and they make it easy for us to access our work from all of our devices. However, by centralizing data storage on servers, cloud apps also take away ownership and agency from users. If a service shuts down, the software stops functioning, and data created with that software is lost.
"Apple pie might be tasty and nutritious and exactly what you want, but, theoretically, apple pie could burst into flames someday, and take your favorite pie-eating bib with it.
An OS agnostic apps, meaning web apps is such a killer feature. You can use the same app on: Linux, Mac OS, Windows, Android, iOS
Even more, developing for web is typically faster. You made the change in the code => you see the result on the screen. For example: phone apps written in swift could be faster than ones written in react-native, but it is so annoying waiting for the compilation to finish after every small change.
----
When I worked on imagery data in an autonomous vehicles company product managers pushed us to explore the data in the cloud and it was soooo inconvenient.
As the result, PMs were ignored and everyone had a personal desktop with GPUs and fast SSDs that had the local copy of the data, so that debugging, prototyping would be fast.
As lag that one gets working with a heavy data remotely reminded moving back from SSD to slow HDD, where you needed to wait some time to see the result on the screen.
It was only half a second every time, but felt ultra annoying.
[1] https://tiamat.tsotech.com/pao (2012)
If there is anyone interested in working on such projects - let's talk! We can't leave our future to greedy surveillance zealots.
I'm personally very against vendor lock in, but there is some value to them.
NC itself gets you file sync and webdav etc. An add on gets you the webby version of LibreOffice. You can bolt on AI addons to classify and tag your images/photos and with a bit more effort, your docs too.
It's properly local first.
- because I could not find something similar that doesn't milk and own my data
- to never lose a bookmark again
- to have my bookmark data encrypted in the cloud
- to have private history
- to have some extra time saving features in the extension that are for unknown reason rare to find
- more learning and experience (it's acutally quite complex to build this)
After about 4 years of using it daily on every pc I own, I found out it's a pain for me and my family when it is not installed on a browser. I thought; if it's useful for us, it might be useful for others too! So, I decided to make it available by subscription for a small fee to cover the server and other costs. I'm not really into marketing, so almost no one knows it exists. You can find it on markbook.io.Asking for a friend . . .
Moreover, local-first —at least in theory— enables less infrastructure, which could reignite new indie open source software with less vendor lock-in.
However, despite all my excitement about embracing these ideas in the pursuit of better software, there's one hurdle that preventing more wide spread adoption amongst developers, and that is the Web platform.
The Web platform lacks building blocks for distributing hashed and/or signed software that isn't tied to origins. In other words, it's hard to decouple web-apps from the same-origin model which requires you set up a domain and serve requests dynamically.
Service Workers and PWAs do help a bit in terms of building offline experiences, but if you want users to download once, and upgrade when they want (and internet is available), you can't use the Web. So you end up breaking out of the browser, and start using Web technologies outside of the browser with better OS functionality, like Electron, React Native, Tauri et al (the https://userandagents.com/ community is doing some cool experiments in this space).
If you really embrace "local first" just use the file system, and the user can choose from many solutions like git, box, etc.
I hate signing up for your sync just as much as any other SAAS, but it's even more opaque and likely to break.
Since it needed to access users' local photo libraries, I didn't want the app to connect to the internet under any circumstances. So I made it a paid app instead of the usual free+in-app purchases model, since the latter requires calling StoreKit which goes online. But because the app had to run the CLIP model, it would crash on lower-performance phones like the iPhone X. Users who paid for it couldn't use it and felt scammed, leading to tons of one-star reviews and angry complaints about their photos being stolen. Eventually I decided to open-source the app, though it never brought me much revenue anyway.
Two years later, Apple started announcing they'd be integrating this exact feature into Apple Intelligence : )
Whether you need a spinner or not should be decided by the User Experience (e.g., when the user has to wait for more than 100ms, show a spinner), and not by the location of the data. I am a big fan of local-first apps and enjoy building them myself. However, sometimes your app takes a moment to load. With local-first, you eliminate the network as a source of delays, but there are other factors as well, such as large data sets or complex algorithms.
For example, when you have a project planning software and want to plan 100 work packages with multiple resource combinations in an optimal way, depending on the algorithm, this can take some time. In that case, a spinner or a progress bar is a good thing.
The article posits it as though subscription software is something which has been sneaked in on us. But users today expect things like instant updates, sync across devices, collaboration, and constant bug fixes and patches - none of which come easily if you're only willing to pay for the system once.
This seems like a bold claim, but IMHO Ink & Switch have earned their solid reputation and it wouldn't surprise me if it's true. I agree w/ their analysis and am philosophically aligned w/ their user-centric worldview. So who's going to build "Firebase for CRDTs"?
I love this article, but the section on security raised a lot of questions. What's the model for authorizing access to documents for collaboration? How do you managed keys safely for encrypted data? How do users recover "lost" keys?
Cloud computing models have a lot of security mechanisms built-in. You might not like the model (AWS IAM for example) but at least there's a foundation already in place.
Its not local-first or some sort of cloud diet trend, it should be the norm.
- Password manager: KeyPassXC
- Notes: Logseq
- Analytics: Plausible
- Media: Jeyllyfin
- Uptime kuma
- Finance tracker: Actual Budget etc is too heavy so I built this. https://github.com/neberej/freemycash/
- Search: Whoogle? is kinda dead. Need alternative.
What is sad is that they used to be local files first note app and then they moved to sqlite citing some sync and performance issues.
While this sounds good deal, with this approach
- You have to charge total cost of subscription at once (1y or 2y),
- Still have to keep servers running for syncing, also you have think about cases where user syncing 1y of data in a single day.
- Have to keep people on the payroll for future developments.
(You are here thinking only in developer perspective.)
Yes, you are. You can find tons of purely local apps that monetize themselves with ads.
I looked over your careers page and see all of your positions are non-remote. Is this because of limitations of working on local-first software require you to be in-person? Or is this primarily a management issue?
So you can run 1000 local first app that syncs to a Dropbox for that 10/m in storage. And that storage is full B2C level ready to go not some low level s3 like primitive. Has auth, has supported has programs to sync.
Really most of the cloud cost is not needed.
Nobody is forcing anybody to make their games rely solely on online services. It's not a legal requirement, regulatory requirement, or anything else. It is a choice, like most things in software. To make the choice to rely on online services and then say "we'll have to spend money later to unfuck this!" is honestly short sided, pathetic, and nobody should accept it.
That being said, yes, i do believe *in the near/upcoming future* local-first, self-hosting and i will add more fair open source vendors will work! Well, at least, i hope so! I say that because Europe's recent desire to pivot away from the big U.s. tech companies, and towards more digital sovereignty - in my opinion - begins the foundational dependency for an ecosystem that will/could sustain self hosting, etc. The more that europe is able to pivot away from big tech, the more possibilty exists for more and varied non-big tech vendors manifest...and the more that Europe adopts open source, the more the possibility that usage and expertise of self-hosting grows....plus, for those who do not know how to, or simply do not wish to manage services themselves...well, in time i think Europe will have fostered a vast array of vendors who can provide such open source, digital services, but get paid a fair cost for providing fair value/services, etc. ...and, by the way, i say this all as a biased person in favor of open source AS WELL AS being an American. :-)
This calling back might amount to taking delivery. In a banking context, that is where the user takes delivery of whatever money and other property is in the account. In the cloud vendor case, this would be the user receiving a big Zip file with all the contents of the account.
Taking delivery is not always practical and is also not always desirable. Another option in a financial context is transferring accounts from one vendor to another: this can take the form of wiring money or sometimes involves a specialized transfer process. Transferring the account is probably way more useful for many cloud services.
This leads us to a hard thing about these services, though: portability. Say we delineate a clear property interest for user's in their cloud accounts and we delineate all of their rights. We have some good interests and some good rights; but what does it mean to take delivery of your Facebook friends? What does it mean to transfer your Facebook account from one place to another?
Anecdotally, I’ve never worked anywhere where the data formats are documented in any way other than a schema in code,
Not necessarily. I like local-first due to robust syncing via CRDTs, not because I somehow want to avoid cloud providers.
It’s a local-first platform that supports real-time sync with CRDTs at its core, making conflict resolution much easier to manage. Ditto is designed to handle offline-first use cases and peer-to-peer sync out of the box, so you don’t have to build a custom sync engine from scratch.
It supports a wide range of platforms including Swift, Kotlin (Android), Flutter/Dart, React Native, JavaScript (Web/Node), .NET (C#), C++, Java, and Rust. You can dive deeper into what it offers from the docs site: https://docs.ditto.live/home/about-ditto
Here is a good recap of the current players. https://www.localfirst.fm/landscape
It's also open source and has bindings for Dart, JS, Swift, C#, Kotlin, etc
First is that yeah, local first, but I also want concurrency. If it's just local first, you're right, any old sync will do. But I want more than that. I want to not have to think (a la dropbox, being slick). I want my wife and I to be able to make separate edits on our phones when we're in a dead zone.
Second is that sync works a lot better when it has deep knowledge of the data structure and semantics. Git and box both have significant shortcomings, but both exacerbated by the concurrency desire.
How do they do that without hitting the internet?
A notepad also isn't enough to correlate heart rate etc to specific exercises and plotting over time
It’s self reinforcing because those companies that get subscription revenue have both more revenue and higher valuations enabling more fund raising, causing them to beat out companies that do not follow this model. This is why local first software died.
This is what every "cloud file sharing" provider like Dropbox is doing. If there is a conflict, the version on the server is "the right one", and your locally conflicted file is copied on the side with some annotation in the file name.
Utopia. Unattainable. Self-determination of the individual has been consistently persecuted under all societal arrangements; communism and capitalism equally hate a citizen that wants to remain independent and self-sufficient.
Whenever it's possible to solve a business problem or political problem with a technical solution, that's usually a strong approach, because those problems are caused by an adversarial entity and the technical solution is to eliminate the adversarial entity's ability to defect.
Encryption is a great example of this if you are going to use a cloud service. Trying to protect your data with privacy policies and bureaucratic rules is a fool's errand because there are too many perverse incentives. The data is valuable, neither the customer nor the government can easily tell if the company is selling it behind their backs, it's also hard to tell if he provider has cheaped out on security until it's too late, etc.
But if it's encrypted on the client device and you can prove with math that the server has no access to the plaintext, you don't have to worry about any of that.
The trouble is sometimes you want the server to process the data and not just store it, and then the technical solution becomes, use your own servers.
I don't think that's quite correct. I think the authors fully acknowledge that the business case for local-first is not complexly solved and is a closely related problem. These issues need both a business and technical solution, and the paper proposes a set of characteristics of what a solution could look like.
It's also incorrect to suggest that local-first is an argument for decentralisation - Martin Kleppmann has explicitly stated that he doesn't think decentralised tech solves these issues in a way that could become mass market. He is a proponent of centralised standardised sync engines that enable the ideals of local-first. See his talk from Local-first conf last year: https://youtu.be/NMq0vncHJvU?si=ilsQqIAncq0sBW95
It is not only a business problem. I stay away from cloud based services not only because of subscription model, but also because I want my data to be safe.
When you send data to a cloud service, and that data is not encrypted locally before being sent to the cloud (a rare feature), it is not a question of if but when that data will be pwned.
I'm trying to imagine how this would be enforced when a company shutters and it's principals walk away.
This is not practical for data of any size. Prod migrations to a new database take months or even years if you want things to go smoothly. In a crisis you can do it in weeks but it can be really ugly, That applies even when moving between the same version of open source database, because there's a lot of variation between the cloud services themselves.
The best solution is to have the data in your own environment to begin with and just unplug. It's possible with bring-your-own-cloud management combined with open source.
My company operates a BYOC data product which means I have an economic interest in this approach. On the other hand I've seen it work, so I know it's possible.
Also some more pondering on local-first application development from a "few" (~10) years back can be found here: https://unhosted.org/
I should probably write a blog post, but I will say that I investigated power sync, electricSQL, livestore and powersync before. I briefly looked at jazz tools but wanted something a bit more structured.
I'm pretty impressed this far. I've actually been writing it with Vue and a community library. Permissions were a bit tricky, but once I figured it out it was simple. And I like their magic email login. And I like their dashboard/reply, but there are a few big changes I would make there to make it less fiddly.
I love that it's open source, and that if I want to, I could self host it.
As for the other options:
- jazz wasn't structured enough
- livestore came off as too fiddly with the event store, but it was appealing. That the dev tools are payealled was disappointing, but understandable
- electriSQL really only provided half a solution (read, not the write model
- couchDB / pouchDB wasn't structured enough for me, and I wanted better cross document support than was obvious / baked in.
- did not investigate zero really
EDIT: actually I wanted to point to the "landscape" link (in the top menu) but that URL is quite unergonomic.
Rust and JavaScript implementations, a handful of network strategies. It doesn't come with the free or paid offering that jazz.tools does, but it's pretty nice.
Also, so many of these selfhostable apps are web applications with a db, server and frontend, but for a lot of use cases (at least for me personally) you just use it on one machine and don't even need a "hosted" version or any kind of sync to another device. A completely local desktop program would suffice. For example I do personal accounting once a month on my computer – no need to have a web app running 24/7 somewhere else. I want to turn on the program, do my work, and then turn it off. While I can achieve that easily as a developer, most of the people can't. There seems to be a huge misalignment (for lack of a better word) between the amount of high-quality selfhostable FOSS alternatives and the amount of people that can actually use them. I think we need more projects like yours, where the goal is to close that gap.
I will definitely try to use selfhostblocks for a few things and try to contribute, keep it up!
Good point. Governments would do this if they really worked "for the people"
"Mechanically preventing wrongdoing from happening" can be a bit of a Shangri-La. What Tech can mechanically do is increase the cost of wrongdoing, or temporarily deflect attempts towards easier targets. But that by definition cannot "solve the problem for everyone" as there will always be a lowest hanging fruit remaining somewhere.
What contracts can do is help to reduce the demand for wrongdoing.
I view everyone flocking around Electron as proof of a failure on this front.
Spinners should not exist in a local first app.
Oh but it has (IMO).
> users today expect things like instant updates [...] constant bug fixes and patches
Nah, this is in reverse. With boxed software, the developer had to deliver an essentially bug-free product. Now, with easy updates technically possible, the developers have gone complacent, and deliver shit. That is why users expect bugfixes instantly. (And any enlightened user abhors unrequested features, as there are no features without regressions, and who wants regressions in any serious application?) The only tolerable online updates are security fixes.
> sync across devices, collaboration
This is a valid expectation, but its execution has been a train-wreck. Research, design and implementation should start with end-to-end encryption; the network architecture should be peer-to-peer (mesh, not centralized). What do we get instead? More centralization of control than ever, and less privacy and ownership than ever.
If files are insufficient, what data-structure would make modular sync possible for multiple applications in an OS?
And I’m not suggesting one doesn’t exist, I’m challenging to present a comprehensive solution, that probably involved operating systems.
> I want my wife and I to be able to make separate edits on our phones when we're in a dead zone.
Files do this.
There are other options for key storage, revoking group privileges, etc. It's an extensive topic, but the foundation is there, it just depends on your network and use cases.
"Sharing models" are totally irrelevant until the concept of self-determination is tolerated by the powerful (and they will never tolerate it). Accessing my data from multiple devices is totally secondary; I don't trust mobile endpoints to access my remote data in the first place.
>3. The network is optional
Ad SDKs usually allow caching ads for a period of time so that ads can still be shown while the device is temporarily offline.
When Apple joined the madness, all hopes where lost (that was a long time ago now, sight)
The business is doing alright, but what really keeps me going is that the app is something I genuinely wanted for myself. I use it all the time, it's always open in the background, so that keeps me motivated.
And while they spend a lot of time on CRDTs as a technical solution, I didn't see any suggestions for business model solutions.
In fact, if we had a business model solution--particularly one where your data is not tied to a specific cloud-vendor--then decentralization would not be needed.
I get that they are trying to solve multiple problems with CDRTs (such a latency and offline support) but in my experience (we did this with Groove in the early 2000s) the trade-offs are too big for average users.
Tech has improved since then, of course, so maybe it will work this time.
The experience has made me a big fan of self hosting.
My company does that with a few small vendors we've got for the source code we depend on.
Do you actually need anything special for CRDTs over a normal database? My understanding is the actual CRDT part is done "client side"
They're still a local-first note application. It's just slightly harder for you to edit your notes externally, and not even by that much - it's very easy to directly query (read and write) SQLite databases, and if you really cared you could have made a script to grab a note, export it to a temporary text file, allow you to edit it, then update the SQLite database.
> I can't version controlled backup and sync those files
You absolutely can - you can dump SQLite databases to text files that contain SQL queries that will restore the database that you can then backup and sync: https://stackoverflow.com/questions/75675/how-to-dump-the-da...
> then they moved to sqlite citing some sync and performance issues
Yes, that's because "plain text" files are bad for performance and harder to sync correctly. For people who (1) have over a hundred thousand notes they want to keep (like me) and (2) want maximum confidence that they're not going to lose years worth of work, that's incredibly important.
The devs made the right choice. You can always write scripts to interface with a SQLite database with an external editor. You can't take plain text files and magically make them as fast and durable as a database.
Example: I made a firefox extension that automatically fills forms using LLM. It's fully offline (except OPTIONALLY) the LLM part, optionally because it also supports Ollama locally.
Now the issue is that it's way too hard for most people to use: find the LLM to run, acquire it somehow (pay to run it online or download it to run in Ollama) gotta configure your API url, enter API key, save all of your details for form fulling locally in text files which you then have to backup and synchronize to other devices yourself.
The alternative would be: create account, give money, enter details and all is synced and backedup automatically accross devices, online LLM pre-selected and configured. Ready to go. No messing around with Ollama or openrouter, just go.
I don't know how to solve it in a local way that would be as user friendly as the subscription way would be.
Now things like cars and washing machines are a different story :p
It's sad because the dynamics and incentives around clear, up-front prices seem generally better than SaaS (more user control, less lock-in), but almost all commercial software morphs into SaaS thanks to a mix of psychology, culture and market dynamics.
There are other advantages to having your software and data managed by somebody else, but they are far less determinative than structural and pricing factors. In a slightly different world, it's not hard to imagine relatively expensive software up-front that comes with a smaller, optional (perhaps even third-party!) subscription service for data storage and syncing. It's a shame that we do not live in that world.
What if cloud platforms were more like brokerage firms? I can move my stocks from UBS to Fidelity by filling out a few forms and everything moves (somewhat) seamlessly.
My data should be the same way. I should be able to move all my data out of Google and move it to Microsoft with a few clicks without losing any documents or even my folder hierarchy. [Disclaimer: Maybe this is possible already and I'm just out of the loop. If so, though, extend to all SaaS vendors and all data.]
For something like data portability--being able to take my data to a different provider--that probably requires a technical solution.
But other problems, like enshittification, can't be solved technically. How do you technically prevent a cloud vendor from changing their pricing?
And you're right that the solution space is constrained by technical limits. If you want to share data with another user, you either need to trust a central authority or use a distributed protocol like blockchain. The former means you need to trust the central provider; the latter means you have to do your own key-management (how much money has been lost by people forgetting the keys to their wallet?)
There is no technical solution that gets you all the benefits of central plus all the benefits of local-first. There will always be trade-offs.
But that's the point of contracts, right? When a company shuts down, the contracts become part of the liabilities. E.g., if the contract says "you must pay each customer $1000 if we shut down" then the customers become creditors in a bankruptcy proceeding. It doesn't guarantee that they get all (or any) money, but their interests are negotiated by the bankruptcy judge.
Similarly, I can imagine a contract that says, "if the company shuts down, all our software becomes open source." Again, this would be managed by a bankruptcy judge who would mandate a release instead of allowing the creditors to gain the IP.
Another possibility is for the company to create a legal trust that is funded to keep the servers running (at a minimal level) for some specified amount of time.
And the biggest advantage I see of this perspective over the "technical problem" perspective is that assigning responsibility completely covers the problem space, while "hope that some clever math formula can magic the problem away" does not.
It seems like you'd need the latter to truly be immune to cloud-vendor problems. [But I may not understand how it works.]
That said, the app is currently designed for desktop use—mobile UX is still on our roadmap.
As for signup: it helps us track and bill users. Building our own auth system for local-first would’ve been a full project on its own. Until better options exist for authorization and billing in local-first apps, we’ll stick with a cloud signup flow.
Brightened reading this. If you have any feedback please let us know! We on the discord, and answer over on founders@instantdb
I mean, I did it, I built an app with a transparent background sync. Then I added a special page, 'sync center'.
In reality, mobile devices don't always have perfect network connections. Therefore, when the user is unsure whether the device is in sync or if the sync is in progress but encounters an obstacle, they might perceive the app as unreliable.
Banning spinners is dogmatic, not user-centric.
I think it boils down to provenance and concurrency. If we edit the same line a file, that's ba merge conflict when it really should be simple and something I shouldn't have to bother with. And when we do do the same line edit, I'd love to have provenance on that data.
Granted, those aren't local first thing exactly, but I think there will be apps that want all of that.
Originally the idea was to keep everything within the Obsidian UI so things like username/password didn't make sense (no password managers in Obsidian).
We initiate the OAuth2 login flow from within Obsidian. I guess we could add an extra click that takes you to our website first and then add support more auth methods from there. I don't really want it to feel like a web app though.
I'd love to hear your take. Which login method do you think is both simple and could be coherently used within Obsidian on all platforms?
Feel free to give it a try though, I’d love that! Also feel free to join the matrix channel UF you have any questions or just to get some updates.
Note that this does not even need two users: I hit this problem with a desktop and laptop and self-hosted NextCloud myself.
In general, a filesystem that actually stored both raw data (to fail-over to), but also a per-format event log, and maybe even app specific events (imagine a PNG changes, we could have any change recorded as raw bytes, generic bitmap image operation like "modify pixels at x,y to ..." and app-specific log like "gimp: apply sharpen filter on polygon area ...").
This would allow the other side to attempt to do the smartest sync it has (if it has a compatible version of gimp, it could decide to apply the filter, otherwise fall back to raw pixel changes if no conflicts, and then fall back to full file contents reconciliation).
Just like MIME handlers get registered, if file systems provided such change logs, some could have very advanced sync systems with this support from "filesystems".
It’s amazing how easily we can collaborate online nowadays. We use Google Docs to collaborate on documents, spreadsheets and presentations; in Figma we work together on user interface designs; we communicate with colleagues using Slack; we track tasks in Trello; and so on. We depend on these and many other online services, e.g. for taking notes, planning projects or events, remembering contacts, and a whole raft of business uses.
Today’s cloud apps offer big benefits compared to earlier generations of software: seamless collaboration, and being able to access data from any device. As we run more and more of our lives and work through these cloud apps, they become more and more critical to us. The more time we invest in using one of these apps, the more valuable the data in it becomes to us.
However, in our research we have spoken to a lot of creative professionals, and in that process we have also learned about the downsides of cloud apps.
When you have put a lot of creative energy and effort into making something, you tend to have a deep emotional attachment to it. If you do creative work, this probably seems familiar. (When we say “creative work,” we mean not just visual art, or music, or poetry — many other activities, such as explaining a technical topic, implementing an intricate algorithm, designing a user interface, or figuring out how to lead a team towards some goal are also creative efforts.)
In the process of performing that creative work, you typically produce files and data: documents, presentations, spreadsheets, code, notes, drawings, and so on. And you will want to keep that data: for reference and inspiration in the future, to include it in a portfolio, or simply to archive because you feel proud of it. It is important to feel ownership of that data, because the creative expression is something so personal.
Unfortunately, cloud apps are problematic in this regard. Although they let you access your data anywhere, all data access must go via the server, and you can only do the things that the server will let you do. In a sense, you don’t have full ownership of that data — the cloud provider does. In the words of a bumper sticker: “There is no cloud, it’s just someone else’s computer.”
When data is stored on “someone else’s computer”, that third party assumes a degree of control over that data. Cloud apps are provided as a service; if the service is unavailable, you cannot use the software, and you can no longer access your data created with that software. If the service shuts down, even though you might be able to export your data, without the servers there is normally no way for you to continue running your own copy of that software. Thus, you are at the mercy of the company providing the service.
Before web apps came along, we had what we might call “old-fashioned” apps: programs running on your local computer, reading and writing files on the local disk. We still use a lot of applications of this type today: text editors and IDEs, Git and other version control systems, and many specialized software packages such as graphics applications or CAD software fall in this category.
In old-fashioned apps, the data lives in files on your local disk, so you have full agency and ownership of that data: you can do anything you like, including long-term archiving, making backups, manipulating the files using other programs, or deleting the files if you no longer want them. You don’t need anybody’s permission to access your files, since they are yours. You don’t have to depend on servers operated by another company.
To sum up: the cloud gives us collaboration, but old-fashioned apps give us ownership. Can’t we have the best of both worlds?
We would like both the convenient cross-device access and real-time collaboration provided by cloud apps, and also the personal ownership of your own data embodied by “old-fashioned” software.
We believe that data ownership and real-time collaboration are not at odds with each other. It is possible to create software that has all the advantages of cloud apps, while also allowing you to retain full ownership of the data, documents and files you create.
We call this type of software local-first software, since it prioritizes the use of local storage (the disk built into your computer) and local networks (such as your home WiFi) over servers in remote datacenters.
In cloud apps, the data on the server is treated as the primary, authoritative copy of the data; if a client has a copy of the data, it is merely a cache that is subordinate to the server. Any data modification must be sent to the server, otherwise it “didn’t happen.” In local-first applications we swap these roles: we treat the copy of the data on your local device — your laptop, tablet, or phone — as the primary copy. Servers still exist, but they hold secondary copies of your data in order to assist with access from multiple devices. As we shall see, this change in perspective has profound implications.
Here are seven ideals we would like to strive for in local-first software.
Much of today’s software feels slower than previous generations of software. Even though CPUs have become ever faster, there is often a perceptible delay between some user input (e.g. clicking a button, or hitting a key) and the corresponding result appearing on the display. In previous work we measured the performance of modern software and analyzed why these delays occur.

Server-to-server round-trip times between AWS datacenters in various locations worldwide. Data from: Peter Bailis, Aaron Davidson, Alan Fekete, et al.: “Highly Available Transactions: Virtues and Limitations,” VLDB 2014.
With cloud apps, since the primary copy of the data is on a server, all data modifications, and many data lookups, require a round-trip to a server. Depending on where you live, the server may well be located on another continent, so the speed of light places a limit on how fast the software can be.
Local-first software is different: because it keeps the primary copy of the data on the local device, there is never a need for the user to wait for a request to a server to complete. All operations can be handled by reading and writing files on the local disk, and data synchronization with other devices happens quietly in the background.
While this by itself does not guarantee that the software will be fast, we expect that local-first software has the potential to respond near-instantaneously to user input, never needing to show you a spinner while you wait, and allowing you to operate with your data at your fingertips.
Users today rely on several computing devices to do their work, and modern applications must support such workflows. For example, users may capture ideas on the go using their smartphone, organize and think through those ideas on a tablet, and then type up the outcome as a document on their laptop.
This means that while local-first apps keep their data in local storage on each device, it is also necessary for that data to be synchronized across all of the devices on which a user does their work. Various data synchronization technologies exist, and we discuss them in detail in a later section.
Most cross-device sync services also store a copy of the data on a server, which provides a convenient off-site backup for the data. These solutions work quite well as long as each file is only edited by one person at a time. If several people edit the same file at the same time, conflicts may arise, which we discuss in the section on collaboration.
Personal mobile devices move through areas of varying network availability: unreliable coffee shop WiFi, while on a plane or on a train going through a tunnel, in an elevator or a parking garage. In developing countries or rural areas, infrastructure for Internet access is sometimes patchy. While traveling internationally, many mobile users disable cellular data due to the cost of roaming. Overall, there is plenty of need for offline-capable apps, such as for researchers or journalists who need to write while in the field.
“Old-fashioned” apps work fine without an Internet connection, but cloud apps typically don’t work while offline. For several years the Offline First movement has been encouraging developers of web and mobile apps to improve offline support, but in practice it has been difficult to retrofit offline support to cloud apps, because tools and libraries designed for a server-centric model do not easily adapt to situations in which users make edits while offline.
Since local-first applications store the primary copy of their data in each device’s local filesystem, the user can read and write this data anytime, even while offline. It is then synchronized with other devices sometime later, when a network connection is available. The data synchronization need not necessarily go via the Internet: local-first apps could also use Bluetooth or local WiFi to sync data to nearby devices.
Moreover, for good offline support it is desirable for the software to run as a locally installed executable on your device, rather than a tab in a web browser. For mobile apps it is already standard that the whole app is downloaded and installed before it is used.
Collaboration typically requires that several people contribute material to a document or file. However, in old-fashioned software it is problematic for several people to work on the same file at the same time: the result is often a conflict. In text files such as source code, resolving conflicts is tedious and annoying, and the task quickly becomes very difficult or impossible for complex file formats such as spreadsheets or graphics documents. Hence, collaborators may have to agree up front who is going to edit a file, and only have one person at a time who may make changes.

A “conflicted copy” on Dropbox. The user must merge the changes manually.

In Evernote, if a note is changed concurrently, it is moved to a “conflicting changes” notebook, and there is nothing to support the user in resolving the situation — not even a facility to compare the different versions of a note.

In Git and other version control systems, several people may modify the same file in different commits. Combining those changes often results in merge conflicts, which can be resolved using specialized tools (such as DiffMerge, shown here). These tools are primarily designed for line-oriented text files such as source code; for other file formats, tool support is much weaker.
On the other hand, cloud apps such as Google Docs have vastly simplified collaboration by allowing multiple users to edit a document simultaneously, without having to send files back and forth by email and without worrying about conflicts. Users have come to expect this kind of seamless real-time collaboration in a wide range of applications.
In local-first apps, our ideal is to support real-time collaboration that is on par with the best cloud apps today, or better. Achieving this goal is one of the biggest challenges in realizing local-first software, but we believe it is possible: in a later section we discuss technologies that enable real-time collaboration in a local-first setting.
Moreover, we expect that local-first apps can support various workflows for collaboration. Besides having several people edit the same document in real-time, it is sometimes useful for one person to tentatively propose changes that can be reviewed and selectively applied by someone else. Google Docs supports this workflow with its suggesting mode, and pull requests serve this purpose in GitHub.

In Google Docs, collaborators can either edit the document directly, or they can suggest changes, which can then be accepted or rejected by the document owner.

The collaboration workflow on GitHub is based on pull requests. A user may change multiple source files in multiple commits, and submit them as a proposed change to a project. Other users may review and amend the pull request before it is finally merged or rejected.
An important aspect of data ownership is that you can continue accessing the data for a long time in the future. When you do some work with local-first software, your work should continue to be accessible indefinitely, even after the company that produced the software is gone.

Cuneiform script on clay tablet, ca. 3000 BCE. Image from Wikimedia Commons
“Old-fashioned” apps continue to work forever, as long as you have a copy of the data and some way of running the software. Even if the software author goes bust, you can continue running the last released version of the software. Even if the operating system and the computer it runs on become obsolete, you can still run the software in a virtual machine or emulator. As storage media evolve over the decades, you can copy your files to new storage media and continue to access them.
On the other hand, cloud apps depend on the service continuing to be available: if the service is unavailable, you cannot use the software, and you can no longer access your data created with that software. This means you are betting that the creators of the software will continue supporting it for a long time — at least as long as you care about the data.
Although there does not seem to be a great danger of Google shutting down Google Docs anytime soon, popular products do sometimes get shut down or lose data, so we know to be careful. And even with long-lived software there is the risk that the pricing or features change in a way you don’t like, and with a cloud app, continuing to use the old version is not an option — you will be upgraded whether you like it or not.
Local-first software enables greater longevity because your data, and the software that is needed to read and modify your data, are all stored locally on your computer. We believe this is important not just for your own sake, but also for future historians who will want to read the documents we create today. Without longevity of our data, we risk creating what Vint Cerf calls a “digital Dark Age”.
Some file formats (such as plain text, JPEG, and PDF) are so ubiquitous that they will probably be readable for centuries to come. The US Library of Congress also recommends XML, JSON, or SQLite as archival formats for datasets. However, in order to read less common file formats and to preserve interactivity, you need to be able to run the original software (if necessary, in a virtual machine or emulator). Local-first software enables this.
One problem with the architecture of cloud apps is that they store all the data from all of their users in a centralized database. This large collection of data is an attractive target for attackers: a rogue employee, or a hacker who gains access to the company’s servers, can read and tamper with all of your data. Such security breaches are sadly terrifyingly common, and with cloud apps we are unfortunately at the mercy of the provider.
While Google has a world-class security team, the sad reality is that most companies do not. And while Google is good at defending your data against external attackers, the company internally is free to use your data in a myriad ways, such as feeding your data into its machine learning systems.
Maybe you feel that your data would not be of interest to any attacker. However, for many professions, dealing with sensitive data is an important part of their work. For example, medical professionals handle sensitive patient data, investigative journalists handle confidential information from sources, governments and diplomatic representatives conduct sensitive negotiations, and so on. Many of these professionals cannot use cloud apps due to regulatory compliance and confidentiality obligations.
Local-first apps, on the other hand, have better privacy and security built in at the core. Your local devices store only your own data, avoiding the centralized cloud database holding everybody’s data. Local-first apps can use end-to-end encryption so that any servers that store a copy of your files only hold encrypted data that they cannot read.
With cloud apps, the service provider has the power to restrict user access: for example, in October 2017, several Google Docs users were locked out of their documents because an automated system incorrectly flagged these documents as abusive. In local-first apps, the ownership of data is vested in the user.
To disambiguate “ownership” in this context: we don’t mean it in the legal sense of intellectual property. A word processor, for example, should be oblivious to the question of who owns the copyright in the text being edited. Instead we mean ownership in the sense of user agency, autonomy, and control over data. You should be able to copy and modify data in any way, write down any thought, and no company should restrict what you are allowed to do.
In cloud apps, the ways in which you can access and modify your data are limited by the APIs, user interfaces, and terms of service of the service provider. With local-first software, all of the bytes that comprise your data are stored on your own device, so you have the freedom to process this data in arbitrary ways.
With data ownership comes responsibility: maintaining backups or other preventative measures against data loss, protecting against ransomware, and general organizing and managing of file archives. For many professional and creative users, as introduced in the introduction, we believe that the trade-off of more responsibility in exchange for more ownership is desirable. Consider a significant personal creation, such as a PhD thesis or the raw footage of a film. For these you might be willing to take responsibility for storage and backups in order to be certain that your data is safe and fully under your control.
We believe professional and creative users deserve software that realizes the local-first goals, helping them collaborate seamlessly while also allowing them to retain full ownership of their work. If we can give users these qualities in the software they use to do their most important work, we can help them be better at what they do, and potentially make a significant difference to many people’s professional lives.
However, while the ideals of local-first software may resonate with you, you may still be wondering how achievable they are in practice. Are they just utopian thinking?
In the remainder of this article we discuss what it means to realize local-first software in practice. We look at a wide range of existing technologies and break down how well they satisfy the local-first ideals. In the following tables, ✓ means the technology meets the ideal, — means it partially meets the ideal, and ✗ means it does not meet the ideal.
As we shall see, many technologies satisfy some of the goals, but none are able to satisfy them all. Finally, we examine a technique from the cutting edge of computer science research that might be a foundational piece in realizing local-first software in the future.
Let’s start by examining software from the end user’s perspective, and break down how well different software architectures meet the seven ideals for local-first software. In the next section we compare storage technologies and APIs that are used by software engineers to build applications.
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| Files + email attachments | ✓ | — | ✓ | ✗ | ✓ | — | ✓ |
Viewed through the lens of our seven goals, traditional files have many desirable properties: they can be viewed and edited offline, they give full control to users, and they can readily be backed up and preserved for the long term. Software relying on local files also has the potential to be very fast.
However, accessing files from multiple devices is trickier. It is possible to transfer a file across devices using various technologies:
Of these, email attachments are probably the most common sharing mechanism, especially among users who are not technical experts. Attachments are easy to understand and trustworthy. Once you have a copy of a document, it does not spontaneously change: if you view an email six months later, the attachments are still there in their original form. Unlike a web app, an attachment can be opened without any additional login process.
The weakest point of email attachments is collaboration. Generally, only one person at a time can make changes to a file, otherwise a difficult manual merge is required. File versioning quickly becomes messy: a back-and-forth email thread with attachments often leads to filenames such as Budget draft 2 (Jane's version) final final 3.xls.
Nevertheless, for apps that want to incorporate local-first ideas, a good starting point is to offer an export feature that produces a widely-supported file format (e.g. plain text, PDF, PNG, or JPEG) and allows it to be shared e.g. via email attachment, Slack, or WhatsApp.
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| Google Docs | — | ✓ | — | ✓ | — | ✗ | — |
| Trello | — | ✓ | — | ✓ | — | ✗ | ✗ |
| ✗ | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ |
At the opposite end of the spectrum are pure web apps, where the user’s local software (web browser or mobile app) is a thin client and the data storage resides on a server. The server typically uses a large-scale database in which the data of millions of users are all mixed together in one giant collection.
Web apps have set the standard for real-time collaboration. As a user you can trust that when you open a document on any device, you are seeing the most current and up-to-date version. This is so overwhelmingly useful for team work that these applications have become dominant. Even traditionally local-only software like Microsoft Office is making the transition to cloud services, with Office 365 eclipsing locally-installed Office as of 2017.
With the rise of remote work and distributed teams, real-time collaborative productivity tools are becoming even more important. Ten users on a team video call can bring up the same Trello board and each make edits on their own computer while simultaneously seeing what other users are doing.
The flip side to this is a total loss of ownership and control: the data on the server is what counts, and any data on your client device is unimportant — it is merely a cache. Most web apps have little or no support for offline working: if your network hiccups for even a moment, you are locked out of your work mid-sentence.

If Google Docs detects that it is offline, it blocks editing of the document.
A few of the best web apps hide the latency of server communication using JavaScript, and try to provide limited offline support (for example, the Google Docs offline plugin). However, these efforts appear retrofitted to an application architecture that is fundamentally centered on synchronous interaction with a server. Users report mixed results when trying to work offline.

A negative user review of the Google Docs offline extension.
Some web apps, for example Milanote and Figma, offer installable desktop clients that are essentially repackaged web browsers. If you try to use these clients to access your work while your network is intermittent, while the vendor’s servers are experiencing an outage, or after the vendor has been acquired and shut down, it becomes clear that your work was never truly yours.

The Figma desktop client in action.
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| Dropbox | ✓ | — | — | ✗ | ✓ | — | ✓ |
Cloud-based file sync products like Dropbox, Google Drive, Box, or OneDrive make files available on multiple devices. On desktop operating systems (Windows, Linux, Mac OS) these tools work by watching a designated folder on the local file system. Any software on your computer can read and write files in this folder, and whenever a file is changed on one computer, it is automatically copied to all of your other computers.
As these tools use the local filesystem, they have many attractive properties: access to local files is fast, and working offline is no problem (files edited offline are synced the next time an Internet connection is available). If the sync service were shut down, your files would still remain unharmed on your local disk, and it would be easy to switch to a different syncing service. If your computer’s hard drive fails, you can restore your work simply by installing the app and waiting for it to sync. This provides good longevity and control over your data.
However, on mobile platforms (iOS and Android), Dropbox and its cousins use a completely different model. The mobile apps do not synchronize an entire folder — instead, they are thin clients that fetch your data from a server one file at a time, and by default they do not work offline. There is a “Make available offline” option, but you need to remember to invoke it ahead of going offline, it is clumsy, and only works when the app is open. The Dropbox API is also very server-centric.

Users of the Dropbox mobile app spend a lot of time looking at spinners, a stark contrast to the at-your-fingertips feeling of the Dropbox desktop product.
The weakest point of file sync products is the lack of real-time collaboration: if the same file is edited on two different devices, the result is a conflict that needs to be merged manually, as discussed previously. The fact that these tools synchronize files in any format is both a strength (compatibility with any application) and a weakness (inability to perform format-specific merges).
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| Git+GitHub | ✓ | — | ✓ | — | ✓ | — | ✓ |
Git and GitHub are primarily used by software engineers to collaborate on source code. They are perhaps the closest thing we have to a true local-first software package: compared to server-centric version control systems such as Subversion, Git works fully offline, it is fast, it gives full control to users, and it is suitable for long-term preservation of data. This is the case because a Git repository on your local filesystem is a primary copy of the data, and is not subordinate to any server.
A repository hosting service like GitHub enables collaboration around Git repositories, accessing data from multiple devices, as well as providing a backup and archival location. Support for mobile devices is currently weak, although Working Copy is a promising Git client for iOS. GitHub stores repositories unencrypted; if stronger privacy is required, it is possible for you to run your own repository server.
We think the Git model points the way toward a future for local-first software. However, as it currently stands, Git has two major weaknesses:
It’s interesting to note that most software engineers have been reluctant to embrace cloud software for their editors, IDEs, runtime environments, and build tools. In theory, we might expect this demographic of sophisticated users to embrace newer technologies sooner than other types of users. But if you ask an engineer why they don’t use a cloud-based editor like Cloud9 or Repl.it, or a runtime environment like Colaboratory, the answers will usually include “it’s too slow” or “I don’t trust it” or “I want my code on my local system.” These sentiments seem to reflect some of the same motivations as local-first software. If we as developers want these things for ourselves and our work, perhaps we might imagine that other types of creative professionals would want these same qualities for their own work.
Now that we have examined the user experience of a range of applications through the lens of the local-first ideals, let’s switch mindsets to that of an application developer. If you are creating an app and want to offer users some or all of the local-first experience, what are your options for data storage and synchronization infrastructure?
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| Web apps | ✗ | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ |
A web app in its purest form is usually a Rails, Django, PHP, or Node.js program running on a server, storing its data in a SQL or NoSQL database, and serving web pages over HTTPS. All of the data is on the server, and the user’s web browser is only a thin client.
This architecture offers many benefits: zero installation (just visit a URL), and nothing for the user to manage, as all data is stored and managed in one place by the engineering and DevOps professionals who deploy the application. Users can access the application from all of their devices, and colleagues can easily collaborate by logging in to the same application.
On the other hand, a web app that needs to perform a request to a server for every user action is going to be slow. It is possible to hide the round-trip times in some cases by using client-side JavaScript, but these approaches quickly break down if the user’s internet connection is unstable.
Despite many efforts to make web browsers more offline-friendly (manifests, localStorage, service workers, and Progressive Web Apps, among others), the architecture of web apps remains fundamentally server-centric. Offline support is an afterthought in most web apps, and the result is accordingly fragile. In many web browsers, if the user clears their cookies, all data in local storage is also deleted; while this is not a problem for a cache, it makes the browser’s local storage unsuitable for storing data of any long-term importance.
Relying on third-party web apps also scores poorly in terms of longevity, privacy, and user control. It is possible to improve these properties if the web app is open source and users are willing to self-host their own instances of the server. However, we believe that self-hosting is not a viable option for the vast majority of users who do not want to become system administrators; moreover, most web apps are closed source, ruling out this option entirely.
All in all, we speculate that web apps will never be able to provide all the local-first properties we are looking for, due to the fundamental thin-client nature of the platform. By choosing to build a web app, you are choosing the path of data belonging to you and your company, not to your users.
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| Thick client | ✓ | — | ✓ | ✗ | — | ✗ | ✗ |
iOS and Android apps are locally installed software, with the entire app binary downloaded and installed before the app is run. Many apps are nevertheless thin clients, similarly to web apps, which require a server in order to function (for example, Twitter, Yelp, or Facebook). Without a reliable Internet connection, these apps give you spinners, error messages, and unexpected behavior.
However, there is another category of mobile apps that are more in line with the local-first ideals. These apps store data on the local device in the first instance, using a persistence layer like SQLite, Core Data, or just plain files. Some of these (such as Clue or Things) started life as a single-user app without any server, and then added a cloud backend later, as a way to sync between devices or share data with other users.
These thick-client apps have the advantage of being fast and working offline, because the server sync happens in the background. They generally continue working if the server is shut down. The degree to which they offer privacy and user control over data varies depending on the app in question.
Things get more difficult if the data may be modified on multiple devices or by multiple collaborating users. The developers of mobile apps are generally experts in end-user app development, not in distributed systems. We have seen multiple app development teams writing their own ad-hoc diffing, merging, and conflict resolution algorithms, and the resulting data sync solutions are often unreliable and brittle. A more specialized storage backend, as discussed in the next section, can help.
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| Firebase, CloudKit, Realm | — | ✓ | ✓ | — | ✗ | ✗ | ✗ |
Firebase is the most successful of mobile backend-as-a-service options. It is essentially a local on-device database combined with a cloud database service and data synchronization between the two. Firebase allows sharing of data across multiple devices, and it supports offline use. However, as a proprietary hosted service, we give it a low score for privacy and longevity.
Firebase offers a great experience for you, the developer: you can view, edit, and delete data in a free-form way in the Firebase console. But the user does not have a comparable way of accessing, manipulating and managing their data, leaving the user with little ownership and control.

The Firebase console: great for developers, off-limits for the end user.
Apple’s CloudKit offers a Firebase-like experience for apps willing to limit themselves to the iOS and Mac platforms. It is a key-value store with syncing, good offline capabilities, and it has the added benefit of being built into the platform (thereby sidestepping the clumsiness of users having to create an account and log in). It’s a great choice for indie iOS developers and is used to good effect by tools like Ulysses, Bear, Overcast, and many more.

With one checkbox, Ulysses syncs work across all of the user’s connected devices, thanks to its use of CloudKit.
Another project in this vein is Realm. This persistence library for iOS gained popularity compared to Core Data due to its cleaner API. The client-side library for local persistence is called Realm Database, while the associated Firebase-like backend service is called Realm Object Server. Notably, the object server is open source and self-hostable, which reduces the risk of being locked in to a service that might one day disappear.
Mobile apps that treat the on-device data as the primary copy (or at least more than a disposable cache), and use sync services like Firebase or iCloud, get us a good bit of the way toward local-first software.
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| CouchDB | — | — | ✓ | ✗ | — | — | — |
CouchDB is a database that is notable for pioneering a multi-master replication approach: several machines each have a fully-fledged copy of the database, each replica can independently make changes to the data, and any pair of replicas can synchronize with each other to exchange the latest changes. CouchDB is designed for use on servers; Cloudant provides a hosted version; PouchDB and Hoodie are sibling projects that use the same sync protocol but are designed to run on end-user devices.
Philosophically, CouchDB is closely aligned to the local-first principles, as evidenced in particular by the CouchDB book, which provides an excellent introduction to relevant topics such as distributed consistency, replication, change notifications, and multiversion concurrency control.
While CouchDB/PouchDB allow multiple devices to concurrently make changes to a database, these changes lead to conflicts that need to be explicitly resolved by application code. This conflict resolution code is difficult to write correctly, making CouchDB impractical for applications with very fine-grained collaboration, like in Google Docs, where every keystroke is potentially an individual change.
In practice, the CouchDB model has not been widely adopted. Various reasons have been cited for this: scalability problems when a separate database per user is required; difficulty embedding the JavaScript client in native apps on iOS and Android; the problem of conflict resolution; the unfamiliar MapReduce model for performing queries; and more. All in all, while we agree with much of the philosophy behind CouchDB, we feel that the implementation has not been able to realize the local-first vision in practice.
As we have shown, none of the existing data layers for application development fully satisfy the local-first ideals. Thus, three years ago, our lab set out to search for a solution that gives seven green checkmarks.
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| ??? | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
We have found some technologies that appear to be promising foundations for local-first ideals. Most notably are the family of distributed systems algorithms called Conflict-free Replicated Data Types (CRDTs).
CRDTs emerged from academic computer science research in 2011. They are general-purpose data structures, like hash maps and lists, but the special thing about them is that they are multi-user from the ground up.
Every application needs some data structures to store its document state. For example, if your application is a text editor, the core data structure is the array of characters that make up the document. If your application is a spreadsheet, the data structure is a matrix of cells containing text, numbers, or formulas referencing other cells. If it is a vector graphics application, the data structure is a tree of graphical objects such as text objects, rectangles, lines, and other shapes.
If you are building a single-user application, you would maintain those data structures in memory using model objects, hash maps, lists, records/structs and the like. If you are building a collaborative multi-user application, you can swap out those data structures for CRDTs.

Two devices initially have the same to-do list. On device 1, a new item is added to the list using the .push() method, which appends a new item to the end of a list. Concurrently, the first item is marked as done on device 2. After the two devices communicate, the CRDT automatically merges the states so that both changes take effect.
The diagram above shows an example of a to-do list application backed by a CRDT with a JSON data model. Users can view and modify the application state on their local device, even while offline. The CRDT keeps track of any changes that are made, and syncs the changes with other devices in the background when a network connection is available.
If the state was concurrently modified on different devices, the CRDT merges those changes. For example, if users concurrently add new items to the to-do list on different devices, the merged state contains all of the added items in a consistent order. Concurrent changes to different objects can also be merged easily. The only type of change that a CRDT cannot automatically resolve is when multiple users concurrently update the same property of the same object; in this case, the CRDT keeps track of the conflicting values, and leaves it to be resolved by the application or the user.
Thus, CRDTs have some similarity to version control systems like Git, except that they operate on richer data types than text files. CRDTs can sync their state via any communication channel (e.g. via a server, over a peer-to-peer connection, by Bluetooth between local devices, or even on a USB stick). The changes tracked by a CRDT can be as small as a single keystroke, enabling Google Docs-style real-time collaboration. But you could also collect a larger set of changes and send them to collaborators as a batch, more like a pull request in Git. Because the data structures are general-purpose, we can develop general-purpose tools for storage, communication, and management of CRDTs, saving us from having to re-implement those things in every single app.
For a more technical introduction to CRDTs we suggest:
Ink & Switch has developed an open-source, JavaScript CRDT implementation called Automerge. It is based on our earlier research on JSON CRDTs. We have then combined Automerge with the Dat networking stack to form Hypermerge. We do not claim that these libraries fully realize local-first ideals — more work is still required.
However, based on our experience with them, we believe that CRDTs have the potential to be a foundation for a new generation of software. Just as packet switching was an enabling technology for the Internet and the web, or as capacitive touchscreens were an enabling technology for smartphones, so we think CRDTs may be the foundation for collaborative software that gives users full ownership of their data.
While academic research has made good progress designing the algorithms for CRDTs and verifying their theoretical correctness, there is so far relatively little industrial use of these technologies. Moreover, most industrial CRDT use has been in server-centric computing, but we believe this technology has significant potential in client-side applications for creative work.
This was the motivation for our lab to embark on a series of experimental prototypes with collaborative, local-first applications built on CRDTs. Each prototype offered an end-user experience modeled after an existing app for creative work such as Trello, Figma, or Milanote.
These experiments explored questions in three areas:
We built three prototypes using Electron, JavaScript, and React. This gave us the rapid development capability of web technologies while also giving our users a piece of software they can download and install, which we discovered is an important part of the local-first feeling of ownership.
Trellis is a Kanban board modeled after the popular Trello project management software.

Trellis offers a Trello-like experience with local-first software. The change history on the right reflects changes made by all users active in the document.
On this project we experimented with WebRTC for the network communication layer.
On the user experience side, we designed a rudimentary “change history” inspired by Git and Google Docs’ “See New Changes” that allows users to see the operations on their Kanban board. This includes stepping back in time to view earlier states of the document.
Watch Trellis in action with the demo video or download a release and try it yourself.
Pixelpusher is a collaborative drawing program, bringing a Figma-like real-time experience to Javier Valencia’s Pixel Art to CSS.
![]()
Drawing together in real-time. A URL at the top offers a quick way to share this document with other users. The “Versions” panel on the right shows all branches of the current document. The arrow buttons offer instant merging between branches.
On this project we experimented with network communication via peer-to-peer libraries from the Dat project.
User experience experiments include URLs for document sharing, a visual branch/merge facility inspired by Git, a conflict-resolution mechanism that highlights conflicted pixels in red, and basic user identity via user-drawn avatars.
Read the full project report or download a release to try it yourself.
PushPin is a mixed media canvas workspace similar to Miro or Milanote. As our third project built on Automerge, it’s the most fully-realized of these three. Real use by our team and external test users put more strain on the underlying data layer.

PushPin’s canvas mixes text, images, discussion threads, and web links. Users see each other via presence avatars in the toolbar, and navigate between their own documents using the URL bar.
PushPin explored nested and connected shared documents, varied renderers for CRDT documents, a more advanced identity system that included an “outbox” model for sharing, and support for sharing ephemeral data such as selection highlights.
Watch the PushPin demo video or download a release and try it yourself.
Our goal in developing the three prototypes Trellis, Pixelpusher and PushPin was to evaluate the technology viability, user experience, and developer experience of local-first software and CRDTs. We tested the prototypes by regularly using them within the development team (consisting of five members), reflecting critically on our experiences developing the software, and by conducting individual usability tests with approximately ten external users. The external users included professional designers, product managers, and software engineers. We did not follow a formal evaluation methodology, but rather took an exploratory approach to discovering the strengths and weaknesses of our prototypes.
In this section we outline the lessons we learned from building and using these prototypes. While these findings are somewhat subjective, we believe they nevertheless contain valuable insights, because we have gone further than other projects down the path towards production-ready local-first applications based on CRDTs.
CRDT technology works.
From the beginning we were pleasantly surprised by the reliability of Automerge. App developers on our team were able to integrate the library with relative ease, and the automatic merging of data was almost always straightforward and seamless.
The user experience with offline work is splendid.
The process of going offline, continuing to work for as long as you want, and then reconnecting to merge changes with colleagues worked well. While other applications on the system threw up errors (“offline! warning!”) and blocked the user from working, the local-first prototypes function normally regardless of network status. Unlike browser-based systems, there is never any anxiety about whether the application will work or the data will be there when the user needs it. This gives the user a feeling of ownership over their tools and their work, just as we had hoped.
Developer experience is viable when combined with Functional Reactive Programming (FRP).
The FRP model of React fits well with CRDTs. A data layer based on CRDTs means the user’s document is simultaneously getting updates from the local user (e.g. as they type into a text document) but also from the network (as other users and other devices make changes to the document).
Because the FRP model reliably synchronizes the visible state of the application with the underlying state of the shared document, the developer is freed from the tedious work of tracking changes arriving from other users and reconciling them with the current view. Also, by ensuring all changes to the underlying state are made through a single function (a “reducer”), it’s easy to ensure that all relevant local changes are sent to other users.
The result of this model was that all of our prototypes realized real-time collaboration and full offline capability with little effort from the application developer. This is a significant benefit as it allows app developers to focus on their application rather than the challenges of data distribution.
Conflicts are not as significant a problem as we feared.
We are often asked about the effectiveness of automatic merging, and many people assume that application-specific conflict resolution mechanisms are required. However, we found that users surprisingly rarely encounter conflicts in their work when collaborating with others, and that generic resolution mechanisms work well. The reasons for this are:
When different users concurrently modify different parts of the document state, Automerge will merge these changes cleanly without difficulty. With the Kanban app, for example, one user could post a comment on a card and another could move it to another column, and the merged result will reflect both of these changes. Conflicts arise only if users concurrently modify the same property of the same object: for example, if two users concurrently change the position of the same image object on a canvas. In such cases, it is often arbitrary how they are resolved and satisfactory either way.
Automerge’s data structures come with a small set of default resolution policies for concurrent changes. In principle, one might expect different applications to require different merge semantics. However, in all the prototypes we developed, we found that the default merge semantics to be sufficient, and we have so far not identified any case requiring customised semantics. We hypothesise that this is the case generally, and we hope that future research will be able to further test this hypothesis.
Visualizing document history is important.
In a distributed collaborative system another user can deliver any number of changes to you at any moment. Unlike centralized systems, where servers mediate change, local-first applications need to find their own solutions to these problems. Without the right tools, it can be difficult to understand how a document came to look the way it does, what versions of the document exist, or where contributions came from.
In the Trellis project we experimented with a “time travel” interface, allowing a user to move back in time to see earlier states of a merged document, and automatically highlighting recently changed elements as changes are received from other users. The ability to traverse a potentially complex merged document history in a linear fashion helps to provide context and could become a universal tool for understanding collaboration.
URLs are a good mechanism for sharing.
We experimented with a number of mechanisms for sharing documents with other users, and found that a URL model, inspired by the web, makes the most sense to users and developers. URLs can be copied and pasted, and shared via communication channels such as email or chat. Access permissions for documents beyond secret URLs remain an open research question.
Peer-to-peer systems are never fully “online” or “offline” and it can be hard to reason about how data moves in them.
A traditional centralized system is generally “up” or “down,” states defined by each client by their ability to maintain a steady network connection to the server. The server determines the truth of a given piece of data.
In a decentralized system, we can have a kaleidoscopic complexity to our data. Any user may have a different perspective on what data they either have, choose to share, or accept. For example, one user’s edits to a document might be on their laptop on an airplane; when the plane lands and the computer reconnects, those changes are distributed to other users. Other users might choose to accept all, some, or none of those changes to their version of the document.
Different versions of a document can lead to confusion. As with a Git repository, what a particular user sees in the “master” branch is a function of the last time they communicated with other users. Newly arriving changes might unexpectedly modify parts of the document you are working on, but manually merging every change from every user is tedious. Decentralized documents enable users to be in control over their own data, but further study is needed to understand what this means in practical user-interface terms.
CRDTs accumulate a large change history, which creates performance problems.
Our team used PushPin for “real” documents such as sprint planning. Performance and memory/disk usage quickly became a problem because CRDTs store all history, including character-by-character text edits. These pile up, but can’t easily be truncated because it’s impossible to know when someone might reconnect to your shared document after six months away and need to merge changes from that point forward.
We continue to optimize Automerge, but this is a major area of ongoing work.
Network communication remains an unsolved problem.
CRDT algorithms provide only for the merging of data, but say nothing about how different users’ edits arrive on the same physical computer.
In these experiments we tried network communication via WebRTC; a “sneakernet” implementation of copying files around with Dropbox and USB keys; possible use of the IPFS protocols; and eventually settled on the Hypercore peer-to-peer libraries from Dat.
CRDTs do not require a peer-to-peer networking layer; using a server for communication is fine for CRDTs. However, to fully realize the longevity goal of local-first software, we want applications to outlive any backend services managed by their vendors, so a decentralized solution is the logical end goal.
The use of P2P technologies in our prototypes yielded mixed results. On one hand, these technologies are nowhere near production-ready: NAT traversal, in particular, is unreliable depending on the particular router or network topology where the user is currently connected. But the promise suggested by P2P protocols and the Decentralized Web community is substantial. Live collaboration between computers without Internet access feels like magic in a world that has come to depend on centralized APIs.
Cloud servers still have their place for discovery, backup, and burst compute.
A real-time collaborative prototype like PushPin lets users share their documents with other users without an intermediating server. This is excellent for privacy and ownership, but can result in situations where a user shares a document, and then closes their laptop lid before the other user has connected. If the users are not online at the same time, they cannot connect to each other.
Servers thus have a role to play in the local-first world — not as central authorities, but as “cloud peers” that support client applications without being on the critical path. For example, a cloud peer that stores a copy of the document, and forwards it to other peers when they come online, could solve the closed-laptop problem above.
Similarly, cloud peers could be:
The key difference between traditional systems and local-first systems is not an absence of servers, but a change in their responsibilities: they are in a supporting role, not the source of truth.
These experiments suggest that local-first software is possible. Collaboration and ownership are not at odds with each other — we can get the best of both worlds, and users can benefit.
However, the underlying technologies are still a work in progress. They are good for developing prototypes, and we hope that they will evolve and stabilize in the coming years, but realistically, it is not yet advisable to replace a proven product like Firebase with an experimental project like Automerge in a production setting today.
If you believe in a local-first future, as we do, what can you (and all of us in the technology field) do to move us toward it? Here are some suggestions.
Local-first software has benefited tremendously from recent research into distributed systems, including CRDTs and peer-to-peer technologies. The current research community is making excellent progress in improving the performance and power of CRDTs and we eagerly await further results from that work. Still, there are interesting opportunities for further work.
Most CRDT research operates in a model where all collaborators immediately apply their edits to a single version of a document. However, practical local-first applications require more flexibility: users must have the freedom to reject edits made by another collaborator, or to make private changes to a version of the document that is not shared with others. A user might want to apply changes speculatively or reformat their change history. These concepts are well understood in the distributed source control world as “branches,” “forks,” “rebasing,” and so on. There is little work to date on understanding the algorithms and programming models for collaboration in situations where multiple document versions and branches exist side-by-side.
We see further interesting problems around types, schema migrations, and compatibility. Different collaborators may be using different versions of an application, potentially with different features. As there is no central database server, there is no authoritative “current” schema for the data. How can we write software so that varying application versions can safely interoperate, even as data formats evolve? This question has analogues in cloud-based API design, but a local-first setting provides additional challenges.
For centralized systems, there are ample examples in the field today of applications that indicate their “sync” state with a server. Decentralized systems have a whole host of interesting new opportunities to explore user interface challenges.
We hope researchers will consider how to communicate online and offline states, or available and unavailable states for systems where any other user may hold a different copy of data. How should we think about connectivity when everyone is a peer? What does it mean to be “online” when we can collaborate directly with other nodes without access to the wider Internet?

The “railroad track” model, as used in GitX for visualizing the structure of source code history in a Git repository.
When every document can develop a complex version history, simply through daily operation, an acute problem arises: how do we communicate this version history to users? How should users think about versioning, share and accept changes, and understand how their documents came to be a certain way when there is no central source of truth? Today there are two mainstream models for change management: a source-code model of diffs and patches, and a Google Docs model of suggestions and comments. Are these the best we can do? How do we generalize these ideas to data formats that are not text? We are eager to see what can be discovered.
While centralized systems rely heavily on access control and permissions, the same concepts do not directly apply in a local-first context. For example, any user who has a copy of some data cannot be prevented from locally modifying it; however, other users may choose whether or not to subscribe to those changes. How should users think about sharing, permissions, and feedback? If we can’t remove documents from others’ computers, what does it mean to “stop sharing” with someone?
We believe that the assumption of centralization is deeply ingrained in our user experiences today, and we are only beginning to discover the consequences of changing that assumption. We hope these open questions will inspire researchers to explore what we believe is an untapped area.
If you’re a software engineer, designer, product manager, or independent app developer working on production-ready software today, how can you help? We suggest taking incremental steps toward a local-first future. Start by scoring your app:
| 1. Fast | 2. Multi-device | 3. Offline | 4. Collaboration | 5. Longevity | 6. Privacy | 7. User control | |
|---|---|---|---|---|---|---|---|
| Your app |
Then some strategies for improving each area:
If you are an entrepreneur interested in building developer infrastructure, all of the above suggests an interesting market opportunity: “Firebase for CRDTs.”
Such a startup would need to offer a great developer experience and a local persistence library (something like SQLite or Realm). It would need to be available for mobile platforms (iOS, Android), native desktop (Windows, Mac, Linux), and web technologies (Electron, Progressive Web Apps).
User control, privacy, multi-device support, and collaboration would all be baked in. Application developers could focus on building their app, knowing that the easiest implementation path would also given them top marks on the local-first scorecard. As litmus test to see if you have succeeded, we suggest: do all your customers’ apps continue working in perpetuity, even if all servers are shut down?
We believe the “Firebase for CRDTs” opportunity will be huge as CRDTs come of age. We’d like to hear from you if you’re working on this.
Computers are one of the most important creative tools mankind has ever produced. Software has become the conduit through which our work is done and the repository in which that work resides.
In the pursuit of better tools we moved many applications to the cloud. Cloud software is in many regards superior to “old-fashioned” software: it offers collaborative, always-up-to-date applications, accessible from anywhere in the world. We no longer worry about what software version we are running, or what machine a file lives on.
However, in the cloud, ownership of data is vested in the servers, not the users, and so we became borrowers of our own data. The documents created in cloud apps are destined to disappear when the creators of those services cease to maintain them. Cloud services defy long-term preservation. No Wayback Machine can restore a sunsetted web application. The Internet Archive cannot preserve your Google Docs.
In this article we explored a new way forward for software of the future. We have shown that it is possible for users to retain ownership and control of their data, while also benefiting from the features we associate with the cloud: seamless collaboration and access from anywhere. It is possible to get the best of both worlds.
But more work is needed to realize the local-first approach in practice. Application developers can take incremental steps, such as improving offline support and making better use of on-device storage. Researchers can continue improving the algorithms, programming models, and user interfaces for local-first software. Entrepreneurs can develop foundational technologies such as CRDTs and peer-to-peer networking into mature products able to power the next generation of applications.
Today it is easy to create a web application in which the server takes ownership of all the data. But it is too hard to build collaborative software that respects users’ ownership and agency. In order to shift the balance, we need to improve the tools for developing local-first software. We hope that you will join us.
We welcome your thoughts, questions, or critique: @inkandswitch or hello@inkandswitch.com.
Martin Kleppmann is supported by a grant from The Boeing Company. Thank you to our collaborators at Ink & Switch who worked on the prototypes discussed above: Julia Roggatz, Orion Henry, Roshan Choxi, Jeff Peterson, Jim Pick, and Ignatius Gilfedder. Thank you also to Heidi Howard, Roly Perera, and to the anonymous reviewers from Onward! for feedback on a draft of this article.
And as for sqlite being local first - it's not the same. It's the nature of the data a plain text note taking app deals with that neuters that very idea of those plain text notes by storing in a local sqlite db.
That, and also there are real benefits to the end user of having everything persisted in the cloud by default.
But it's even worse in that case, because that can also happen if they mess something up. Your email account got banned by some capricious bot, or the provider abruptly decided to stop providing the service, and then the service tied to it decided to send you a verification code to the email you don't have access to anymore -- even though you didn't forget your password for either of them. So now you have even more ways to lose all your stuff.
Meanwhile if you were willing to trust some email provider to not screw you and you only needed some way to recover your keys if your computer falls into the sea, you could just email a copy of them to yourself. And then you wouldn't be relying on that provider to have the only means of recovery, because they're still on your device too.
The big problem comes into play for new, or more custom types of applications. It takes a while for something to become ubiquitous enough that standard formats are developed to support them.
Through regulating markets to ensure fierce competition - including things like portability, standard APIs, banning egress fees and similar lock in techniques, breaking up infrastructure (DCs and networking) from service providers. In cloud we have 3 vertically integrated mega oligopolies. That’s not a healthy market.
> data portability […] probably requires a technical solution
Yes, formats and APIs are needed for technical reasons, but it already exists (or fairly trivial to implement) and is not provided – sometimes actively obstructed – for business reasons. Imo interop is predominantly bottlenecked by social/business concerns.
This is different from what the local-first article is describing, which addresses data for individuals. That's a much harder problem to solve at scale.
Yes, there might be a breakthrough or a bug in encryption, and jnless you've been targetted, you can respond. But we've seen and experienced breakdowns in human character (employees spying on customers, stealing data...), government policies and company behaviour to trust the complexity and cost (lawyers) of enforcing accountability through policy.
In general, you do need both, but if you've got one, to engineers, technical solution is usually more appealing.
The asset in the contract is their customer's data; it is becoming stale by the minute. It could be residing in debtor-owned hardware and/or in data centers that are no longer getting their bills paid.
It takes time to get a trustee assigned and I think we need an immediate response - like same day. (NAL but prep'd 7s & 13s)
The entire point of Chapter 11 (and similar bankruptcy legislation internationally) is to allow companies to get out of contracts, so that they can restructure the business to hopefully continue on as a going concern.
Bear devs advise against doing that: "Generally speaking, it is safe to access the database for reading only"
> It's just slightly harder for you to edit your notes externally
Yup, just slightly harder! Very slightly. A difference of 3.75 picoseconds. Couldn't agree more.
> it's very easy to directly query
Right!
> and if you really cared..have made a script
And designed a nuclear reactor while I was at it, isn't it?
> The devs made the right choice
Yessss!! Finally.
Ffs!!!
Only useful thing from Garmin app has been comparing heart rates to a year ago.
Related: I've been incubating an idea for a while that open source, as it presently stands, is largely an ecosystem that exists in support of cloud SaaS. This is quite paradoxical because cloud SaaS is by far the least free model for software -- far, far less free than closed source commercial local software.
That plus web dev is trendy and everybody is learning it. I wouldn't know how to code a proper desktop app right now, I've not done it in years. I don't want to criticize that or the centralization aspect – there will still be ways to put these centralized things on a PC for example.
I’m also suspect of logs as a general form of conflict resolution as you are just hoping the two edits don’t touch the same area. And if they do then you are left in an invalid state.
You brought up zips. Pile of files seems like a way you can divide up data so it can have more pieces that are mergable/diffable.
For example “the folder can contain N files” or “there must be exactly 1 of this file”.
Also interesting to note that you couldn't actually muster a coherent response to any of my points and just had to make ad hominem attacks and emotional outbursts.
Claude can one shot this.
It's still worth pointing out that this design decision is orthogonal to the decision to use SQLite, though. The Bear devs could have designed it such that you could write to the database directly, or they could have kept the text-file-based design, but still told the user that they can't modify the files directly (as one of my personal projects does). The assignment of blame to SQLite specifically is misguided.
there are different kinds of ads, but lets be clear that even a Show HN is a form of ad. Some forms of ads are just more appreciated than others.
IMHO, a fully local app is an app that can run locally with all the functionality, not that it's isolated from everything else.
Browser, email client (running locally on your device such as Mail.app, mutt, Outlook,...), Zed (text editor, runs locally but can check for updates... as can many other modern apps)...
It's the same thing as the subscriptions for movies like Netflix, except at least in the last case we can fight back with various means (and it's not a necessity).
The SaaS model is basically a perfect racketeering setup, I think it should be outlawed at least philosophically. There is no way business is not going to abuse that power and they have already shown as much...
I agree with your sentiment on Open Source. I think like many of these types of things, it lives in contradictions. In any case, Linux as it is today, couldn't exist without the big commercial players paying quite a bit to get it going.
But by then my extension probably also won't be needed anymore as it would likely be integrated in the OS.
Obsidian is doing a pretty good job selling sync functionality to their free client. Because the have a really good markdown editor implementation IMHO with community plug-in support that IMHO beats every PKM cloud tool out there that competes with them.
It's possible most ubiquitous open source software ever (far more common than markdown) and your notes exist in fully readable text form inside it
Bear being proprietary is the real threat of lock in
For zip and other container-type files, you'd have log entries to the tune of "changed contained file foo.png: ...".
Operating systems would need to support some basic operations: container file operations like zip files, basic bitmap image editing, basic text document diffing, structured text diffing (XML, JSON, YAML...), etc...
Applications would provide OS-registered services (like MIME handlers are registered today) that can interpret and produce even more semantic events on top of the existing ones.
The environment could offer an interface during "syncing" when it detects a conflict to resolve it using one of the generic (or not) conflict resolution mechanisms (use local or remote version completely; use incremental delta if there is some generic semantic diff; app-provided capability if present on both sides).
Now, you are right that this can be implemented with this log being a regular file next to the file itself and completely user-space, but you will hit issues if you are not able to tie it nicely to things like fwrite/fsync and similar syscalls.
Obviously, for it to make sense, it needs to be widely accepted as the approach, which is what the local-first movement is trying to achieve with CRDTs.
No, what we need is a way for people to not starve so that they don't have to make money at all and can focus instead on their passion project(s). Cough UBI cough
Sure there is: “$500 upfront or $21/mo for 24 months *”
* if you don’t complete you 24 payments, we freeze your license.
sqlite3 data.db 'select text from notes'
I use sqlite3 to load and query random CSVs all the time. It feels a bit weird to hear data described as "locked" within a SQLite DB, because it's one of the simplest non-text formats for me to read data from. It would surprise me of it took more than five minutes to set up a one-way cron job to dump your notes into plain text files.How would you design a system that uses SQLite as primary storage for notes (rather than just as a search index or metadata store) while still letting people edit those notes in any text editor, sync via any cloud and make them accessible to any AI or other third party software that knows how to use a file system?
Exporting and re-importing every single time you want to edit a note is impractical for tech folks and impossible for regular users.
I can imagine a partial solution using FUSE, FileProvider and whatever the respective file system abstractions are on other platforms. But that would be a huge amount of work.
Pen and paper is severely underrated today.
My understanding is maybe use an open source provider to mitigate vendor lock in?
If we really wanted a system where we deem certain items essential and went everyone to have access to them, it makes no sense to pay for them. Money may still make sense for nonessential or luxury items, but it just gets in the way if the government has to give me money so I can go spend it on the food they actually want me to have.
This is just unbelievable! Fucking pitchforks are out literally!
I am dealing with plain text notes and you all want me to write sql queries and scripts to access those fucking text files?
Are you all (these few people who just jumped in the subthread) pulling some sort of prank of so?
I don't want you to do anything. Use whatever you want! But if you love your tool except for the fact it uses an open database format instead of text files, then lucky you, there's a solution, and it takes all of five minutes.
I'll admit that I was unclear because I used the word “starve” in my message. Obviously this choice of word was borne out of the principle that food is among the most vital basic needs, and that depriving people of it is one prominent way in which our current society is cruel. Nevertheless, UBI is not about just food, but more generally about basic needs.
Surely it wouldn't just be food, but regardless the government would be coming up with a list of items and basing the UBI on that. If those items are deemed necessary enough that everyone should have access, why not make them freely available rather than abstracting through money first?
For a UBI to exist the government has to define some kind of system for how to set the basic income level, I assume they would define a basket of goods (and services) similar to how CPI is calculated and define a formula for how the UBI is calculated from there. One way or another, someone in the government would be coming up with a list of what is "essential" and deciding how much to subsidize.
They would also need to similarly define how the UBI is adjusted over time. Prices change over time, and there would likely be a pretty quick jump in prices when the UBI is first put into effect.
All that to say, we will never have a UBI without it being centrally planned from the top. Whether it is authoritarian or not would be up for debate, it can be centrally planned and pushed from the top down without being authoritarian - unless one thinks we're already authoritarian, most of our current federal programs would fit into that category.
It's not about telling you what you should need or live without. It's about providing a service.