The Changelog: Software Development, Open Source - Local-first, y/n? (Friends)
Episode Date: November 22, 2024Our friends Johannes Schickling & James Long join us to discuss the movement of local-first, its pros and cons, the tradeoffs, and the path to the warming waters of mostly local apps....
Transcript
Discussion (0)
Welcome to ChangeLog and Friends, our weekly talk show about mostly local. A big thank you to our friends and partners over at fly.io, the home of changelog.com and the
cloud for developers who ship. That's you. That's us. Check them out at fly.io. Okay, let's local
first. What's up, friends? I'm here with Kurt Mackey, co-founder and CEO of Fly. As you know, we love Fly. That is the home of changelog.com.
But Kurt, I want to know how you explain Fly to developers.
Do you tell them a story first? How do you do it?
I kind of change how I explain it based on almost like the generation of developer I'm talking to.
So like for me, I built and shipped apps on Heroku, which if you've never used Heroku,
is roughly like building and shipping an app on Vercel today.
It's just it's 2024 instead of 2008 or whatever.
And what frustrated me about doing that was I didn't I got stuck.
You can build and ship a Rails app with a Postgres on Heroku the same way you can build and ship a Next.js app on Vercel.
But as soon as you want to do something interesting, like as soon as you want to at the time, I think one one of the things I ran into is like, I wanted to add what used to be like kind of the basis for
Elasticsearch. I want to do full text search in my applications. You kind of hit this wall with
something like Heroku where you can't really do that. I think lately we've seen it with like
people wanting to add LLMs kind of inference stuff to their applications on Bracel or Heroku
or Cloudflare or whoever these days, they've started like releasing abstractions
that sort of let you do this,
but I can't just run the model I'd run locally
on these black box platforms that are very specialized.
For the people my age, it's always like,
oh, Heroku is great, but I outgrew it.
And one of the things that I felt like I should be able
to do when I was using Heroku was like run my app
close to people in Tokyo for users that were in Tokyo.
And that was never possible. For modern generation devs it's it's a lot more Vercel based it's a lot
like Vercel is great right up until you hit one of their hard line boundaries and then you're kind
of stuck. There's the other one we've had someone within the company I can't remember the name of
this game but the tagline was like five minutes to start forever to master. It's sort of how we're
pitching Fly is like you can get an app going in five minutes,
but there's so much depth to the platform
that you're never going to run out of things
you can do with it.
So unlike AWS or Heroku or Vercel,
which are all great platforms,
the cool thing we love here at ChangeLab most about Fly
is that no matter what we want to do on the platform,
we have primitives, we have abilities,
and we as developers can charge our own mission on Fly.
It is a no-limits platform built for developers,
and we think you should try it out.
Go to fly.io to learn more.
Launch your app in five minutes.
Too easy.
Once again, fly.io. This is your fourth appearance on our pod. So welcome back. We have Johannes Schickling and James Long.
What's up, guys?
Not much.
Great to be here.
I'm super excited to be back talking more about Local First.
What was my third time?
I know I came and talked about Actual, and then I talked about something else.
I didn't know this was my fourth.
Putting me on the spot.
Sorry about that.
So for a time, for a little while, we produced and shipped the React podcast
here on this network.
So you were on ChangeLog Interviews 242,
The Burden of Open Source,
and then you were on the React podcast
talking about React and Electron,
which we published,
and then actually, actually open source
talking about actual.
So with us, with Adam and I twice,
but on the network three times.
Got it.
Technically with me several times. Nice. And you just once, Jared. Fair. three times. Got it. Technically with me, several times.
And you just once, Jared. Fair.
Good fact checks, guys.
Fact checking you on here. Johannes, do you feel
good about three? Does that sound right to you?
Yeah, sounds about right.
I guess one or two maybe about
GraphQL, Prisma.
Another one about something
afterwards. I don't know.
About using the effect library.
Are you still an effect fan?
Oh yeah, that was on JS Jabberdo, I think.
That's JS Party,
which is a far superior JavaScript podcast.
No, just kidding.
We're just doing conflict resolution right here live.
That's right.
All of our podcasts are resolved in a CRDT,
so I just used that in a way
which probably showed
that I don't know exactly how it works.
But let's move on swiftly.
We want to talk about LocalFirst
because we have, of course,
Johannes, the purveyor of LocalFirst.fm
and James, you've been doing things locally
in the browser for a long time,
pushing the limits,
I would say both of you.
And James recently posted a post, which is what you do now,
you don't tweet anymore, you post, in which you said that after a long time of trying it, doing it,
etc., you don't think it's the future for all kinds of apps, which there's a question about,
is that the case? Now, it's a blog post in progress. Whenever I see somebody with a blog
post in progress, or it should be a blog, but it isn't yet. And they're talking, I think let's have an actual conversation because
this will help all of us think through things and iron out our thoughts. And so I want to start
there. But before even that, I think the definition of local first is also ambiguous or perhaps up for
debate. So maybe we can get on the same page about what a local first web app is and is even the word web supposed to be in there i think it is but johannes maybe start there
we'll see if all four of us agree about what local first really is yeah i would say that uh web is
not a necessity of local first i think local first is um has kind of so far gone through two rounds of like a definition attempt the first one was
through the ink and switch essay i think in 2019 or so by martin kleppman pvh and so on and that
was outlined in a set of seven ideals that define what local first software is. And that's along the lines of like no spinners,
the network being optional, et cetera.
None of that is really about any platform.
I think at the end of the day,
software runs wherever we use a certain device.
And at some point it might run wherever.
So the web is just a very common platform.
And then the second attempt to define
what local first software is,
was last year, or technically, I guess, this year, from Martin Kleppmann at the first local first conference, where I think he tried to simplify it a little bit more what local first software is,
where I think he said along the lines that a computer that you're not aware of even existing
should not prevent your software from running
and i would say that this is we can take it apart what that definition means but i think it's kind
of intuitive and given that a lot of software runs in the browser i think that's where particularly
our mind goes and i would say it's particularly hard to build local first grade software
in the browser. It's somewhat
possible, sometimes not fully practical
and I think we'll go deep
into that. But local
first has nothing
inherently, is not inherently bound
to the web.
James, anything to add or subtract?
Agree or disagree with what he's
saying there? No, I think that all sounds good. I think the web is definitely kind of anti-local for us in some ways. And so we're, the community, it feels like we're kind of pushing the boundaries. That's why we have to push the boundaries, because it has a lot of boundaries around doing things locally. Because I mean, honestly, it began as this, you know, client server model, which is a really powerful model. And so we're trying to figure out how to kind of pull
it back from that. But no, totally agree. I think these kind of terms are helpful
for conversations because it's a very simplistic term. It's like a code name almost. But these
things always naturally are actually pretty ambiguous and difficult to nail down specifically.
And I think it's worthwhile to have conversations to actually define the nuances a little bit more and they can also be under the umbrella of
local first i think i don't think we need to you know mince words too much um but it is worthwhile
to kind of like take a step back and actually talk about what that means exactly to two different
people right and i might also add that i think local first is often seen as sort of this binary thing.
But I think that's, at least as of today, not too helpful of a perspective.
I'd rather encourage people to think about local first as like an aspiration and a spectrum that you can take many steps in that direction.
Would you have reached all the seven ideals of the local first manifesto or
would you fully already nail the definition of like if another computer stops working does your
software stop working probably not but you're already well on your way there software like
linear etc is not local first by definition but it's way further along the lines there compared to other software.
And I think that's what it's all about, like being aspiring to building better software.
And I think local first is a way how we can think about getting there.
When you have the question, what you have to follow up with why. So we know what it is now
for we all agree. Why go local first? Why aspire to the spectrum?
Why aspire to the binary?
Why aspire at all towards this local first direction?
I can start with why I sort of naturally fell into this around 2017, which was around the time.
I think the essay came out like a little bit later after I had started going down this path and it sort of crystallized a lot for me. But yeah, when I was building Actual, which is a personal finance app that I built and tried to sell for a couple years, it actually met most of the principles of the original one where it's actually completely local first. Literally all of your data is local and the server is a super dumb server. And in that architecture, you can even like end-to-end encrypt, which felt appealing. I think it was more appealing idealistically, like, or like ideologically appealing.
Because it was just like, hey, like it's your personal financier.
It sounds cool to encrypt it.
I think a lot of my evolution from this is like, nobody really cared that much about
that.
And so I'm sort of reeling back from some of the like deep research I did back then.
But anyway, the main reason I did it was for performance and
just like simplicity, like it just felt really cool to just like write SQL queries and have this
SQL database totally available to your entire local machine, where rather than like an HTTP
request that came back with like, most of the fields, but some of them were missing because
they needed to join some table that was on a totally different sharded database in a separate
place. And so then you have to do a follow up HTTP request and GraphQL
sort of follows some of this, but it's GraphQL just feels like super overly complex. And when
you need to do mutations with GraphQL, it's just like really locks you into this like specific
format. And then you're always like waiting on loading spinners and things like that. And it's
just like this super compelling, compelling simplicity of like hey sql query get
my data back within like five milliseconds render it and then like subscribe to that data and it's
all completely local and you don't need like a web socket to a remote server that could die
like die anytime now so that that was that was my main motivation and i think that might hold
for your reasons johannes is that is that right yeah i i think i want to i very much subscribe to what
you've already said um i think there's two major perspectives for me one is the perspective from
me as a builder who wants to build a product for end users so what do you want the experience
the end user experience to be and obviously performance is one that very very quickly
comes to mind what i want the app to
feel like like it should be a great user experience and i think local first that's a really high bar
this is where software like linear etc is so that makes it so clear that this is just like a high
quality app and local first helps you get there But the other one is from a developer experience perspective
and not just even from a developer experience perspective,
but also like you've mentioned the word simplicity.
I think this is what typically ruins
both the user experience and the developer experience
that we are just drowning in complexity.
And Local First for me was sort of like a promise
for like eventually we can do much better. We can
build more ambitious apps in a way that is actually simpler to build for the developer.
And this is a promise that I still strongly believe in. We're not quite there yet. We've
already made a lot of progress in that direction. But is what is for me all about is like that like
we're drowning in complexity typically the more ambitious of an app we are building
and local first gives me hope and gives me a promise that we can do a lot better that we
gain simplicity for some category of apps and this won't hold for all category of apps this is what
where i also strongly
agree with your point that you've shared. Local first is not the panacea for all apps. But for
some apps, it can be a much better trade off. And this is what got me so excited about it.
What category of apps do you think that applies to? Because when it comes to simplicity,
I think the mental model for a developer
that I operate a server
and a client makes a request to my server
and I do whatever I'm going to do and then I respond
and the client renders it.
To me, it's hard to get more simplistic than that,
but that, admittedly, is a very basic
application. However, there are some applications where it's like, you're reading a newspaper.
Does it need to be local first? Because the actual newspaper content is not in the device,
it's on the server. And so what good is it without the server? So I'm sure there's like,
I mean, you keep mentioning linear, it's probably like hidden out of the ballpark
use cases
there's probably like
pretty good use cases
and there's probably like
maybe what James
has been finding
is like well
is it the future
for all apps
he doesn't think so
so in your
definition
Johanna
so your thoughts
like what are like
the greatest
local first
apps
and then what are
some good ones
and then maybe we'll get
to ones where it's like
yeah
doesn't really make sense yeah so I don't disagree with james that it's like it is not the future for
all apps i do think it could be a better future for some apps and so that how i would categorize
this as a starting point at least is like anything that really centers around my data as a user or as a small group of users.
So for example, a note-taking app. I think that's a very prototypical example for where LocalFirst
makes a lot of sense, where it's simple to build, and where it also from an end-user perspective
makes so much sense because all the data that's ever created in this app, I probably created,
I've written down by myself at some point or dictated, et cetera. All the data is coming
from me, very opposed to like a newspaper where someone else has written everything. I'm never
going to read all of it. So that I think is an anti-use case for local first anything that feels like a social
network or newspaper etc anything where a individual user small group of users have created
some data i think that is a very good use case this is where you have like if you think about
the data as a graph you have like it's a very highly connected dense graph and it's very easy
to in terms of the quantity of the data that it actually fits on the devices that we're using
so this is like a rough idea of what makes a good fit for a local first app but then it also
like scales a bit beyond that so for example if you want to not just work on some data by yourself,
but maybe in the realm of like a smaller group, let's say your family, or let's say your small
team, your medium team, and the larger it gets, the less of a good fit it possibly is for local
first since trust is another matter. Like when you you're you're probably trusting your all the
members in your family you might also trust all the members in a small team once you're like a
5 000 person company you have like legal obligations etc that you need to have like strict boundaries
in place and someone needs to be able to remotely delete all of the data this is where it gets a
little bit in tension but the the more it is all about a user's data
or a small group of users,
I think this is where it's a great starting point.
So James, you said in your post
that you think it's cool for some very specific apps
like Obsidian.
As an example, of course, this is an app
that's operating on your local Markdown files
and then also building from there
and doing additional stuff. You built a personal finance app in the browser, right? Or with web
tech. And that sounds like something Johannes is very much defining and you gave it a shot.
So curious your thoughts on that being applicable in that circumstance or what you found with regard
to what sounds like a good use case for a local first,
according to Johannes and makes sense to me. Yeah, I think, I mean, it's just hard because
that kind of reasoning still resonates with me. It's super amazing to just like have this three
megabyte SQLite file. And for me personally, like I have maybe eight years of transactions,
it's maybe scaled up to five megabytes. Like it's not ever going to be remotely a problem
to have this all local.
And to me also, it was really compelling
at the very beginning.
So I actually started with WebTek,
but it was wrapped with Electron.
So it was a fully native app.
So I didn't have to be actually
in the guardrails of the browser.
So it literally used native SQLite.
There was a SQLite file locally on my computer.
And what's so cool about that
is I could just like fire it up from the terminal and just like run some select queries. The problem,
there's a lot of things that kind of have tripped away at that for me that have made me kind of take
a step back to kind of rethink some of it. Even for some of these apps that do seem at the upfront
better. One is like the web is the distribution king. You cannot get away from
the web. Like I, it was very clear early on that like downloading this huge 300, it wasn't 300,
I don't know. It was like 75 megabyte electron app. And everybody was like, made fun of you for
building this like web thing that was so new. I was just like tired of having to deal with all
of that stuff. And also the notarization and like actually deploying things through the native stuff.
It's just like,
it is the worst thing I've ever experienced.
And going, I also built like React Native apps too,
which is like biggest regret of actual
was just like overextending myself.
But for every single thing
that you distribute it to,
you have to like notarize it.
You have to pay money
to actually distribute it through it.
You have to like get a certificate for Windows.
I had to get this other
like weird Sectigo certificate chain. So it was a lot. So I deployed to the web and I could make a bug fix
and deploy it in three seconds. It was amazing. The problem there is I lose the local SQLite file
capability, right? So they do have this new technology. So I built Upstart SQL, which was
this SQLite abstraction over IndexedDB. I still think it was like super cool.
Now they have this like OPFS capability with like the file system access API.
So you can do real files,
but they're sandboxed within the browser.
I don't know.
They might exist somewhere locally,
but I'm pretty sure you're not really,
I don't think they do.
I think that they're compressed in a weird way
that you can't actually just have a local SQLite file.
They give you basically like a virtual private file system. And so you lose this ability to just
like, hey, have a local SQLite file. So you have to compile WebAssembly down and lose some
performance. I don't know exactly what that overhead is, but it's slower. And it, Johannes,
you probably have way more experience because you've done a lot more of this, like more recently.
So I'm curious what that perf is. We can talk about that in just a second. But it is a little,
there's going to be a little bit of overhead right there. Like if it's a C
running, I can fine tune it. I can, I can tweak it, but I, I mean, web always blows me away.
Like maybe there's, maybe it actually matches the native speed now. But there's also just the fact
that you, your data is still sandboxed in this thing. Right. And so that was one thing is that
I lose the ability to just like
locally query stuff. And so now if I want to do that, well, now I have to like, if I want it,
like, let's say that I had a script, right? That like, I've had this idea that was kind of this
weird idea where I think I saw this person on Hacker News a couple weeks ago. He had this
printer that every day would like print out something. And I love that idea. And I'm actually
going to do that. I'm going to have this printer that prints out things.
And one of those things is going to be my latest transaction things, like how much have
we spent on food?
And then I can go up and print that on my refrigerator and my whole family can see,
my wife can see updates to our budget.
To do that, to have a service running on my machine now has to, it's just really awkward,
right?
I guess it has to become a client in this whole distributed system.
And so it has to download the entire SQLite file,
the entire data,
and then download the whole app
to interface with it
and then like run those queries.
Whereas if it was just an HTTP API,
I mean, just like you said, Jared,
this is incredibly simple.
You just make a request to the HTTP API.
So it scales complexity-wise
across use cases
that I think are more interesting.
And so I think that there's like,
there's something that I'd love
to talk about later in this podcast
about like what I think
could be the next step
for some of these kinds of things.
But I do still think that like,
for like note-taking things
and things like that,
it does still feel like,
I use Bear,
which all uses like a local SQLite
database as far as I know.
And then it uses like the
iCloud syncing and I love it because it's so fast like I can just like pull it up on my phone and I
know that it will come up instantly because all the files are there so I think there are still
use cases there but there's still a case where like well then I can like I guess it feels nicer
because I can just rsync my files to my server and then I can build a little HTTP thing like around it. But it just feels like this like complexity
that I kept having to hit for like,
oh, there's this like thing
that everybody else is used to doing.
And I can't do that now
because I've built this other thing
that has good trade-offs.
But I think that there might be architectures
that have similar benefits
without losing some of that kind
of weirdness and also my final point i'll make is that like those complexity things and like there's
these libraries now johannes i need to look more at yours but like i'm scared to build on top of
something if especially if it forces me to use their own apis like their own database abstraction
i like the ones that do let me use raw raw, but even those are like, this is a fundamental abstraction in your stack, right? If you're a startup that blows up, and you get stuck with that, and it turns out to not scale or be bad, or that the people making that burnout or like go away, that is a hard have to be really like this is just like a like a chicken and the egg type thing where it's like if you want local first to be really good and build these things you're going
to have to work really really hard and long to make this like a robust foundation so that's my
initial number of thoughts happy to yeah so in your experience building actual are you saying
that you kept hitting these walls or you would hit the walls if you had to scale on and network and add clients or add
collaboration so to speak this local first direction took you in places that locked you in
and couldn't let you scale or do things differently i suppose i'm not finding the right words but
essentially locked you into a place or choices and you couldn't get around them basically that
that was one thing that was hard.
And like some of that is because I built it myself. And so if I was able to use it, there is
like amazing library, like the one that Johannes has built. Is it LifeStore? Is that the name of
it? There's a couple of them out there. Yeah. I need to check that out. It definitely would have
helped me a lot if I had one already that was there that solves some of these problems for me.
But I think some of this is a fundamental piece of the architecture where like people just wanted
to build a little client around it,
like themselves and access actuals API.
I was like, hey, okay, we don't have an API.
I ended up building one and you know how it worked.
It was the entire app
which downloaded the entire data first.
And so to boot up the API the first time you run it
takes seconds, like 10 seconds.
So very, very slow and not very tenable.
And the other thing that I was going to say is things like protected data. So if people wanted
to have these roles and authorization, I think that's something that, I think that that part,
I think is not fundamental. I think that's solvable, but it is hard. If you wanted to say
this user can input this transaction and I want to hide it from my spouse
because it's like for Christmas.
Those kinds of things just got really tricky.
And just these weird things were like,
okay, you're logged out
and you stopped paying for the product,
but you still have it all locally.
And so people could like keep using it.
And it's just like these weird things
where like you log out
and then you log back in as a different user,
but the other local data is still there.
And like, it's just like, to me i was like i want to be a startup that focuses on the problem
like the the solving the actual you and i kept having to be dragged into this like
weird mind state of like how do i deal with this like crazy weird mind-bending situation
that local first so i i think that is the benefit of some of the why the community has moved towards this
newer model of local first, where it's like a really heavy kind of cache where it's like
it still is a little bit more dependent on the server and it's not completely local first.
But it adheres to the principles where you query your data locally, but it's not as like
I got a new name for everybody.
I'll stop calling it local first.
It's called mostly local.
Okay, mostly local. Okay?
Mostly local.
You're swimming upstream there.
I think we have critical mass
calling it local first
at this point.
Okay, friends.
I'm with a good friend of mine,
Avdar Suithin from Timescale.
They are positioning Postgres
for everything from
IoT,
sensors,
AI,
dev tools,
crypto,
and finance apps.
So, Avdar,
help me understand why Timescale feels Postgres is most well positioned to be the database for AI applications.
It's the most popular database according to the Stack Overflow Developer Survey.
And Postgres, one of the distinguishing characteristics is that it's extensible.
And so you can extend it for use cases beyond just relational and transactional data for use cases like time series and analytics.
That's kind of where Timescale the company started, as well as now more recently Vector Search and Vector Storage, which are super impactful for applications like RAG, recommendation systems, and even AI agents, which we're seeing more and more of those things today.
Yeah, Postgres is super powerful.
It's well loved by developers. I feel like more devs
because they know it. It can enable more developers to become AI developers, AI engineers and build
AI apps. From our side, we think Postgres is really the no brainer choice. You don't have
to manage a different database. You don't have to deal with data synchronization and data isolation
because you have like three different systems and three different sources of truth.
And one area where we've done work in
is around the performance and scalability.
So we've built an extension called PG Vector Scale
that enhances the performance and scalability of Postgres
so that you can use it with confidence
for large scale AI applications
like RAG and agents and such.
And then also another area is coming back
to something that you said, enabling more
and more developers to make the jump into building AI applications and become AI engineers
using the expertise that they already have.
And so that's where we built the PGAI extension that brings LLMs to Postgres to enable things
like LLM reasoning on your Postgres data, as well as embedding creation.
And for all those reasons, I think when you're building an AI application,
you don't have to use something new.
You can just use Postgres.
Well, friends, learn how Timescale is making Postgres powerful.
Over 3 million Timescale databases power IoT,
sensors, AI, dev tools, crypto, and finance applications,
and they do it all on Postgres.
Timescale uses Postgres for everything,
and now you can too.
Learn more at timescale.com.
Again, timescale.com.
And by our friends at 8sleep.
I love my 8sleep.
Check them out, 8sleep.com.
I've never slept better.
And you know I love biohacking.
I love sleep science.
And this is all about sleep science mixed with AI to keep you at your best while you sleep.
This technology is pushing the boundaries of what's possible in our bedrooms.
Let me tell you about 8sleep and their cutting edge Pod 4 Ultra.
So what exactly is the Pod?
Imagine a high-tech mattress cover that you can easily add to any bed.
But this isn't just any cover.
It's packed with sensors, heating and cooling elements,
and it's all controlled by sophisticated AI algorithms.
It's like having a sleep lab, a smart thermostat,
and a personal sleep coach,
all rolled into one single device.
And the pod uses a network of sensors
to track a wide array of biometrics while you sleep.
It tracks sleep stages, heart rate variability, respiratory rate, temperature, and more.
And the really cool part is this.
It does all this without you having to wear any devices.
The accuracy of this thing rivals what you would get in a professional sleep lab.
Now, let me tell you about my personal favorite thing.
Autopilot Recap.
Every day, My8sleep tells me what my autopilot did for me
to help me sleep better at night.
Here's what it said last night.
Last night, autopilot made adjustments
to boost your REM sleep by 62%.
Wow, 62%.
That means that it updated and changed my temperature
to cool, to warm, and helped me fine tune exactly where I
wanted to be with precision temperature control to get to that maximum REM sleep. And sleep is
the most important function we do every single day. As you can probably tell, I'm a massive fan
of my eight sleep, and I think you should get one. So go to eightsleep.com slash changelog.
And right now they have an awesome deal for Blind Friday going from November 11th through December 14th.
The discount code changelog will get you up to $600 off the Plug4Ultra when you bundle it.
Again, the code to use is changelog.
And that's from November 11th through December 14th.
Once again, that's 8sleep.com slash changelog.
I know you love it.
I sleep on this thing every night, and I absolutely love it.
It's a game changer, and it's going to change your game.
Once again, 8sleep.com slash changelog.
It seems like the difference between James and Johannes is like
James is trying to build an app for production
and Johannes loves building dev tools
and things to enable developers.
And so you're kind of trying,
almost like James would be your eventual customer or user
because he's talking about this live store.
You see this future and you're trying to create it, right?
Well, that's not entirely true.
So the reason why Livestore came into existence in the first place
is actually based on a predecessor project called Riffle
that I collaborated on with Jeffrey Litt and Nicholas Schieffer.
Jeffrey did his PhD project at MIT about this last year.
And this was like a two-year collaboration
where we've worked on Riffle.
The entire idea around Riffle was
what if you can make your app state management,
not just like the backend data management,
but actually your app state management,
what if you could also use a database for that
and bringing reactivity, etivity etc right into your app so
kind of going one step even further to what james landed landed on to using sqlite i think typically
on a separate thread where you asynchronously work with that synchronous state that sql database
we took it one step further and we saw sqlite being so fast that you could actually run it
in the main thread that's a different can of worms, technically very, very interesting and was also quite a challenge
to build. But the reason why I got involved is actually I took a bit of a step back from Prisma
where it was all building dev tools. I wanted to get back into the shoes of building my own app
again. So that was actually in terms of the chicken and egg
where LiveStore is maybe the egg
but the chicken that was also needed
was me working on my own app and that's called Overtone.
So Overtone, I think we talked about that on a previous time
is a new music app that I'm building
sort of like a third party client
for wherever your music lives so
think about it like what's superhuman is to gmail overtone is to spotify or to your own music
collection to youtube music to bandcamp etc and that was my primary driver to even want something
like riffle and like that now led to liveestore. And I'm developing both Livestore and Overtone in tandem.
Overtone is still sort of the most demanding use case
that informs all design decisions around Livestore.
But I'm not doing this in a vacuum,
even though I am like with one foot
in the dev tool building situation,
but with the other foot,
I'm firmly in the app developing situation
but i think where i can now also subscribe to the point you were you were making i am less
strict about like making harsh time-wise trade-offs in favor of shipping earlier i'm taking a more
long-term minded approach and i'm making design decisions around the technologies
and around the product that might cost me a couple of months
maybe sometimes years in terms of actually shipping everything
where I take a more long-term minded approach
and your typical startup thinks about how can we reduce
the scope for an initial MVP and just launch it
and this is where I take a different trade off.
Gotcha. Okay, that makes a lot of sense.
So effectively what we have is a different way,
a new way of building for the web,
which is the opposite way that most of us
have been building for the web, right?
So we call it client-server,
but we really are server-oriented.
And the client does things,
and the server is the source of truth and all of that.
And that's a new and perhaps better way of doing it.
However, there's a whole bunch of groundwork that has to be laid
because you're basically pioneering.
And what James, maybe you have found as you pioneered through this on your own
with Actual is like there's lots of different gnarly, nasty problems
that have to be solved in order to do this.
Stuff that us architecture astronauts
don't really think about when we're just on podcasts
talking about new paradigms in a different way
is like, well, what happens when somebody
cancels their account and it's local first?
You ran into that in reality and you're like,
oh, I have a whole new problem I have to solve.
Whereas on a traditional web app,
we've been there, we've done that.
You can just look it up or
whatever you gotta do to be like, Oh, here's what you do. And those trade-offs for you, James,
today, at least over the last few years have been not worth it. Fair?
Yes. I think that's fair. And I do think that there are, I think I want to make sure that my
points are, my main concern is that some of my problems are just
completely inherent like if you are assuming that you're going to acquire your data locally
like first and if it's like not there it can fall back to the survey even if that there are things
inherent into this that i i don't think are are completely solvable and i don't mean that that
means that it's dead in the water it's's a bad idea, but that there are problems that I think I don't see mentioned or that I think people say,
we'll get there. Like we'll, we'll figure it out. And it, but to me, it's like, it's an inherent
part of it. So it's less that like, there's all these things that I think I don't mean,
and I don't mean to like put cold water on this at all. i do think that like live store and other things can
make this significantly easier and solve a lot of the hard problems and there will be many apps
built on things like that but i think there is uh there are a couple like trade-offs here that are
just need to be kept in mind as well that might make it hard for other people right newsflash
it's not a silver bullet yeah and not only are there problems that haven't been solved yet,
but you think that just like anything, there are trade-offs
and there are problems that you don't think will be solved.
The API one is one I hadn't really thought about.
Johannes was kind of shaking his head in the affirmative
as you talked about it.
Is that a solved problem, Johannes?
You have client-first apps.
How do we build a generic API for a client-first app
like Actionable, for instance.
Is that a problem now?
When you say, how do we build an API, I'd love to hear a clarification of that.
Since one idea around local-first apps is that you actually, you should ask yourself,
do we still need an API?
It's all about the client-side experience at the end of the day, or some other things
that you need to build maybe you want to send an email if a certain thing happens etc and you might want to
do that on some server-side thing but one of the ideas of local first is trying to nudge you away
from that very api centric way of thinking of an architecture, if you're building, let's say, a calculator app that just happens to synchronize between your phone and your tablet, then you could try to
think about that as like, oh, we're going to have an API here, et cetera. But if you just start out
working on that in a single-player experience, it would never think about, do we need an API
of our calculator? No, we just built that thing client-side. And now if you have that as a starting point and you want to synchronize data
between your different clients, you don't necessarily need an API for that. You just
need a transfer mechanism between the clients. And that's rather where the Local First idea comes
from. That being said, you can still interact and integrate with APIs,
but I think with local first, you'd rather think about
how do I synchronize the data,
and less how do I request response with an API.
Sure.
Well, we don't have to invent hypothetical API scenarios,
because James, your customers were asking you for this, right?
Yes, they're like, I'm in my terminal,
and I want to just write this script that dumps things out and to like put it on my second monitor like i think maybe it was just
like maybe this is i i can't paint too broad of a of a of a stroke here because i think maybe this
this is one app that just would have benefited from like a like a a standard api because people
wanted to query their data they wanted to like like, yeah, like write scripts on the remote server
to like set up their own notifications
for when like a transaction came through
that was like too much.
And so like, I know in this specific case,
it would have been nice to have an API.
So the way how I'm starting to think about scenarios
like those is similar to how we're using Git.
I think we're thinking less about Git
as an API endpoint that you can correspond with,
but you're thinking about Git as a semantic protocol
that you use in a very specific environment.
In this case, how you evolve your code repository
in a semantic way.
And I think the same analogy could have also held true
for your scenario so obviously
this would have taken quite a bit more effort to define and develop this and so on like and build
sdks for for the various target platforms etc but i think from a mental model perspective
there's nothing inherent that this needs to be an API. I think the synchronization mechanism
still holds true to this.
And this is where Git is sort of like
a very commonly used synchronization mechanism.
And I would like for apps to embrace
the sort of more Git, less APIs mindset,
where often that can be more declarative
instead of like APIs often being kind of like
very hand wavy in an imperative way but yeah it will take time to get things off the ground there
and kudos to you again for just putting in so much effort and the pioneering work that you've
done over the years and particularly also targeting the web. I think the web is both like a blessing and a curse.
It is a blessing that it can already do all of those things
that it's possible with right now,
the ubiquitous distribution you're getting with the web, etc.
But it also lags behind in terms of capabilities
that we've already had for decades on more native platforms.
I'm very bullish on the web even catching up with those native capabilities.
Just want to add a few points on what you've mentioned before in regards to file system
support, etc.
So you've mentioned OPFS as sort of like this origin private file system, which I think
by definition is sort of like non-accessible to the user.
I think the current way how it works,
for example, in Chrome,
is there is actually like some folder somewhere,
I guess under like application support or library,
somewhere on macOS or in different places
where you can actually see the real files,
but this might just be an implementation detail.'s not meant to be access user accessible however also in chrome there is a i'm not sure
whether it's even newer but there's a separate api with mostly the same api surface where it
lets a user actually mount a real file or a real folder system from their actual hard drive into the web app.
And you can read and write from it.
So with that, you get like real files in your app.
And those files don't go away if something happens to the web app
unless the web app decides to delete it.
But this way, we're already taking another big step
towards native capability apps,
at least in Chrome for now. I'm not sure
what the current status with other platforms, with other browsers, but stuff like that gives
me a lot of hope. And the way, if I'm now wearing my application developer hat for Overtone,
what I'll probably do is like, I love those capabilities and I'll embrace them for the
given browsers. So I'll probably say like,
hey, if you want to use the web version
and not the desktop version,
and if you want to have the most advanced experience,
then please use Chrome, use Arc, et cetera.
And if you use another browser,
then I'll diffuse the capabilities a little bit.
And hopefully in two years,
Safari and other browsers have caught
up. So I'm more long-term minded on this and I don't see it. I don't look at a feature and say,
if I can't have it on all platforms, I'm not having it at all. I'm rather opting into features
progressively enhancement way, step-by-step. Yeah. I had forgotten that. I think that I saw
that was released
and I think you have to like,
there's a notification
that pops up for the user, right?
And then they just have to say allow.
And that's great.
But I love that.
I think that moving towards
those kind of models
for apps that this works well
is going to unlock a lot of like
really, really cool stuff.
I think that that is a huge blocker
that that was one
of my biggest gripes.
And so the fact that
that is starting to be solved
is amazing.
I think overall, the web is sort of like
in this weird spot where the web
has traditionally always been
like a website distribution mechanism.
But we all want like more and more
app-like experiences in the web.
But there isn't really this binary way
of like flicking on the app mode in the browser
and everything by default is treated as a website.
And that makes for a worse experience,
even so that Safari takes some pretty strong steps
in that direction.
If you don't visit a website for, I think, seven days or so,
it just wipes all of your data,
which can be very counterintuitive and very much, I think, ha or so it just like wipes all of your data which can be very counterintuitive
and very much I think hampers the trust that you can put in web apps making it again sort of like
the self-perpetuating prophecy that oh it's just a website and you can't have real apps and I guess
the closest we have in that regard is like that you pin something to your dock bar that actually does change the defaults quite a bit so but yeah that's sort of with my web optimism head on
yeah i think some of my reaction and pulling back and evolving my ideas i think are founded in like
good stuff some of it is just that i just so burned so like so many times on things that aren't
a problem anymore that i i'm still kind of evolving my ideas but like i did one burned so like so many times on things that aren't a problem anymore that i i'm
still kind of evolving my ideas but like i did one like so i built absurd sql which like was uh
sqlite on top of index cb before all of this other stuff was available and like there was definitely
just like a time when i loaded up actual and like it was like okay log in or i think i was logged in
but like none of my data was there and had to redownload it and like luckily the syncing stuff was nice because I'm mostly online so I didn't really lose any
data but like it's just a really bad taste in my mouth to be like man the web just sucks uh because
like like it just blew away my it just like all my index db was gone I guess like my disk was
running low on space or something um now to be totally clear like you were saying Johannes I
think this has all been
mostly solved
and is way, way better,
especially if we're starting
to use real local files.
I don't think the OPFS
even suffers from this.
But yeah, like that,
the web has a lot of trust issues,
I think, with people.
Or people have a lot of trust issues
with the web.
And yeah.
Well, it's an attack vector, right?
It's networked.
Obviously, there's going to be
a lack of trust.
Yeah. Also, it's not in vector, right? It's networked. Obviously, there's going to be a lack of trust. Yeah, also it's not in your control
because the browser vendors control browsers.
Right, and it sounds like, too,
both of your perspectives push against
what the browser wants to be for an application.
For example, it doesn't seem to want to be local first.
It wants to be connected.
It wants to assume the thing it's rendering is connected or wants to be connected. It wants to assume the thing it's rendering is connected
or wants to be connected. So you're kind of fighting upstream
to the platform, essentially,
that you're building against. So you have to get better
buy-in from browsers.
I wouldn't subscribe full-heartedly to that
statement. I think this is mostly a matter of
the hive mindset that we've developed in the web over the last decades really and I think this is also
where the local first mindset gives you a bit of like a bias counter to that point since you can
actually build a lot of web things where you treat the network as being optional. And I think if we put ourselves at least temporarily
in the perspective of a mobile app developer,
I think this is where it's much more common
that you want to build for an assumption
that a user doesn't have connectivity all the time.
And the way how you build the best experience in that regard
is by really treating the connectivity as an optional thing that enhances the app and you can
very much build a web app in the same way and we have a lot of ingredients that i think are highly
underused in that regard so we have like service workers. And by just forcing you and constraining yourself
in the way how you build the app,
where you say like,
actually I separate every network interaction
behind like some little surface
that I have like under my control in my application.
And I want to make sure that the application
maybe initially installs similar
to how you install an app from the from
an app store and from there the app is functional from there the app is enhanced with network
both enhanced in terms of data synchronization loading media etc and also loading new app updates
is very feasible to do that in the web i think think is just not really helped by major frameworks, something
like Next.js, etc. doesn't help you at all with that. So I think it's mostly a mindset thing.
And the mindset thing is also holding back the technologies that are being developed.
And the lack of those technologies don't evolve the mindset. So I think it's a bit of a chicken
egg problem in terms of the mindset. And we see the most development coming really
rather in the mobile world
where those assumptions are much more common.
I'm fascinated by Overtone then
as a local first application
because it's playing my Spotify playlists for me, right?
How is Overtone useful in a local-only context,
like in an offline mode,
that would make it a great local first app.
Yeah, and I think that's actually also
raising an interesting question in regards to local first,
that it's, again, not binary.
That is either fully local first,
or it is embracing all the APIs.
Overtone is a great example where I need a hybrid.
I do want to integrate with all of like
the different music services, music sources that you might have. I also want to support or I do
support things like RSS, etc. And there's also a licensing question and a copyright question that
comes into play here. Some data I am allowed to download, some data I am allowed to download some data i'm allowed to actually cache or store locally
some other data i'm just allowed to stream on demand so for example if i'm playing something
from spotify i obviously can't can just stream that but i can't download it whereas if i've
bought something on bandcamp that is something that i actually do want to bring on my hard drive. So it really
depends on the kind of situation there. But I'm building this in a way that gives you kind of the
best of both worlds, that keeps local whatever you can, and you're allowed to keep local and
that's kind of de facto yours, stuff that I'm buying from Bandcamp or from other places or stuff that I already have in my Dropbox, et cetera,
there shouldn't be any reason
why I shouldn't be able to use that on my hard drive
or on my computer while I'm doing a road trip.
Whereas there's other data
or other kind of content
where I might already have seen the metadata
and that metadata should still be accessible to me.
For example, that I see it like, oh, I like those things
or have the playback history, but temporarily until I have connectivity,
I am not allowed or I'm not able to stream that data.
So it's sort of like a hybrid mix.
But typically with a web app that is built in a more
traditional way at best you have like some offline caching that breaks the moment you first click on
an album and then it doesn't have all the data you need and you don't you just get a spinner
right do you think that i so i'm curious on your thoughts on this because there's two more points
that i wanted to bring up in terms of the things that i've i have found hard one of them also it's
just like integration with services and so it with with actual obviously like i want to pull
down transactions data and so like that it's like you have to have a server obviously for you it's
you need to pull down the music to actually play it and it you're right that, so that forces you to have this kind of hybrid model. And I always found it hard to like fully have a local thing, but then bolt on all of these
additional services. I guess it was harder for actual, especially because it was this whole
privacy focus first thing where it's like, it's all privacy focused. And yet you have to pull
down your transactions from this third party thing where you log in and give them your data.
And then it has to flow through my server because I have to like have a key to work with that service.
So it flows through my server.
So it's like it's not it's not privacy focused at all.
So that was maybe a hard thing for me.
But really to step back even more so, I love having, I don't know, I guess a hybrid can be, it's just like an additional complexity and heart.
And like, if it's all from the server,
all flowing down,
bolting on a new service is like,
it flows through the exact same pipes
that everything else uses, right?
Now we have this like two different models.
And has that been hard to kind of like
think through for you?
Because for me, sometimes I'm just like
too many things going on
and it feels nice to have a single model. But how has your approach been to sort of tackle that? Like
overhead? Yeah, I mean, if you're just building a notes app, we're the only person who's gonna
write down a note, and possibly you write it on your computer, and you write it on your phone,
and those are connected somehow, that is much, much, much easier. And this is where you're like in a fully isolated,
like homogenic local first world.
And once you're in that more hybrid world,
this is where there's a lot more that could go wrong.
And if I would be all focused on like shipping something
within a couple of months
and I need to get users, etc.
Maybe I've raised VC money, and I need to run faster on the treadmill.
This would have been the last approach that I would have taken.
However, given that I want to build this for the long run,
I'm taking a much different kind of trade-off.
I want to be able to not hate my life building this app
continuously once i've launched i don't want to just like move the problems under the rug but i
want to if i if there's something that can go wrong with a high probability it will go wrong
and so i'm basically just making this a problem of tomorrow and once you have more users
this doesn't make things better so i want to address those in a more principled way and yes
to answer your question yes it was pretty hard and took a pretty long time to figure out principled
approaches principled solutions to those really hairy problems. And I think my solutions that I found here
are very tailored to this specific use case.
So I'm not sure whether it's going to be applicable
to many, many others.
However, what I found for this works really well for me.
So what I'm basically doing is I ask myself,
what would make my life a lot easier
working with those external data sources
and de facto those data sources give you not of the git style history of everything that has
happened but just give they just give you api endpoints of partial snapshots of like this is
what our api things what our systems things, like the current state is.
And so it gives you like a,
here's like the first 50 tracks in this playlist
and then you can paginate over that, et cetera.
And that is very much built for the sort of like
temporary client experience.
The client doesn't remember everything,
but what would help me a lot is if I would get more
of like the Git style evolution of everything that has happened in this playlist.
Everything like this track was added at this position.
Those are the information about this particular album, about this particular artist, etc.
And I've built myself a little module that basically gives me that sort of worldview and reconstructs a history of everything
that has happened about this.
So it gives me basically a changelog, no pun intended,
about everything that has happened
about this particular thing,
about this particular playlist, et cetera.
And I basically isolate the heavy lifting,
eating my vegetables on that particular problem.
And once I have that chang change log of all the histories, then it's basically Redux style just applying that. So
isolating, separating the problems. And that has made such a huge difference for me. And that
allows me to actually do it. And this approach works for every data source that I've seen so far
in regards to overtone. Cool. How does it work? Why'd you make it? WorkOS has been building stuff in authentication for a long time, since the very beginning.
But we really focused initially on just enterprise auth, single sign-on SAML authentication.
But a year or two into that, we heard from more people that they wanted all the auth
stuff covered.
Two-factor auth, password auth, you know, with blocking passwords that have been reused.
They wanted auth with, you know, other third-party systems.
And they wanted really WorkOS to handle
all the business logic around tying together identities, provisioning users, and even more
advanced things like role-based access control and permissions. So we started thinking about that,
more how we could offer it as an API. And then we realized we had this amazing experience with
Radix, with this API, really the component system for building front-end experiences
for developers.
Radix is downloaded
tens of millions of times every month
for doing exactly this.
So we glued those two things together
and we built AuthKit.
So AuthKit is the easiest way
to add auth to any app,
not just Next.js,
if you're building a Rails app
or a Django app
or a just straight up Express app
or something.
It comes with a hosted login box.
So you can customize that. You can style it, you can build your own login experience to it's extremely modular,
you can just use the backend APIs in a headless fashion. But out of the box, it gives you
everything you need to be able to serve customers. And it's tied into the WorkOS platform. So you can
really, really quickly add any enterprise features you need. So we have a lot of companies that start
using it because they anticipate they're going to grow up market and want to serve enterprise. And they don't want
to have to re-architect their auth stack when they do that. So it's kind of a way to like future-proof
your auth system for your future growth. And we had people that have done that. People that started
off and they're like, oh, I'm just kicking the tires. I'm just doing this. And then poof, their
app gets a bunch of traction, starts growing. It's awesome. And they go close Coinbase or Disney or United Airlines or, you know, it's like a major customer.
And instead of saying, oh, no, sorry, we don't have any of these enterprise things and we're going to have to rebuild everything.
Just go into the WorkOS dashboard and check a box and you're done.
Aside from the fact that AuthKit is just awesome.
The real awesome thing is that it is free for up to 1 million users. Yes,
1 million monthly active users are included in this out of the gate. So use it from day one.
And when you need to scale to enterprise, you're already ready. Too easy. You can learn more at
offkit.com or of course, workos.com. Big fans, check it out.
One million users for free.
Wow.
WorkOS.com or OffKit.com.
So how warm is the water then, Johannes, in the Local First world?
So you've been taking it slow and steady in order to solve a lot of the problems.
What about devs out there, maybe they're more like James,
or they're like, I have a product, I want to get it out there,
I have an idea, maybe I have 18 months runway,
but I've got to go from zero to customers in 12 to 18 months.
Is it warm enough that local first can make sense,
or is it like, ah, you're going to have some tough sledding?
So I would say that right now
if you're on a strict time budget then local first is probably not yet for you i will probably give a
different answer i would have most certainly given a much more stricter answer along those lines two
years ago so i think right now it's already less irrational
to go this path.
But given that there is still a lot of infrastructure missing
or it's not quite as mature yet,
I would say maybe in two years from now,
I would confidently say,
okay, the water is pretty warm for those specific use cases.
I would say the more of a specific use case you have
where you feel like, no, local first is so perfect for this
and this will give me a strategic benefit further down the road,
for example, that you built something where user privacy really matters
or for other reasons.
If you have a very specific reason, then I would say,
actually, the water is warm enough that you can swim or do whatever activity in there.
But it's not a silver bullet yet.
It's not like the catch-all scenario yet.
So I think for that you're probably still better off
with your typical three-tier web app.
But it is trending in the right direction.
We have so many more off-the-shelf technologies already there that people can try out.
There's actually quite a couple that are just about to launch in the coming months.
So the space is really getting there.
And I'm very confident that for this mentioned set of use cases, I think within the coming
years, we'll see it flip, that it gets easier and simpler to build apps in this way in the medium to long term.
Since at the end of the day, if you build apps that have a rich client-side experience, there is just by definition, there's a distributed system to be solved.
And this is what like Notion is struggling with right now.
This is where many apps are actually getting worse over time.
My Notion calendar doesn't work offline, etc.
Those are things that it's just almost impossible
to retroactively address where you need to choose
the right architecture from the get-go.
And I think this will be a better starting point
in the not-so-distant future.
I feel a pain of Notion, honestly.
Like I think Notion is the unique scenario where you almost want slivers of it to be
local-ish first or mostly local.
I'm still sticking to that because like, obviously you want the calendar to work.
My calendar app from the, you know, on native Mac OS works just fine offline.
Why in the world is Notion's calendar not?
And the same thing with opening Notion to write things.
You cannot do that.
It's very challenging.
It just, like, you can render some of the things,
like it'll cache some of that stuff and you can view it,
but you can't interact with it.
So basically Notion is unusable when not connected and that's
super sad because you're mostly creating there's a lot of things that happen
in notion because notion can be very simple and notion can be very very very complex yeah once
you sort of add team members and scale databases and have permissions and different layers and
all these things and so i really do not envy the engineering challenge
they have to solve their mostly local problem.
But there you go.
Yeah, and I mean, I have so much admiration
for the folks who have been building Notion,
particularly in the early days,
but are also who are like scaling Notion right now.
And I think it's like almost like an impossible trade-off
to make right now because something like Apple software,
Apple nodes, et cetera,
they have a very specific target audience,
which is like you who bought the computer,
you as the primary user, it can be all about you.
There won't be like some super sysadmin who says,
no, you won't have access to all of your nodes anymore.
It's your computer.
All of that stuff on that computer is yours.
Whereas with Notion, as they go more and more into enterprises,
this is where they need to have certain constraints
and certain guarantees that some intern might,
if they accidentally got access to some
confidential data, that someone can revoke it and not store it for eternity on their device.
So it's very, very different trade-offs that are more in favor of an enterprise and less in favor
of an individual who owns that data. And I think that's almost an impossible trade-off to make. And even that trade-off aside
is just a very tough engineering challenge
if you start out with a relatively thin client
and then slap on more and more caching.
You've got to go all the way
and treat this to some extent as your source of truth
that you can reasonably build an app experience around that.
And in that regard apple
has to if you uh if you're a bit more generous to the definition of local first apple has kind of
been the og of local first apps in some way and most ios apps and so on i guess android apps as
well are much more local first than the typical web apps. Yeah, I think this idea of like partial sync
basically is kind of what you're implying.
That notion is kind of needing this idea of like
some of it is offline,
but you can't download the whole thing, right?
Because the intern should not be able to access
those private files.
So it can't be one big database.
So you need this like partial syncing thing
where maybe it's like multiple databases
and like one full database
that can be individually downloaded.
And that's where I've seen
some of the more modern
Electric SQL,
I think has partial sync.
And what were the two other ones
that I was just looking at?
Power sync and yeah,
there was one more
that there's this idea
where you can like
download part of it,
which solves some of my complaint
where like you want to boot up
this thing to use it as an API,
but because of the way it works,
kind of,
kind of what you're saying,
Johannes,
it's like a get thing where you can just like download the data.
You could download just the data,
data that you need to do the work that you need to do.
And it's like this partially sync thing.
But to me,
that just sounds mind bendingly complex to figure out how that works.
And I haven't dug into how the,
the current things work,
but it does seem like a very hard problem. Well, as a Notion user, the things I
want to do are I want to create a new document. Like I want to be able to note take. I want the
note taking app to be able to take notes no matter if I'm connected or not. I mean, that's
a very simplistic, like don't give me anything else. I can, as an individual user, I can
understand trade-offs that, okay, I'm offline. I can't see the full else. I can, as an individual user, I can understand trade-offs that, okay, I'm offline.
I can't see the full table.
I can't manipulate data in the cloud.
I get that.
And there may be some users out there
who are less savvy.
I don't think that's very savvy, honestly,
but maybe less savvy than that,
that don't get that.
They get upset.
But I want to create a note.
I want to be able to do things like that.
But I get the challenge there.
There's so much complexity that you could have in Notion with what it does. And I just don't
even envy the engineering task to even accomplish that mission they've got. But they need it. They
need it in certain ways. That's why I think mostly some of it, certain tasks could be
local first or local minded. One of the, I think I would encourage,
if I was to say anything to the local first community right now, I think one of the things
that would get me very interested is a incremental approach to all of this kind of stuff. Because I
think my problem is like, yes, you want to create a note and you want to write that note. Notion does
a crap load of other things. And you might not care about 90% of those things working offline, right?
You just don't care.
And so, but like we've been talking about,
it's you kind of need to buy into this from the very beginning, right?
It's a very different development experience.
And it can be a great development experience.
If you have all your data locally,
you just like run like your SQL queries,
even on the main thread, like Johanna said.
But if you like, I want to just build my app
the freaking way that everybody else is
building it, because then I can use all the services everybody else is using.
I can use all of the analytics things that are like every single, that was one of the
things, another thing I ran into actual when I wanted to use like Mixpanel, I literally
had to fork their client because it like didn't work in the way that I needed to work because
it like, you have to run it locally, right?
You can't run it on the server anymore.
And I remember it like didn't work in, because I was like compiling node to run it locally. You can't run it on the server anymore. And I remember it didn't work
because I was compiling Node
to run in a WebWorker, doing
something weird like that.
And of course, this third-party
SDK, which assumes you're in Node in the server,
would work that way. So I had to fork
it, fix all this bug, and
every single time I had to do something different.
Whenever you walk a different
path, it's hard.
I want to build my apps.
I want Notion to build their apps
the way that everybody else is building it,
the way that they're normally building it.
And then you can figure out
how to add on the local first thing.
And it's a really hard problem.
But if they should be able to say,
I want to make the ability to add a note
and sync some basic properties of that note
in that special cased way.
But the other things are just hitting an API.
To me, that sounds interesting.
I know that's almost even harder
because now we're back to a real hybrid.
But to me, it's like,
then I can do my startup,
focus on just the normal everything.
And then as we get bigger and harder and things get harder,
I can specialize parts of the app
to be local first. And that to me is
that, I don't know, it sounds interesting
to me.
For what it's worth, a lot of the technologies
that are in the works right now, like off-the-shelf
local first-ish
technologies, so you've mentioned some of them
such as Electric, another one
that's coming out soon
is called zero sync by the the folks at rosicorp their previous product was called replicash and
so what both of those technologies have in common is that they lean into your existing postgres
database that you can partially sync the data that's in that Postgres database onto your client.
And then you have an experience where you can still locally work with the data in either
an optimistic way or save some of the writes offline and process them when you get online
again.
And that is sort of like a sliding spectrum of what is not yet possible, eventually possible, but they're
heavily leaning into that incremental adoption story, which I think makes it much easier for
people to say like, hey, we have our existing app, we have our existing API, we have our existing,
for example, Postgres database, we want to build a new feature, we want to overhaul
this existing feature. And for that, we want to lean into sync, we want to overhaul this existing feature and for that we want to lean into sync
we want to build a like a real-time collaboration experience so it is getting there but i think if
someone does have the freedom and luxury to build a greenfield app and who wants to really like
in the same way as people are trusting apple nodes, it's like you pull it up, you click that new note button,
and off you go.
There's nothing in your way.
If you want to have that sort of no asterisk experience,
I think the best way to get there
and also have a great developer experience
is to fully lean into it.
Well, I've certainly clicked on new note inside Apple Notes
and seen a loading spinner,
so I'm not sure if anybody necessarily has this problem solved.
It wasn't there before iCloud Sync, but as soon as they added iCloud Sync, now all of
a sudden it was waiting for something to update in the background and I could not enter text.
That was recently, probably within the last year or so, but a one-off.
Which makes me think about the state of sync.
You mentioned these new tools that are upcoming.
We had DHH on the show a couple weeks ago. We were talking about Rails 8's embrace of SQLite and some of the possibilities that unlocks. He was very excited about the potential of having
multi-tenant apps where each app gets their own SQLite database. Of course, this is how
many local first things work. In the first place, James's actual app, you get your own little SQLite database there in the browser.
And I mentioned, yeah, you could have your own little base camp
right there in your client, and then it just syncs,
and everything's good.
And he said, he was very happy about that,
except for when I said, it just syncs.
And he's like, I don't think sync is a solved problem like that.
And I'm curious, what's the state of sync tools, the community, is it a solved problem like that. And I'm curious, what's the state of sync tools,
the community?
Is it a solved problem?
Obviously partial sync is not a solved problem,
but can we rely on the state of the art
in syncing libraries and tools?
I would say this is a heavy area of research,
development, and various attempts,
various different trade-offs.
So probably not yet by the time when this episode comes out,
but in a couple of weeks from now,
I'm planning in collaboration with a friend of mine,
Jess Martin, we're working on a comparison landscape resource
that compares the various syncing engines,
the various local first stacks, et cetera.
So that tries to give you a much more matter-of-fact,
nuanced differentiation of the different technologies.
But what I can already offer as a high-level answer to this
is that there's a couple of different approaches to syncing.
Some of them are based on CRDTs,
which has the trade-off that it can work
in a fully peer-to-peer decentralized approach.
And then there can be also like approaches where you still have a central authority.
Each of them have different trade-offs. Each of them have multiple technologies
building those. And it's really a matter of what is like a good fit for your application use case. So for example, if you still want to run a central sync entity
that has the authority,
that implies a bunch of other technologies.
So things are coming along nicely.
There are also a few that synchronize SQLite databases,
for example, directly.
So it really depends on what works well for your app and i would say
we're a lot further along than compared to five years ago and in hopefully a couple of years from
now there's just de facto best technologies for the various trade-offs and you can just use that
a couple of shout outs i would give at this point where I think it mostly just works for the use case that
you have is something like Yjs or AutoMerge if you're using CRDT. So if you use something like
Firebase, but you want to go more local first, those are great options. There's also
JazzTools. So this is for Greenfield apps. And then for Brownfield apps where you want an
incrementally adopted things like electric
SQL, parsing, the upcoming zero, et cetera.
And there's many others.
But I would say it's good if you're curious to build something with it just to tinker,
maybe not yet fully go into production.
Now is certainly a great time to get started with it.
And for many production use cases, it might be perfectly reasonable already. I think a lot of the academic research is probably good enough to where we
should be able to have something that would be really, really good. But it's just hard to actually
build out the actual, because the academic research is like really complex math and to
distill that down into a product that's actually stable and has the trust of the community because
they just literally just need to exist for five years to make sure that they're not going to go under that will take
time but i mean honestly like i did everything myself which was i overextended myself but
syncing was not my near my top complaint like the crdt stuff there was like amazing and like i can't
i'm not taking credit for that myself i just just use hyper, hyper electrical clocks. Um, it was like really cool how it worked and the research was, was there.
And it like the sinking worked great.
Like none of my complaints are about like, it was hard to sink.
It's just like, man, when you start sinking, all these other kinds of things come up that
are weird.
Not to say that I even nearly solved it, but like, it was cool that I was able to take
some existing research and just get this thing that worked actually reasonably well for, for my use case well for my use case. So I'm excited to see all these other things coming out.
But I think it now just takes new generations of actual experiences that are always getting
a level further than the ones before. And I think step by step, we can actually systematically
solve and address some of those problems
through off-the-shelf community packages
or just by sharing sort of like best practices
and building that tribe knowledge.
And I think that will already take things very far.
And what is so nice about syncing
is I think it will really be like a step function
in simplifying our app stacks
in the same way as like declarative
u programming such as react view solid etc this has made stuff that been like super gnarly and
imperative before where you needed to use jquery or manipulate the dom manually to making everything
just beautiful declarative and there's like entire category of stuff you didn't need to deal with anymore.
Now, if you get that for data
across your different clients and servers, et cetera,
that's what syncing gives you.
And this can liberate stuff so much,
and that's amazing.
James, you mentioned before we called a show,
you did want to give some thoughts
on what you think maybe a future
for mostly local community might look like.
That's a, I threw Adam a bone there. Open floor for you, James, just to share your thoughts on
what you think might be compromised or whatever your ideas are there.
Yeah. So my current, I'm kind of like kicking off my own research phase, which I wanted to do this
start a couple of weeks ago and then kids and life and holidays now.
So hopefully over the holidays,
I'll get some time to really dig in here.
I'm excited about something.
And this, like, again, this is not mutually exclusive.
It's not zero sum.
Like I fully support the local first community.
I think it is a really, really cool idea and cool tech.
And I love, I love, I'm surprised at how,
like it's not mainstream,
but I'm surprised at how popular it's become.
I was, at some point was like, there's no way people are going to actually really invest
in this because this is so much work to build a whole new platform.
So really cool to see it.
But what I am thinking now is that a lot of the benefits, at least that I was after, I
might be able to get them with doing things just more on the edge. And so the way that
my thoughts have been sort of evolving is that basically the way actual worked was it ran your
whole SQLite database and it did the entire backend of the app backend. It was, it was all
local was in a web worker, right? So it was a different process, but locally on your machine.
And you could, so once you're in the webWorker, you can do what, like the SQL queries
were literally synchronous.
Like they weren't even async
because it's actually faster.
Like it's so fast that the async overhead
of doing multiple promise calls
is actually slowing it down.
And like just architecturally,
it was just like having to, you know,
you introduce an async call somewhere
and then all the call stack has to be async.
It's just super annoying.
Super, so like going back to Johanna's development experience there, it's amazing. Once you're in that web
worker, you async call into it, but then once you're in there, it's great. But with all of
the problems that I've been saying, it's hard to integrate services. It's just kind of this
hybrid approach can be mentally taxing. I just kind of want things to work the way everybody
else works, which is that you hit a server and you get something back.
What if we do this?
This multi-tenant approach is really interesting to me.
And there's a company, Terso, Terso.tech, which is building out a scalable infrastructure for this where every single person, every single request even, could possibly get their own SQLite database.
And so what if basically I took this web worker backend that is local, but it's not actually local
and it's at the closest data center point
that could possibly be closest to you.
And so in that way, I'm still accepting the fact
that there is a network call,
that there is this boundary there, but it's very close.
So I just, I'm hosting currently my website,
jlongster.com on the Northern Virginia Oz data center or whatever. And I'm hosting currently my website, jlongster.com, on the Northern Virginia OZ data center or whatever.
And I'm in Richmond.
So I'm a couple hours drive.
And it's about 20 milliseconds overhead.
So I think we can assume 20 to 30 milliseconds overhead for a moderately non-fine-tuned network infrastructure.
I think that could even be faster.
That, to me me feels acceptable. And once I accept that single round trip cost,
then I can move everything to my server,
still have the local SQLite database
and have my development experience there.
And like possibly there's like the SQLite syncing
going on in the backend.
So I'm not ditching syncing, right?
You're probably gonna have to like sync these changes
across a backend distributed network.
But it's just nice to now own that because now I can do analytics.
I can flip something on in just a minute without having to get everybody to refresh their clients.
I can do a multitude of clients.
If I wanted a terminal app for my finances, I could curl something really fast and get a buttload of charts.
I could do a quick like i just get
that api like instantly right like it crosses that network boundary which lets me do everything the
way that everybody else is kind of doing it so like it's like the same stuff might be going on
even the syncing because you're probably going to have to be syncing that sqlite database if because
you're just mutating it locally on that edge instance right it's going to have to replicate
that somehow elsewhere but it's like if you draw the line of the app, and local
first is like, at least, for the most part, we're kind of having this hybrid thing where it like,
sort of depends on a server. But for the most part, a local first app in principle is like,
you draw the line of the entire app and all of the data. And it's like, all on your computer.
And then there's another circle, which is the server.
And then it's like syncing to the server.
This is like if you draw the line all around your app,
but then it like reaches over into the server
for like one little bit, which is that like edge node.
And then the edge node is talking
to all of the complex server.
And the more I go down this, the more it's like,
well, I really just want to make a single request
to the server, right?
I don't want to have to go back and forth.
Maybe I'm evolving to be a use the platform person and I'm just leaning to very, very light client apps.
And now I'm starting to lean into this whole React model where it streams live updates.
It's kind of fitting that it's taken years to get here, but it seems like React server components are actually a thing now.
And it is a compelling model, right?
A long time, I was like, this is the weirdest idea ever, especially when I was local first.
I was like, this doesn't benefit me at all.
Now, suddenly, if I'm flipping my position a little bit, it's like React server components are amazing.
Because I can run the entire app on the backend, get all of this stuff that I want, stream in just a couple lightweight client components that I want to.
I do full navigations,
maybe even possibly.
And the thing that also gets me
is the ability to flip open
new tabs instantly.
That's one of the things
that I'm a little bit like,
because things are all local,
it's just slow to boot up the app.
And normally I was like,
well, you boot up the app once
and you're digging in your finances
for like an hour.
Like, I don't really care.
But the thing that does feel nice is just to like command click a link and open up a new window.
Use my local macOS windowing system to split the screen, have different tabs, and just like very quickly in a very lightweight way, just like spawn tons of tabs.
And those tabs load in just like 30 milliseconds, right?
That can be hard to do local first
because you're buying into the thing
where the entire thing must run locally.
And so it has to boot up.
It has to boot up the thing.
And Johannes, I mean, maybe I'm wrong
that you can get a 25 millisecond boot up time
on a complex app.
I'm curious how Overcast feels
if you've optimized for
that. But that that is where I'm going to be researching and kind of diving into. So not to
say that this is the solution either. But it's something that I'm very excited about.
I applaud you for going down this path in the pursuit of simplicity. And I think this is why
you went down the local first path in the first place. And you've gotten really. And I think this is why you went down
the local first path in the first place
and you've gotten really far.
I think you saw like some glimpses of reward
and where you can see like working with SQLite locally,
et cetera, affords you a lot of simplicity,
but you also revealed a whole bunch of problems
that need to be addressed
and you didn't have the time for that.
And I think there will probably be a similar situation there given that a lot of the things are server side the constraints are not as severe as on a client that could potentially
be like in outer space or something so i think this is where your our traditional knowledge as a web dev community, et cetera, more broadly applies.
However, I would say this works well
for still very connected applications.
So I think it takes server-side applications
to the next level.
But if you want to use that, for example,
to build your next notion
that should work on crappy plane wi-fi
then this won't get you far since you'll now get even further removed from the next edge worker
i think it's going to be a little while until you have like edge workers natively in an airplane
but i think if connectivity is the slightest concern and then i think there might
still be challenges or or otherwise you kind of need to still solve the local first problems
since then you need to uh it's all a matter of like you get if you're connected you get better
latency but there's actually no difference between being offline and high latency.
Being offline is just very, very high latency until you get online again.
And fundamentally, you still need to solve the same problems.
And if your app can't deal with high latency, if it loses everything, then either you don't
support that and you can't write down your node or something or you still need to address it
and i think this is where you still need to address some of the underlying local first problems but
overall it certainly seems like a huge step on the server side and i think this is where we'll
make progress from both ends like from the all the server side stuff is getting better all the local
stuff is getting better and hopefully hopefully, in some cases,
it is already meeting in the middle.
I think Turso is doing some really, really cool stuff there.
But yeah, it's going to take a little while.
Certainly.
Yeah, and I agree.
It sucks.
It's accepting the trade-off that on very slow connections
or on the plane, you will have that problem.
And so that, to to me is the thing
that I'm kind of kicking down the road a little bit,
where it's like, if I can specialize
a very small critical part of the app to be local first,
then there might be specific things
that I would end up building and support there.
But totally accept that maybe that is like very hard
and actually doing that later is like, can be hard too.
And it's a viable position to say
that you need you do need to embrace it fully from the front end i'm sort of balancing that and i'm
kind of curious to see if if i could get to that point i will say that like i'm people cared that
my app was fast and uh i don't know i i think we are a very well connected world and not to say
that like it's not meaningful at all but i think
i'm kind of just falling back into the like it's i'm ditching some of that complexity just in
acceptance that like it might not work as well right sometimes yeah two thoughts on that actually
uh kind of tragic just today uh today is tuesday they're just in the Baltic Sea between Germany and Finland there was like the
sub-ocean fiber
connection was cut
probably by like a state actor
so that shows like how
brittle or like everything is always
connected assumption can be
and it's one thing if like
you're like whatever
your access to X or Blue Sky
or whatever is taking a hit,
but it's another thing if more critical systems
are being taken down.
And the other way, you don't even need to step into a plane or something.
Just go to a coffee shop and use the public Wi-Fi there
and try to just do work for half an hour
and you'll notice like how all of
your apps are just like are rendered completely useless and i think having sort of that constant
assumption everything is like fiber grade 5g grade connected i think can bite back at some point in
europe for example we people use actually trains quite a bit.
And trains has similar Wi-Fi
compared to your public coffee shop or your plane.
And so it's more ubiquitous than you think.
Well, that leads us back to trade-offs.
Because while I completely agree with Yohannes on all that,
sometimes the best app is the one that you can actually build.
And I think that's some of what James is hitting up with
is like what trade-offs is he willing to take
as a solo dev trying to build
whatever it is that you're currently building, James.
You're still working on actual as an open source, right?
Are you moving on to another product now as well?
I've pretty much, the community is fully maintaining it.
I'm not really part of the community anymore.
Okay.
Which is great, so.
Cool.
So on to greener pastures,
but whatever it is that you're trying to build,
I applaud both of you.
Johannes for pushing the industry forward
in this direction
and James for tinkering and experimenting
while you build
and willing to try new things
that most of us wouldn't even try to try
and exploring that way
and helping us discover what might be good compromises,
where it fails, et cetera.
So y'all have me excited about the future,
regardless of where it is.
I feel like I'm warming up, Johannes, to the waters
as the waters themselves warm up.
Keep us updated.
Keep us in the loop as this tooling
and this ecosystem fleshes out and matures
so we can keep our listeners in the know as well. Because this ecosystem fleshes out and matures so we can keep our listeners
in the know as well.
Because at a certain point, I hope you're right
and that pendulum flips or that switch flips.
Pendulums don't flip, they swing.
That flip switches to where it becomes actually easier
to do it this way.
Because I do think the virtues are better
than the drawbacks.
But I think, like you said,
for certain people at certain places,
with certain apps, it's still probably too hard.
So definitely as it matures,
I'm interested in hearing about that.
Adam, anything else from you before we call it a show?
Notion.
Figure it out.
I think they're on it.
To your point, Johannes, yeah,
they've known very well about this problem,
been working on it for many years.
It's really hard to bolt it on.
So yeah, it's hard.
Yeah, a little plug on my behalf.
If this is interesting to any listener
to dig more into Local First,
I want to plug the Local First podcast, Local First FM.
It goes a lot more in depth on all things distributed systems
and all things like various trade-offs.
We had the CTO of Linear on there.
We had James on there.
We had Martin Kleppmann, who's the author of AutoMerge
and the Local First essay on there.
So if you're curious to learn more, this might be a fun place.
Very niche, all about Local First.
But in case
you're curious about this,
worthwhile checking out.
Awesome.
We will link to that.
We will link to all
the things.
James, anything to
plug or shout out
on our way out?
Yeah, I'll just say
if you are listening
and interested in Local First,
please do not let me
dissuade you.
I think it's super interesting
and I am choosing slightly different trade-offs every
now and then, but you get
excited and you go and build
and I am fueled by
proving people wrong. And so if I say
something that you disagree with, prove me wrong and go build
the tooling and support the community.
Johannes, I'm very impressed
and supportive with all the things that you all did.
With Riffle too, also, I was following
that for a long time. So, fully love what you're doing with live store i don't have anything top
of mind for me to shout out specifically so that's all i'll say i'm very certain that all paths will
meet again might be a couple of years realistically but i'm pretty sure that we'll get the best of
both worlds awesome well that's all this time.
So we'll just say goodbye, friends.
Bye, friends.
Bye, friends.
Thank you so much.
Fun conversation today with good friends on Local First.
Is it the future?
Only time will tell.
But I think if applications like Notion can pull it off,
that will be a big win for Local First and all its offering.
And hey, if you're at Notion or you know someone at Notion, let them know.
We want to talk to them about this upcoming feature, how they're tackling it, and all the good stuff.
And I guess on that note, if you want to request an episode, the easiest way to do that is to go to changelog.com slash request.
We love hearing from our listeners about what episodes they want to hear, and we're happy to do it. Again, changelog.com slash request. We love hearing from our listeners about what episodes
they want to hear, and we're happy to do it. Again,
changelog.com slash request.
A big thank you to our friends at fly.io,
our friends
at Timescale, timescale.com,
and our friends at 8sleep.
I've never had better sleep. I love
my 8sleep. Check them out, 8sleep.com.
Their Black Friday sales are here.
Use our code changelog and get a lot of money off. Check them out, 8sleep.com Their Black Friday sales are here. Use our code CHANGELOG and get
a lot of money off. Check them out.
8sleep.com slash changelog.
And to our friends at WorkOS.
WorkOS.com
So awesome. Love the team there.
Love Michael. All they're doing.
Okay. BMC, those beats are
banging. Thank you so much, BMC.
This week is done. This show is done.
So I guess we'll see you next week.
It's better.