The Changelog: Software Development, Open Source - Local-first, y/n? (Friends)

Episode Date: November 22, 2024

Our 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)
Starting point is 00:00:00 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.
Starting point is 00:01:06 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
Starting point is 00:01:46 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.
Starting point is 00:02:04 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.
Starting point is 00:02:30 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.
Starting point is 00:02:54 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.
Starting point is 00:03:32 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,
Starting point is 00:03:49 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.
Starting point is 00:04:01 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
Starting point is 00:04:17 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.
Starting point is 00:04:33 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.
Starting point is 00:04:49 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,
Starting point is 00:05:06 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
Starting point is 00:05:56 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.
Starting point is 00:06:38 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
Starting point is 00:07:19 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.
Starting point is 00:07:40 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
Starting point is 00:08:34 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.
Starting point is 00:09:25 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.
Starting point is 00:10:28 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
Starting point is 00:10:56 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
Starting point is 00:11:30 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
Starting point is 00:12:12 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
Starting point is 00:12:43 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
Starting point is 00:13:25 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.
Starting point is 00:13:59 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
Starting point is 00:14:26 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
Starting point is 00:14:33 so in your definition Johanna so your thoughts like what are like the greatest local first apps
Starting point is 00:14:40 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.
Starting point is 00:15:08 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
Starting point is 00:16:00 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
Starting point is 00:16:50 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.
Starting point is 00:17:17 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
Starting point is 00:17:51 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.
Starting point is 00:18:14 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
Starting point is 00:18:34 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.
Starting point is 00:19:08 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.
Starting point is 00:19:20 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,
Starting point is 00:19:52 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
Starting point is 00:20:08 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
Starting point is 00:20:44 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?
Starting point is 00:21:09 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
Starting point is 00:21:31 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
Starting point is 00:21:44 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,
Starting point is 00:21:56 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
Starting point is 00:22:11 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
Starting point is 00:22:36 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
Starting point is 00:23:28 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
Starting point is 00:24:09 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.
Starting point is 00:24:35 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
Starting point is 00:25:02 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.
Starting point is 00:25:18 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
Starting point is 00:25:45 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.
Starting point is 00:26:07 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
Starting point is 00:26:17 for everything from IoT, sensors, AI, dev tools, crypto, and finance apps. So, Avdar,
Starting point is 00:26:24 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
Starting point is 00:27:12 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
Starting point is 00:27:38 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.
Starting point is 00:28:01 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,
Starting point is 00:28:22 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.
Starting point is 00:28:38 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,
Starting point is 00:29:08 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.
Starting point is 00:29:32 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
Starting point is 00:29:53 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.
Starting point is 00:30:28 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.
Starting point is 00:31:00 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?
Starting point is 00:31:23 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
Starting point is 00:31:52 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
Starting point is 00:32:23 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
Starting point is 00:32:58 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.
Starting point is 00:33:34 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
Starting point is 00:34:06 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,
Starting point is 00:34:30 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.
Starting point is 00:34:48 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
Starting point is 00:35:10 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,
Starting point is 00:35:30 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
Starting point is 00:36:15 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.
Starting point is 00:36:50 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?
Starting point is 00:37:07 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
Starting point is 00:37:58 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.
Starting point is 00:38:34 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
Starting point is 00:39:05 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
Starting point is 00:39:25 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
Starting point is 00:39:52 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
Starting point is 00:40:23 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
Starting point is 00:41:01 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,
Starting point is 00:41:31 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.
Starting point is 00:42:11 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,
Starting point is 00:42:37 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.
Starting point is 00:43:01 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
Starting point is 00:43:27 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
Starting point is 00:43:37 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
Starting point is 00:43:48 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.
Starting point is 00:44:09 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
Starting point is 00:44:39 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
Starting point is 00:45:28 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.
Starting point is 00:45:50 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.
Starting point is 00:46:01 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
Starting point is 00:46:13 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.
Starting point is 00:46:38 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
Starting point is 00:47:15 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
Starting point is 00:47:52 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
Starting point is 00:48:26 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
Starting point is 00:48:54 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,
Starting point is 00:49:18 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
Starting point is 00:49:59 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
Starting point is 00:50:39 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
Starting point is 00:51:07 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
Starting point is 00:51:55 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,
Starting point is 00:52:28 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
Starting point is 00:52:42 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.
Starting point is 00:53:17 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
Starting point is 00:53:47 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
Starting point is 00:54:32 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.
Starting point is 00:55:05 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.
Starting point is 00:55:28 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.
Starting point is 00:55:58 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
Starting point is 00:56:54 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
Starting point is 00:57:26 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,
Starting point is 00:57:36 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
Starting point is 00:57:54 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.
Starting point is 00:58:35 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.
Starting point is 00:59:08 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,
Starting point is 00:59:40 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,
Starting point is 01:00:14 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.
Starting point is 01:00:38 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.
Starting point is 01:01:08 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.
Starting point is 01:01:49 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.
Starting point is 01:02:14 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,
Starting point is 01:02:40 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.
Starting point is 01:03:11 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,
Starting point is 01:03:35 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
Starting point is 01:04:00 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.
Starting point is 01:04:35 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.
Starting point is 01:05:10 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
Starting point is 01:05:25 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?
Starting point is 01:05:37 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,
Starting point is 01:05:46 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.
Starting point is 01:05:57 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
Starting point is 01:06:23 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,
Starting point is 01:06:37 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
Starting point is 01:07:01 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?
Starting point is 01:07:33 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.
Starting point is 01:07:48 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
Starting point is 01:08:09 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.
Starting point is 01:08:25 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,
Starting point is 01:08:40 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,
Starting point is 01:08:58 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
Starting point is 01:09:15 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.
Starting point is 01:09:45 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
Starting point is 01:10:25 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
Starting point is 01:10:56 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.
Starting point is 01:11:22 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,
Starting point is 01:11:56 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?
Starting point is 01:12:17 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,
Starting point is 01:12:41 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.
Starting point is 01:13:06 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.
Starting point is 01:13:41 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
Starting point is 01:14:25 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
Starting point is 01:14:59 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
Starting point is 01:15:36 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
Starting point is 01:16:11 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
Starting point is 01:16:40 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
Starting point is 01:17:01 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.
Starting point is 01:17:30 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.
Starting point is 01:17:45 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.
Starting point is 01:18:22 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,
Starting point is 01:18:37 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
Starting point is 01:19:02 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
Starting point is 01:19:35 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.
Starting point is 01:20:00 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?
Starting point is 01:20:20 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
Starting point is 01:20:51 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.
Starting point is 01:21:26 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
Starting point is 01:21:44 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.
Starting point is 01:22:12 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
Starting point is 01:22:33 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.
Starting point is 01:22:44 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.
Starting point is 01:23:15 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
Starting point is 01:23:44 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
Starting point is 01:24:03 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,
Starting point is 01:24:41 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.
Starting point is 01:25:25 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,
Starting point is 01:26:06 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.
Starting point is 01:26:24 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.
Starting point is 01:26:43 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
Starting point is 01:27:25 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
Starting point is 01:27:43 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
Starting point is 01:28:06 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,
Starting point is 01:28:42 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.
Starting point is 01:29:01 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
Starting point is 01:29:12 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.
Starting point is 01:29:30 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
Starting point is 01:29:46 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.
Starting point is 01:30:04 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.
Starting point is 01:30:20 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
Starting point is 01:30:38 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.
Starting point is 01:30:58 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
Starting point is 01:31:11 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
Starting point is 01:31:20 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
Starting point is 01:31:36 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.
Starting point is 01:32:05 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,
Starting point is 01:32:23 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,
Starting point is 01:32:53 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.
Starting point is 01:33:07 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.
Starting point is 01:33:24 So I guess we'll see you next week. It's better.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.