Hacker News new | past | comments | ask | show | jobs | submit login

I think this is fair, as they haven't committed to offline - though they've said they want to do it, they just want to wait to do it right. That said, they do work fully client-side, so I wouldn't say it's server-first, it's more of a hybrid. I will try and clear this up in our wording.

Final note on the user-stuff: that's always up to the person writing the app anyway. You could make a "download the IndexedDB" button with a couple lines of code, but it's more than that, it's really a whole bunch of decisions you have to make as an app-developer to commit to it. And tbh I think the general understanding of local-first has settled on client-side + optimistic + offline - for the better.




> I wouldn't say it's server-first because the mutations are happening locally first and every feature works fully client-side.

That's not even close to what "local first software" means.

Can apps work without the server? Like, if the server goes down, will the app still work?

Can I collaboratively edit my data without the origin server? (Or at all?) Normally replication built on raw postgres queries relies on atomic row level locks on the server, while processing transactions. What happens if two people edit the same data at the same time?

Does it support end-to-end encryption, so my data isn't readable by the server at all?

Can I back up the app & my data together, and open it back up in 5 years and have the app still work?

All this stuff is talked about in the local first paper. Putting a sync engine in front of postgres (as described by the zerosync website) doesn't do any of this stuff. (Or maybe some of it? Its hard to tell without more information, and I can't find a link to the source code.)

It reminds me when Zoom advertised E2E encryption on zoom's website because the CTO clearly didn't know what "end to end encryption" actually means. It looks like an excellent product - so why exaggerate its capabilities?

"Local first" doesn't mean "edits are applied speculatively in the client before they hit the server". It also doesn't mean "caching part of the centralized postgres database in the client".

Go read the paper. The details matter. https://www.inkandswitch.com/local-first/


[Moved up thread]


To answer your specific questions:

> What if the data I need isn’t in the cache?

The developer can arrange for all the data to be in the cache if the want that part of the app to be fully offline capable.

> What happens when I edit things offline then come online later?

Zero won't support offline mutation at launch, but there's nothing preventing it from working. It is built on [Replicache](https://replicache.dev) which does support offline mutation.

I think almost no software that claims to be local-first actually supports robust offline editing and merging. The only people I've seen really go for this is the I&S folks with their branching stuff and that was just an experiment.

I'm excited to do this right, but most of our users care more about the ux and dx improvements while online, so we'll do it later.

> What happens if the company shuts down and the server gets turned off permanently? Will the app still work?

Developers can self-host Zero. In advance of any standards for sync, this is about the best you're going to get with any local-first software today, except maybe stuff that syncs to Dropbox (which is cool!).

> Can apps work without the server? Like, if the server goes down, will the app still work?

Yes. Read-only at alpha, and later read-write.

> Can I collaboratively edit my data without the origin server? (Or at all?) Normally replication built on raw postgres queries relies on atomic row level locks on the server, while processing transactions. What happens if two people edit the same data at the same time?

Yes. Zero uses server reconciliation, like our previous products Replicache and Reflect. You can read more here:

https://rocicorp.dev/blog/ready-player-two

(how could you even do realtime collaboration with postgres locks? that doesn't really make sense)

> Does it support end-to-end encryption, so my data isn't readable by the server at all?

Sure. That's up to the developer in how they design their database schema, but of course it's possible.

> Can I back up the app & my data together, and open it back up in 5 years and have the app still work?

I mean I guess so? If you had it in an electron app you just snapshot the data directory? An app developer could arrange for this to happen if it was important to them.

Does this all count as local-first? I think it's about as local-first as most other software claiming the title. But again, I kind of prefer to focus on what our product does and for that reason I try to avoid claiming we're local-first.


Thanks - very interesting stuff!

> Yes. Zero uses server reconciliation, like our previous products Replicache and Reflect. You can read more here: https://rocicorp.dev/blog/ready-player-two

Oh I hadn't seen that before, and I love that. It looks like an extension of database transactions / MVCC into the client.

Its interesting thinking about what situations this will & won't work in. I imagine it'd work for most of the mutations made in most applications, like editing rows in a database. And in your example, inserting at the end of a list would work.

But what about inserting in the middle of a list (or, typing in a text document)? Naively, it wouldn't work because "insert at position X" changes its meaning wrt. concurrent edits. But you could make OT work if you provided a way to change the arguments themselves if concurrent changes were detected. (Thats essentially all OT is. When concurrent changes happen, run the transform function. op = transform(op, other_op)).

Interestingly, I think you could use a text CRDT (like yjs) with your architecture. You would need to run the crdt's prepare function in the client first, to convert the edit into the CRDT's format (eg for Yjs, that looks like Insert('a', left_id: XX, right_id: YY). Then if you passed that object into the transaction closure, you could run the CRDT on the server and it'd all work out.

Its not quite as obvious and straightforward as your examples. But still, very cool that its extensible like that.


That is a disappointing interpretation of “local-first”, and would not suit the kind of applications I want to write.

On the other hand, this is still tethered to the server, so likely more commercially viable than a true local-first design.


> That is a disappointing interpretation of “local-first”, and would not suit the kind of applications I want to write.

I don’t think anyone wants or expects all software to be local first.

What would it even mean to "locally first" turn the lights in my house on and off, check the weather, or play a multiplayer-only video game?

Local first makes a lot of sense for some use cases - like personal / creative work (eg Apple Notes). But not for others.


> What would it even mean to "locally first" turn the lights in my house on and off?

It would mean that even when the vendor decides to disconnect the cloud server, the app still knows how to find the lights over the local WIFI and turn them on-and-off. This is one of the poster-child use cases for "local first".

> check the weather?

There's less to work with here, because we generally treat weather as a read-only use case. But it isn't! There are weather apps today that let you connect to your own local weather station, and/or fetch results from other tiny weather stations in your region. All of which could be handled in a "local first" manner (modulo some reasonable way to discover nearby weather stations).

> or play a multiplayer-only video game?

Chess, scrabble, or really any asynchronous turn-based game can be handled via local edit for your move, and then sync to your peer (optionally through a server for easier coordination).


> It would mean that even when the vendor decides to disconnect the cloud server, the app still knows how to find the lights over the local WIFI and turn them on-and-off. This is one of the poster-child use cases for "local first".

I agree with this, but my point is “what should the app do when you’re offline” - as in, your phone is on aeroplane mode. “Local” as in, local to your device. Not your wifi.

What does it mean to turn the lights on and off in that situation?

In my opinion, nothing, it shouldn’t work. And if that’s true, the light is essentially a server, the app / phone is a client. Nothing has changed except making the routing more efficient.


Sure, that's just the nature of interacting with a remote object of any type. But I don't think that invalidates wanting the app to be designed in a "local first" manner with respect to whatever happens to the cloud backend.


Right. A remote object. But the point of local first software is the objects are local.

If I edit a note using Apple Notes, I’m not editing a remote object. I’m editing something local - authoritatively local - to my device. The server doesn’t know more than my phone does, and the server doesn’t get to tell my phone that I don’t have permission to edit my own, local stuff.

That’s different from interacting with a remote object as a client. Hence, I don’t see turning a remotely controllable light on and off to be local first software because way more like interacting with a server than it is like Apple notes. The server just happens to be harder to route packets to sometimes.


By that definition, pretty much the only apps that qualify for local first are document stores. I'm not convinced that it is useful to narrow the definition that far (nor that most of the local first advocates would agree with such a narrowing).

We're basically talking about 1 bit of state that the light is authoritative about (on/off), versus all the other state that your copy of the app can be authoritative about (configuration, schedules, etc).


- turn on lights — there are smart light bulbs that phone home to the cloud. Along with smart assistance, home automation, etc. those are exactly the things that should be local-first, or at least, the server software should be onsite (such as Home Assistant — edge computing). We already have examples of what happens when companies shut down the servers those automations depend upon. To go even fuether, each device that is truly local-first enables the kind of cooperative automation conceived of in Promise Theory.

- checking the weather — although predictions are easier to come by from NOAA’s weather models, areas can have microclimates both natural and man-made that are not so easily predicted through atmospheric modelling. Permaculture design includes scaling microclimates in very small areas (on the order of specific plants) to tweak what can grow there. Local-first makes sense if you want to instrument those microclimates. Better yet, there are ways to read the clouds and conditions to get decent predictions for weather conditions for your immediate area.

- local-first multiplayer video game - what an intriguing idea! The closest I can think of is that multi-user virtual reality spaces that was built on a modern version of Smalltalk. It isn’t local first, but it supports multiple, independent servers that mesh together. There are probably also ways to do this with turn based games, such as chess or go.

Do you have any other examples? The ones you brought up were a good exercise to see how far one can take local-first design.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: