1 00:00:00,049 --> 00:00:04,579 So much work in building a web app goes into reinventing this backend 2 00:00:04,609 --> 00:00:07,460 infrastructure that every single company has to reinvent again. 3 00:00:07,750 --> 00:00:12,460 And so if we can make the data sync protocol and the data storage on the 4 00:00:12,460 --> 00:00:16,309 servers efficient, like loading and synchronization of large collections of 5 00:00:16,409 --> 00:00:18,209 documents, all of that can be generic. 6 00:00:18,269 --> 00:00:21,519 So if one person is then building a graphics app and another person is 7 00:00:21,519 --> 00:00:24,969 building a spreadsheet and another person is building a document 8 00:00:24,999 --> 00:00:29,120 editor, they can all use the same syncing service as the backend. 9 00:00:29,270 --> 00:00:34,270 That I think is part of the economic value proposition of local-first software. 10 00:00:34,996 --> 00:00:37,156 Welcome to the localfirst.fm podcast. 11 00:00:37,406 --> 00:00:41,336 I'm your host, Johannes Schickling, and I'm a web developer, a startup founder, and 12 00:00:41,336 --> 00:00:43,186 love the craft of software engineering. 13 00:00:43,596 --> 00:00:47,346 For the past few years, I've been on a journey to build a modern, high quality 14 00:00:47,346 --> 00:00:49,186 music app using web technologies. 15 00:00:49,506 --> 00:00:53,546 And in doing so, I've been falling down the rabbit hole of local-first software. 16 00:00:54,096 --> 00:00:57,096 This podcast is your invitation to join me on that journey. 17 00:00:57,761 --> 00:01:01,731 In this episode, I'm speaking to Martin Kleppmann, who is one of the authors 18 00:01:01,751 --> 00:01:03,701 of the original local-first essay. 19 00:01:04,141 --> 00:01:09,191 Martin has been exploring local-first software in CRDTs for over 10 years, which 20 00:01:09,191 --> 00:01:13,381 has led to the creation of Automerge, which we discuss in depth in this episode. 21 00:01:14,021 --> 00:01:17,581 We are also exploring the ideas of a generic sync server and the 22 00:01:17,591 --> 00:01:21,331 impact this technology could have on local-first software in the future. 23 00:01:21,508 --> 00:01:25,218 I also have a very special announcement today as I'm co organizing the 24 00:01:25,218 --> 00:01:27,418 world's first local-first Conference. 25 00:01:27,633 --> 00:01:31,963 It will happen on May 30th in Berlin, and I would love to see you there in person. 26 00:01:32,483 --> 00:01:34,713 Go ahead and grab your tickets on localfirstconf. 27 00:01:35,243 --> 00:01:35,593 com. 28 00:01:35,803 --> 00:01:39,193 Before getting started, also a big thank you to Expo and Crab 29 00:01:39,193 --> 00:01:41,153 Nebula for supporting this podcast. 30 00:01:41,773 --> 00:01:43,603 And now my interview with Martin. 31 00:01:45,153 --> 00:01:46,593 Hello, welcome, Martin. 32 00:01:46,593 --> 00:01:49,063 Thank you so much for coming to the podcast. 33 00:01:49,063 --> 00:01:49,403 Hi, Johannes. 34 00:01:49,433 --> 00:01:50,383 Thank you for having me. 35 00:01:51,393 --> 00:01:54,193 I'm super excited to have you on the show. 36 00:01:54,213 --> 00:01:57,683 You're obviously no stranger in the local forest world. 37 00:01:57,733 --> 00:02:00,303 Um, but would you briefly mind introducing yourself? 38 00:02:01,023 --> 00:02:01,863 Uh, yeah, sure. 39 00:02:01,883 --> 00:02:06,613 So I'm just recently an associate professor at the university of Cambridge. 40 00:02:07,093 --> 00:02:10,323 I've been at Cambridge for quite a long time, but for a long time that was 41 00:02:10,323 --> 00:02:12,213 like on fixed term academic contracts. 42 00:02:12,443 --> 00:02:16,383 So this is my first permanent university position, which is nice. 43 00:02:16,383 --> 00:02:18,993 It means I can keep doing this stuff long term. 44 00:02:19,233 --> 00:02:23,213 Um, yeah, previous to that, I did in some past life work on startups. 45 00:02:24,153 --> 00:02:29,083 sold a startup to LinkedIn back in 2012, but then shifted over to academia. 46 00:02:29,726 --> 00:02:30,396 Amazing. 47 00:02:30,746 --> 00:02:35,946 and so you're one of the coauthors of the local-first paper that was 48 00:02:35,946 --> 00:02:38,296 published on the Ink & Switch site. 49 00:02:38,446 --> 00:02:42,556 So, I think most people are also in the local-first space are familiar 50 00:02:42,556 --> 00:02:49,496 with that, but I'm very curious, what is your personal story behind you sort 51 00:02:49,496 --> 00:02:51,886 of finding your way to local-first? 52 00:02:52,156 --> 00:02:57,796 Yeah, there is, it probably starts about 2013 or so, fairly shortly after we had 53 00:02:57,876 --> 00:03:03,396 sold the startup to LinkedIn and I was at LinkedIn, but our project got canceled. 54 00:03:03,726 --> 00:03:08,026 And so I was kind of looking around for new things and I came across this. 55 00:03:08,701 --> 00:03:12,001 paper from Mark Shapiro and colleagues on conflict free 56 00:03:12,001 --> 00:03:14,381 replicated data types or CRDTs. 57 00:03:14,381 --> 00:03:15,501 I can't remember how I come across it. 58 00:03:15,501 --> 00:03:17,621 Maybe somebody put it on Twitter or something like that. 59 00:03:17,821 --> 00:03:21,831 And I read this thing and I was really intrigued by it because I felt that, you 60 00:03:21,831 --> 00:03:26,824 know, this seemed like a way of Making the software a bit less cloud dominated. 61 00:03:27,034 --> 00:03:30,164 I had got a bit frustrated with the whole startup world. 62 00:03:30,164 --> 00:03:35,814 You know, as I was doing web based stuff, social media stuff, it's all very much 63 00:03:35,824 --> 00:03:41,234 like centralized services, which put all of the user's data in one big database. 64 00:03:41,234 --> 00:03:43,204 And I was just a bit uncomfortable with that. 65 00:03:43,204 --> 00:03:46,464 I felt like, it's not really in the user's interest. 66 00:03:46,484 --> 00:03:50,569 Obviously it's in the company's interests to try to collect as much data as they can 67 00:03:50,569 --> 00:03:52,349 and monetize it in whatever way they can. 68 00:03:52,399 --> 00:03:54,409 But for users, it's not really great. 69 00:03:54,459 --> 00:03:58,649 And so I was sort of trying to overcome my unease with this by looking at 70 00:03:58,889 --> 00:04:01,009 technological solutions that might help. 71 00:04:01,059 --> 00:04:04,759 And so then I came across these CRDTs, which seemed like it could be 72 00:04:04,759 --> 00:04:06,809 a part of the answer to the problem. 73 00:04:06,839 --> 00:04:11,319 I felt like it was a way how you could make software that would run on the users. 74 00:04:11,499 --> 00:04:14,559 device and store the data locally on the user's device where 75 00:04:14,559 --> 00:04:15,929 nobody can take it away from you. 76 00:04:16,169 --> 00:04:20,129 And at the same time have all the conveniences of cloud software with 77 00:04:20,129 --> 00:04:23,679 like real time collaboration and sync across all of your devices 78 00:04:23,799 --> 00:04:27,389 and being able to easily share data with other users and so on. 79 00:04:27,649 --> 00:04:31,549 So that was kind of in core of the local-first idea there already, 80 00:04:31,549 --> 00:04:35,399 but it then took us several more years before we really were able to 81 00:04:35,399 --> 00:04:37,749 articulate it clearly enough ourselves. 82 00:04:37,869 --> 00:04:38,819 And so then. 83 00:04:39,204 --> 00:04:41,524 I can't remember when the local-first paper came out. 84 00:04:41,544 --> 00:04:43,384 Was it 2019 or something like that? 85 00:04:43,781 --> 00:04:48,091 So yeah, about 2014 I left LinkedIn for a year. 86 00:04:48,101 --> 00:04:52,941 I spent on sabbatical writing my book and then 2015 I joined the university 87 00:04:52,941 --> 00:04:56,781 and started working on CRDTs myself and then started like gradually 88 00:04:56,781 --> 00:04:58,741 building up the technical foundations. 89 00:04:59,061 --> 00:05:03,311 It then still took us quite a long time before we had like really articulated it. 90 00:05:03,311 --> 00:05:08,161 but all that time was gradually working towards what we now call local-first. 91 00:05:08,471 --> 00:05:12,601 I'm curious whether there were like any particular milestones you've 92 00:05:12,601 --> 00:05:16,661 reached during those early research years where they're like moments 93 00:05:16,671 --> 00:05:20,611 where you thought you hit some walls and you thought this was a dead end. 94 00:05:20,661 --> 00:05:24,581 I mean, with any kind of research, it's always like lots of little 95 00:05:24,581 --> 00:05:27,711 dead ends and then getting out of them and trying other things again. 96 00:05:27,741 --> 00:05:30,461 But I think that's just part of the normal process. 97 00:05:30,491 --> 00:05:33,431 So I'm not going to pretend it was smooth in any way. 98 00:05:33,551 --> 00:05:36,221 Obviously, there's lots of things that didn't work along the way, but also 99 00:05:36,221 --> 00:05:40,241 most of them are sort of in retrospect, kind of don't matter too much. 100 00:05:40,381 --> 00:05:43,681 So like, you know, we have very detailed discussions about. 101 00:05:44,176 --> 00:05:46,946 How a particular merge behavior should work, for example. 102 00:05:46,956 --> 00:05:50,346 So if one user makes one change to a document, another user on a different 103 00:05:50,346 --> 00:05:52,946 device makes a different change, we need to merge those things together. 104 00:05:52,996 --> 00:05:55,396 You know, you can have hours and hours of debate about how 105 00:05:55,436 --> 00:05:56,646 precisely that should work. 106 00:05:56,696 --> 00:06:00,396 But then in the end, once you've settled on an answer and That answer seems to be 107 00:06:00,396 --> 00:06:04,016 broadly okay, then, you know, then the question just becomes uninteresting and 108 00:06:04,406 --> 00:06:06,296 we move on to more interesting things. 109 00:06:06,696 --> 00:06:10,276 So yeah, there's, there's lots of that kind of things along the way. 110 00:06:10,276 --> 00:06:13,956 And like a lot of changes we made to the implementations of these things, 111 00:06:13,956 --> 00:06:16,126 like the software evolved a lot. 112 00:06:16,196 --> 00:06:19,056 Like my first CRDT implementation was in Ruby. 113 00:06:19,136 --> 00:06:23,606 And then that later turned into a JavaScript implementation, which was the 114 00:06:23,606 --> 00:06:27,391 beginnings of what is now Automerge and then that's later got ported to Rust. 115 00:06:27,591 --> 00:06:29,781 And so now the Rust implementation is our primary one. 116 00:06:29,811 --> 00:06:33,051 So, you know, we've really gone through three languages there and God 117 00:06:33,051 --> 00:06:36,351 knows how many orders of magnitude improvement in performance, the early 118 00:06:36,371 --> 00:06:40,151 versions were extremely, extremely slow, but you know, it's, it gradually 119 00:06:40,151 --> 00:06:41,581 gets better as we keep working on it. 120 00:06:42,021 --> 00:06:45,941 I'm really eager to dive in deeper on Automerge and hearing 121 00:06:45,941 --> 00:06:50,296 your side of the story on how Automerge came to where it is today. 122 00:06:50,346 --> 00:06:54,576 Before going into Automerge, Automerge is a library to deal 123 00:06:54,576 --> 00:06:59,446 with CRDTs, but not everyone might be super familiar with CRDTs. 124 00:06:59,506 --> 00:07:04,236 I don't think there's a better person to explain what CRDTs are than you. 125 00:07:04,286 --> 00:07:07,986 Could you give a quick summary, and introduction to CRDTs? 126 00:07:08,261 --> 00:07:12,151 Yeah, so the basic idea is that you've got some data on multiple 127 00:07:12,151 --> 00:07:16,071 devices, the user on each device can independently update that data, 128 00:07:16,241 --> 00:07:17,981 possibly while the device is offline. 129 00:07:18,041 --> 00:07:20,681 And then at some point later, the devices sync their updates. 130 00:07:20,991 --> 00:07:24,981 And ideally, we just want them to merge their states together in some way. 131 00:07:24,981 --> 00:07:29,021 And CRDTs are just algorithms that perform this kind of merging, plus 132 00:07:29,051 --> 00:07:30,671 the data synchronization and so on. 133 00:07:30,731 --> 00:07:32,401 So the idea is that. 134 00:07:32,471 --> 00:07:36,461 You know, often the changes made on two different devices will affect 135 00:07:36,461 --> 00:07:37,751 different parts of a document. 136 00:07:37,891 --> 00:07:40,851 One person is updating one item in the to do list and another person is 137 00:07:40,871 --> 00:07:44,741 updating a different item, and so it's fairly easy to merge those together. 138 00:07:44,821 --> 00:07:47,931 In principle, you can end up with conflict cases where, like, it's 139 00:07:47,931 --> 00:07:51,386 a graphic software, one user makes the rectangle red, another Person 140 00:07:51,386 --> 00:07:52,786 makes the same rectangle green. 141 00:07:52,806 --> 00:07:53,616 Well, what do you do? 142 00:07:53,626 --> 00:07:57,186 Well, I mean, you probably just choose one of the two and then if the user doesn't 143 00:07:57,196 --> 00:07:58,756 like it, they can change the color again. 144 00:07:58,836 --> 00:08:02,366 So it's algorithms just for automating that kind of thing. 145 00:08:02,376 --> 00:08:06,486 Because what we don't want is for the user to be shown like a pop up saying, 146 00:08:06,526 --> 00:08:08,596 Hey, this file was changed on two devices. 147 00:08:08,736 --> 00:08:11,436 Please pick which one you want to keep and which one you want to throw away. 148 00:08:11,486 --> 00:08:12,666 I think that would be bad. 149 00:08:12,706 --> 00:08:17,109 And like previous versions of Apple's pages, also did 150 00:08:17,156 --> 00:08:18,336 that kind of thing, I guess. 151 00:08:18,686 --> 00:08:22,046 I think if I remember correctly, but fortunately now we have better algorithms 152 00:08:22,066 --> 00:08:25,866 which, which just allow changes to be merged together with minimal ceremony. 153 00:08:26,366 --> 00:08:29,826 So that's really all CRDTs are about. 154 00:08:29,976 --> 00:08:33,116 A huge amount of research has gone into like figuring out how 155 00:08:33,116 --> 00:08:35,136 to make the merge behavior good. 156 00:08:35,316 --> 00:08:40,326 So that depending on what types of edits people make, the end result is hopefully 157 00:08:40,326 --> 00:08:44,036 something that was more or less what they expect, what the users expected and 158 00:08:44,196 --> 00:08:45,806 also in making these algorithms fast. 159 00:08:46,076 --> 00:08:49,116 Because, , you can implement these algorithms in a very simple way, but the 160 00:08:49,126 --> 00:08:51,156 simple way tends to be very inefficient. 161 00:08:51,226 --> 00:08:55,436 And so making it so that it doesn't take too much disk space, doesn't take 162 00:08:55,436 --> 00:08:58,936 too much memory and it's generally fast, that actually requires quite a 163 00:08:58,976 --> 00:09:01,006 lot of sophistication on the algorithm. 164 00:09:01,056 --> 00:09:04,516 So that's where a lot of the investment has gone over the last few years, 165 00:09:04,616 --> 00:09:08,321 but yeah, but that's broadly what CRDTs are and Automerge is just a 166 00:09:08,341 --> 00:09:09,871 library that implements this stuff. 167 00:09:09,871 --> 00:09:13,651 So there are other CRDT libraries out there, but, Automerge is the 168 00:09:13,651 --> 00:09:16,111 one that I've been closely involved with over the last few years. 169 00:09:16,646 --> 00:09:20,306 Yeah, I think Automerge is probably one of the most advanced 170 00:09:20,306 --> 00:09:22,656 CRDT implementations right now. 171 00:09:22,656 --> 00:09:26,976 And as you've mentioned, you built your first versions, not in 172 00:09:26,986 --> 00:09:30,736 Rust as it is written today, but there were predecessors to this. 173 00:09:31,216 --> 00:09:33,606 So given that this is now such a. 174 00:09:33,856 --> 00:09:35,066 Such a long journey. 175 00:09:35,096 --> 00:09:38,856 I think it's, if it's fair to say, , that you've been working on this for 10 176 00:09:38,866 --> 00:09:44,696 years, I'd be very interested in hearing your reflections on the history and 177 00:09:44,696 --> 00:09:49,706 the process of taking Automerge from the beginnings to where it is today. 178 00:09:50,386 --> 00:09:50,666 Yeah. 179 00:09:50,666 --> 00:09:55,846 So when I started working on CRDTs, there was no CRDT for JSON data, for example. 180 00:09:55,936 --> 00:10:00,666 So there were existing data types for sets and maps and counters and 181 00:10:00,676 --> 00:10:01,966 registers and things like that. 182 00:10:01,966 --> 00:10:05,456 So just these kind of little atomic data types, but nothing 183 00:10:05,456 --> 00:10:07,066 that really composed them together. 184 00:10:07,636 --> 00:10:08,726 Uh, oh, and lists as well. 185 00:10:08,726 --> 00:10:10,666 I mentioned that there were data types for lists. 186 00:10:11,096 --> 00:10:14,636 And so in a way, JSON is simple, you know, it's just, you can put maps 187 00:10:14,636 --> 00:10:18,826 inside lists and maps and lists inside maps and compose them arbitrarily. 188 00:10:19,271 --> 00:10:22,331 But there's still interesting questions you have to answer, which 189 00:10:22,331 --> 00:10:26,591 is like, for example, what if one user deletes an object while another user 190 00:10:26,591 --> 00:10:28,111 makes an update inside that object? 191 00:10:28,111 --> 00:10:29,261 How do you merge those things? 192 00:10:29,821 --> 00:10:34,711 And so one of the first research papers I wrote was an algorithm for doing 193 00:10:34,831 --> 00:10:38,351 a CRDT for JSON data, which answered exactly this kind of questions. 194 00:10:38,421 --> 00:10:43,471 And then Automerge started out sort of conceptually as an implementation of 195 00:10:43,471 --> 00:10:47,541 this paper, although we ended up actually choosing different behavior for Automerge 196 00:10:47,541 --> 00:10:52,236 than the paper chose, but you know, after examining a bunch of applications and 197 00:10:52,426 --> 00:10:55,646 what sort of behavior they would want, we came to the conclusion that a different 198 00:10:55,646 --> 00:11:00,086 behavior was better, but that was basically the genesis of the whole thing. 199 00:11:00,086 --> 00:11:03,106 So I can't remember which year that JSON CRDT came. 200 00:11:03,346 --> 00:11:07,946 paper came out, but yeah, I was working on it like in 2015, 2016 ish. 201 00:11:08,026 --> 00:11:12,866 And then, I think it was about 2017, Peter van Hardenberg got in touch with me. 202 00:11:12,866 --> 00:11:17,836 So I knew Peter from back in my startup days because he was running 203 00:11:17,866 --> 00:11:20,906 the Heroku Postgres team at the time. 204 00:11:20,996 --> 00:11:25,626 And our company, which was called Reportive, was one of the bigger customers 205 00:11:25,706 --> 00:11:27,936 of, uh, Heroku Postgres at the time. 206 00:11:28,466 --> 00:11:33,591 And so We had, like, talked to Peter as part of, like, just scaling our database. 207 00:11:33,851 --> 00:11:38,011 years later, I hear from Peter again, because he had read my JSON CRDT paper 208 00:11:38,471 --> 00:11:41,791 and went like, Hey, we want to try actually building some apps with this. 209 00:11:41,811 --> 00:11:43,331 Have you tried actually building some apps? 210 00:11:43,831 --> 00:11:45,336 And I went, Oh, no, no, no. 211 00:11:45,336 --> 00:11:46,256 I just do theory. 212 00:11:46,456 --> 00:11:51,786 You know, I just write a paper and I have this extremely janky Ruby implementation 213 00:11:51,786 --> 00:11:55,116 that actually only does half of what the, what was says in the paper. 214 00:11:55,216 --> 00:11:58,556 So then, , it got together with, , Peter and Ink & Switch. 215 00:11:58,846 --> 00:12:01,676 And I think Ink & Switch was quite new still at the time. 216 00:12:01,796 --> 00:12:05,946 And we did, , this project together in which we essentially 217 00:12:05,966 --> 00:12:07,656 built a adjacent CRDT. 218 00:12:07,781 --> 00:12:09,781 That actually worked in JavaScript. 219 00:12:09,851 --> 00:12:13,511 In fact, Orion Henry wrote the first version of that and brought it to me. 220 00:12:13,511 --> 00:12:17,691 And I went like, yeah, nice API, but no, those algorithms are totally wrong. 221 00:12:17,731 --> 00:12:21,181 And so then we worked together to make the algorithms right as well. 222 00:12:21,221 --> 00:12:25,551 And it was a great collaboration because you know, the Ink & Switch folks were. 223 00:12:25,796 --> 00:12:32,296 Just much better, like API design and also UI design and general app development 224 00:12:32,346 --> 00:12:35,976 than I was, whereas I sort of brought the like more mathematical style of 225 00:12:35,976 --> 00:12:39,306 thinking of analyzing the algorithms and making sure that they were correct, 226 00:12:39,366 --> 00:12:41,446 and that was just a great collaboration. 227 00:12:41,711 --> 00:12:43,911 So yeah, we've, we first wrote this library. 228 00:12:43,921 --> 00:12:46,471 We originally called it Tesseract, but then there was already a 229 00:12:46,471 --> 00:12:47,931 JavaScript library of that name. 230 00:12:47,931 --> 00:12:51,551 So we renamed it to Automerge and that name has stuck since. 231 00:12:51,661 --> 00:12:54,801 So yeah, I think Automerge started around 2017. 232 00:12:54,901 --> 00:12:58,411 And then a few Ink & Switch projects used it, but it was very 233 00:12:58,411 --> 00:13:00,051 much research quality software. 234 00:13:00,181 --> 00:13:02,061 You know, it was extremely slow. 235 00:13:02,121 --> 00:13:03,311 It had bugs. 236 00:13:03,461 --> 00:13:05,701 The file format was extremely inefficient. 237 00:13:05,841 --> 00:13:09,191 So it was kind of impractical to use for most things. 238 00:13:10,546 --> 00:13:12,986 As a vehicle for doing research, it worked quite well. 239 00:13:13,016 --> 00:13:16,856 But then at some point, like it became clear that, okay, we 240 00:13:16,866 --> 00:13:19,306 actually want to start building more ambitious software on it. 241 00:13:19,446 --> 00:13:22,456 And it's not really acceptable if it takes three minutes to 242 00:13:22,456 --> 00:13:23,856 load your document off disk. 243 00:13:24,196 --> 00:13:26,436 So, you know, okay, we have to make the. 244 00:13:26,711 --> 00:13:31,751 figure out a new file format to make the file smaller and, , figure out new 245 00:13:31,751 --> 00:13:33,931 algorithms to make the whole thing faster. 246 00:13:34,031 --> 00:13:37,521 And then also we decided that the Rust implementation would be better. 247 00:13:37,571 --> 00:13:40,801 Um, not so much because Rust is faster than JavaScript, but rather 248 00:13:40,801 --> 00:13:42,211 because it's more cross platform. 249 00:13:42,211 --> 00:13:45,931 And so we can compile Rust to WebAssembly for the web, but we can 250 00:13:45,931 --> 00:13:49,171 also compile it to native libraries for iOS and Android, for example. 251 00:13:49,231 --> 00:13:52,561 And so Orion did a lot of work on the port to Rust. 252 00:13:53,081 --> 00:13:56,991 Uh, again, and a few others contributed to that, and Alex 253 00:13:57,031 --> 00:13:59,161 Good got involved with that too. 254 00:13:59,351 --> 00:14:03,271 But then at some point, two years ago or so, we then made the call to 255 00:14:03,321 --> 00:14:07,031 make the Rust implementation, the primary implementation of Automerge. 256 00:14:07,051 --> 00:14:10,851 So all of that JavaScript, I had, I'd been maintaining the JavaScript implementation 257 00:14:10,881 --> 00:14:15,351 as this research code over the years, but we decided to just completely deprecate 258 00:14:15,351 --> 00:14:16,721 that, throw away all of my old code. 259 00:14:16,801 --> 00:14:20,666 And I've done, actually no work on the Rust code of the implementation. 260 00:14:20,666 --> 00:14:24,416 So that's all been done by Alex and Orion and other people now. 261 00:14:24,526 --> 00:14:28,166 And I've just moved into more of an advisory role, which suits me really well. 262 00:14:28,206 --> 00:14:32,146 You know, I'm very happy to be the one not writing the code. 263 00:14:32,146 --> 00:14:34,926 Other people are much better at writing the code than I am, but I know I can 264 00:14:34,936 --> 00:14:38,406 think about the algorithms and the protocols and the data structures. 265 00:14:38,436 --> 00:14:39,786 And that's what I find fun. 266 00:14:39,886 --> 00:14:43,086 And so then, About a year ago or so, we then declared 267 00:14:43,086 --> 00:14:44,706 Automerge to be production ready. 268 00:14:44,826 --> 00:14:50,476 So at that point, then, you know, the Rust implementation was mature and fast. 269 00:14:50,526 --> 00:14:55,746 and we got a sponsorship thing going with GitHub sponsors, which allowed 270 00:14:56,196 --> 00:14:59,711 people who were commercially using, or companies that were commercially using 271 00:14:59,711 --> 00:15:01,651 Automerge, to sponsor its development. 272 00:15:01,681 --> 00:15:04,291 And that is now supporting the work of Alex Goods, who's now 273 00:15:04,291 --> 00:15:06,111 professionally maintaining Automerge. 274 00:15:06,161 --> 00:15:07,921 And that is just such a good arrangement now. 275 00:15:07,921 --> 00:15:11,471 I'm really pleased with how that's working because it means that we have 276 00:15:11,581 --> 00:15:14,961 high quality software that's being professionally maintained, but at the 277 00:15:14,961 --> 00:15:18,741 same time, you know, we haven't had to go out and raise venture capital, which 278 00:15:18,831 --> 00:15:23,421 we feared that that's, you know, might be at odds with the values of local-first. 279 00:15:23,441 --> 00:15:26,941 And so this way by Essentially bootstrapping it off of 280 00:15:26,941 --> 00:15:28,611 the sponsorship revenue. 281 00:15:28,711 --> 00:15:30,961 I think that aligns everybody's interests very well. 282 00:15:30,971 --> 00:15:33,441 And so that has allowed the project to do very well. 283 00:15:33,621 --> 00:15:35,441 That is an incredible journey. 284 00:15:35,481 --> 00:15:38,551 And I mean, this is for an open source project. 285 00:15:38,581 --> 00:15:43,811 Particularly, I think most people use right now, Automerge still in a JavaScript 286 00:15:43,851 --> 00:15:49,886 context for a JavaScript library, where I think you're thinking more in terms of dog 287 00:15:49,896 --> 00:15:54,956 years, Automerge is really a monumental project and it has come incredibly far. 288 00:15:54,956 --> 00:15:56,676 So I'm super excited for that. 289 00:15:57,146 --> 00:15:58,936 So where's the project today? 290 00:15:58,936 --> 00:16:01,806 You've mentioned that it's reached production readiness 291 00:16:02,326 --> 00:16:03,426 around about last year. 292 00:16:03,456 --> 00:16:08,256 Does that mean it's the APIs are final, the research behind it is 293 00:16:08,256 --> 00:16:13,146 concluded and now it's just performance optimizations or what is left to do? 294 00:16:13,661 --> 00:16:17,041 And I just, there's so much, so much we still want to do with it. 295 00:16:17,441 --> 00:16:20,751 So what we mean with production ready is like, there are no egregious 296 00:16:20,751 --> 00:16:23,791 bugs that we know about and the performance is good enough that. 297 00:16:24,581 --> 00:16:28,101 You know, it's plausibly usable in real software, which some of the 298 00:16:28,101 --> 00:16:31,831 research code definitely was not, but it's got much, much better, but 299 00:16:31,831 --> 00:16:36,121 in terms of features, like it, I think we've only really just started. 300 00:16:36,151 --> 00:16:41,241 So what Automerge started with is a basic JSON model, so you can have maps. 301 00:16:41,756 --> 00:16:45,676 Where the keys are strings and the values can be either nested maps, or they can 302 00:16:45,676 --> 00:16:50,816 be nested lists, or arbitrary recursion of those things, or primitive values 303 00:16:50,816 --> 00:16:53,086 like strings and numbers and booleans. 304 00:16:53,146 --> 00:16:53,556 And that's it. 305 00:16:53,746 --> 00:16:56,766 Then, okay, we, we added counters because actually counters are 306 00:16:56,766 --> 00:17:00,236 actually not very useful, but everyone seems to use them for demos. 307 00:17:00,316 --> 00:17:03,096 So we include the counters so that we can have the demo as well. 308 00:17:03,146 --> 00:17:06,636 Then, a big thing we added was rich text. 309 00:17:06,766 --> 00:17:09,466 So that's something that a lot of applications need is. 310 00:17:10,041 --> 00:17:11,321 text with formatting. 311 00:17:11,321 --> 00:17:16,221 And the first version of that is released and implemented, though the 312 00:17:16,241 --> 00:17:19,981 first version only supported inline formatting, such as bold and italic 313 00:17:20,361 --> 00:17:24,661 but not block elements like headings or bullet points or things like that. 314 00:17:24,771 --> 00:17:28,251 And so there's an updated version of that coming soon, which adds 315 00:17:28,341 --> 00:17:29,781 support for block elements too. 316 00:17:29,861 --> 00:17:31,161 So this is now nice. 317 00:17:31,161 --> 00:17:33,331 You can put rich text anywhere inside a document. 318 00:17:33,341 --> 00:17:33,571 So. 319 00:17:33,721 --> 00:17:36,061 You know, it's, if you want to make a Google Docs equivalent thing, 320 00:17:36,071 --> 00:17:39,091 you can do that, but you could also have, for example, a vector 321 00:17:39,091 --> 00:17:42,451 graphics software that has some rich text just inside the text boxes. 322 00:17:42,451 --> 00:17:48,251 And the rest is a drawing consisting of like arrows and lines and 323 00:17:48,741 --> 00:17:50,091 freeform, whatever you want. 324 00:17:50,181 --> 00:17:54,511 And so the JSON type document model has allowed extension in those 325 00:17:54,531 --> 00:17:58,031 directions very well, but there's so much more we still want to do. 326 00:17:58,031 --> 00:17:58,121 So. 327 00:17:58,831 --> 00:18:02,941 Like an obvious missing thing is undo in collaborative software is actually quite 328 00:18:02,951 --> 00:18:06,031 subtle in terms of the behavior you want. 329 00:18:06,081 --> 00:18:09,561 And so in particular, it's not generally the case that you want to undo the 330 00:18:09,561 --> 00:18:13,291 most recent operation, the most recent change to the document, because the most 331 00:18:13,291 --> 00:18:16,511 recent change to document might've been made by somebody else in a part of the 332 00:18:16,511 --> 00:18:17,601 document that you're not looking at. 333 00:18:17,781 --> 00:18:18,306 And so. 334 00:18:18,426 --> 00:18:20,876 Undoing somebody else's change in a completely different part of the 335 00:18:20,876 --> 00:18:23,856 document is definitely not what you intended when you hit command Z. 336 00:18:24,016 --> 00:18:30,106 So actually doing undo well requires, inspecting the editing history of 337 00:18:30,126 --> 00:18:33,626 the document, which we can do because Automerge keeps the editing history 338 00:18:33,626 --> 00:18:37,686 anyway, but actually surfacing that and making the right APIs 339 00:18:37,736 --> 00:18:40,586 the right underlying algorithms, that's still some work in progress. 340 00:18:40,646 --> 00:18:44,931 Another thing that we've long Try to add as a move operation so that, 341 00:18:44,931 --> 00:18:49,341 for example, you could reorder items in lists or if you have a, say a 342 00:18:49,341 --> 00:18:53,841 file system tree, you could drag a directory from one location to another. 343 00:18:54,201 --> 00:18:57,951 That is also quite subtle to implement because you have to answer 344 00:18:57,951 --> 00:19:01,401 questions like, what happens if two users can currently move the 345 00:19:01,401 --> 00:19:03,261 same item to two different places? 346 00:19:03,381 --> 00:19:04,581 You don't want to duplicate it. 347 00:19:04,586 --> 00:19:05,632 In that case, you want to just. 348 00:19:06,061 --> 00:19:07,481 pick one of the destinations. 349 00:19:07,701 --> 00:19:12,011 Or you get weird things where like you have A and B which are siblings and one 350 00:19:12,021 --> 00:19:16,511 user moves A to be a child of B while concurrently another user moves B to be a 351 00:19:16,511 --> 00:19:20,551 child of A and now if you're not careful you could end up with a loop between A 352 00:19:20,551 --> 00:19:22,376 and B and That would be a mess as well. 353 00:19:22,646 --> 00:19:26,046 So to move operation very carefully has to handle those kinds of cases. 354 00:19:26,286 --> 00:19:29,176 You know, we wrote the research paper about it several years ago, but 355 00:19:29,176 --> 00:19:33,426 actually turning that into the kind of production quality code as part of 356 00:19:33,436 --> 00:19:35,516 Automerge is still ongoing project. 357 00:19:35,546 --> 00:19:39,036 And so those are kind of the near term things that we want to. 358 00:19:39,221 --> 00:19:42,401 Features, examples of features that we want to add to Automerge. 359 00:19:42,421 --> 00:19:45,631 Other stuff we want to do better are, for example, synchronizing 360 00:19:45,641 --> 00:19:46,971 large collections of documents. 361 00:19:47,301 --> 00:19:50,681 So at the moment, Automerge really just deals with one document at a time. 362 00:19:50,821 --> 00:19:54,871 But in many apps, you know, you might have a collection of 100, 000 documents and 363 00:19:54,891 --> 00:19:57,211 most of them don't change most very much. 364 00:19:57,271 --> 00:20:00,951 So we need a protocol for efficiently figuring out which of those many documents 365 00:20:00,951 --> 00:20:03,971 have changed and then synchronize only those which have changed and 366 00:20:04,011 --> 00:20:07,301 have minimal overhead for those that have not changed, that kind of stuff. 367 00:20:07,836 --> 00:20:13,656 So you mentioning, uh, collections and that right now Automerge is only working 368 00:20:13,686 --> 00:20:18,226 on sort of a single document level, but you want to go further into collections. 369 00:20:18,566 --> 00:20:21,426 So collections makes me think of databases. 370 00:20:21,746 --> 00:20:26,686 Can you contrast a little bit of how someone who thinks about data 371 00:20:26,686 --> 00:20:32,906 primarily in terms of databases, how your brain needs to change to think 372 00:20:32,926 --> 00:20:35,126 primarily in terms of Automerge and how. 373 00:20:35,386 --> 00:20:40,446 What in the future where someone uses Automerge, do they still use databases? 374 00:20:40,586 --> 00:20:44,466 Do you think about the data that Automerge just manages sort of 375 00:20:44,466 --> 00:20:46,346 like as an implicit database? 376 00:20:46,586 --> 00:20:48,336 How should I think about that in the future? 377 00:20:48,896 --> 00:20:51,756 Yeah, I think there's, there's a lot of similarities between 378 00:20:51,816 --> 00:20:53,376 Automerge and the database. 379 00:20:53,376 --> 00:20:57,406 And we've sort of like internally joke that, you know, we're not writing a 380 00:20:57,406 --> 00:21:01,016 database because writing a database is a crazy thing to do that nobody should 381 00:21:01,056 --> 00:21:05,246 like try to write their own database, but it looks like we are writing a database. 382 00:21:05,246 --> 00:21:06,986 And shh, don't tell anybody. 383 00:21:07,876 --> 00:21:11,376 So like, yeah, a collection of documents definitely starts smelling 384 00:21:11,376 --> 00:21:13,336 quite a lot like a document database. 385 00:21:13,496 --> 00:21:17,446 There's sort of differences in data model and sort of a usage 386 00:21:17,446 --> 00:21:20,296 pattern compared to like how. 387 00:21:20,576 --> 00:21:24,236 Mainstream databases are built, you know, you can take MongoDB or even 388 00:21:24,236 --> 00:21:27,906 the JSON support in Postgres and they give you a JSON data model. 389 00:21:27,926 --> 00:21:31,586 And so in that sense, it's similar ish, but they don't really have 390 00:21:31,586 --> 00:21:32,846 the conflict resolution aspect. 391 00:21:32,866 --> 00:21:38,226 So they assume that all of your rights go to a single leader server and that 392 00:21:38,226 --> 00:21:40,196 server just serializes all of the updates. 393 00:21:40,256 --> 00:21:43,576 And therefore you never end up in a situation where you have to. 394 00:21:43,871 --> 00:21:46,221 merged to diverged versions of the document. 395 00:21:46,661 --> 00:21:49,271 Whereas in local-first, I mean, the whole point of local-first is that you 396 00:21:49,271 --> 00:21:51,091 have to data locally on your own device. 397 00:21:51,131 --> 00:21:53,691 So that means you inevitably end up in having to do this 398 00:21:53,691 --> 00:21:54,901 kind of conflict resolution. 399 00:21:54,901 --> 00:22:00,061 So even though the data model is maybe on a high level, similar to something 400 00:22:00,061 --> 00:22:04,421 like MongoDB, the data synchronization and the conflict resolution aspects. 401 00:22:04,711 --> 00:22:08,751 is something that's very different from a server oriented database. 402 00:22:08,751 --> 00:22:12,991 So you could say it's a more client oriented database where it is intended 403 00:22:12,991 --> 00:22:15,031 to be embedded into client software. 404 00:22:15,101 --> 00:22:19,721 And that would get us quite close to, I think, what Automerge wants to be. 405 00:22:19,911 --> 00:22:23,491 So we have the beginnings of something like that in a library called 406 00:22:23,491 --> 00:22:27,981 Automerge repo, which is it's sort of a wrapper library around Automerge. 407 00:22:28,301 --> 00:22:31,281 Automerge itself is basically just an in memory data structure library. 408 00:22:31,321 --> 00:22:31,681 It does. 409 00:22:32,136 --> 00:22:37,406 Nothing with disk or network, it's just purely an in memory data structure, but 410 00:22:37,436 --> 00:22:40,106 Automerge repo adds the IO layer to it. 411 00:22:40,206 --> 00:22:44,346 And so it provides adapters for like storing data, storing documents on 412 00:22:44,346 --> 00:22:48,436 disk and loading them again, and for synchronizing things over the network. 413 00:22:48,496 --> 00:22:51,026 And it also manages a collection of documents. 414 00:22:51,186 --> 00:22:55,301 And so this is how the whole thing starts looking a bit more like a database. 415 00:22:55,411 --> 00:22:59,751 Another difference I would also note compared to something like MongoDB is 416 00:22:59,781 --> 00:23:04,601 that a lot of these server side databases assume that a single document actually 417 00:23:04,611 --> 00:23:06,311 doesn't get updated all that often. 418 00:23:06,431 --> 00:23:09,451 though you know, you might do 100 writes to a document over 419 00:23:09,471 --> 00:23:10,631 the lifetime of a document. 420 00:23:10,761 --> 00:23:15,171 Whereas the types of Documents we're thinking about every keystroke when you're 421 00:23:15,171 --> 00:23:17,641 writing a text is a right to the document. 422 00:23:17,751 --> 00:23:20,951 And so you can easily accumulate hundreds of thousands of rights to a 423 00:23:20,951 --> 00:23:22,501 document over the lifetime of a document. 424 00:23:22,891 --> 00:23:28,241 And if you have that sort of high rate of updates, that forces entirely different 425 00:23:28,241 --> 00:23:29,701 data structures and data formats. 426 00:23:30,301 --> 00:23:34,666 so I think if you try to use MongoDB or Postgres, And, you know, write a 427 00:23:34,666 --> 00:23:37,666 new version of a document on every keystroke, they would not perform very 428 00:23:37,666 --> 00:23:41,256 well because they actually write an entire new copy of the document to disk 429 00:23:41,266 --> 00:23:43,176 every time you update the document. 430 00:23:43,426 --> 00:23:46,726 And, you know, that's just not going to work if you're making hundreds of 431 00:23:46,726 --> 00:23:48,516 thousands of updates to a single document. 432 00:23:48,756 --> 00:23:53,406 And so that's why Automerge then has got a whole bunch of clever data 433 00:23:53,406 --> 00:23:58,036 structures and file formats in order to deal with those very frequent, very 434 00:23:58,036 --> 00:23:59,976 frequent, but small updates to documents. 435 00:24:00,536 --> 00:24:06,566 So I'm personally, as an app developer, I try to think about like, what is 436 00:24:06,576 --> 00:24:08,686 the best foundation to build an app? 437 00:24:08,706 --> 00:24:12,806 And so you've mentioned that the early prototypes that you've built for what 438 00:24:12,806 --> 00:24:18,126 later became Automerge, you built with Ruby, maybe you probably built apps with 439 00:24:18,126 --> 00:24:22,326 Rails in the past and Rails was really a great foundation to build a new app. 440 00:24:22,946 --> 00:24:23,796 I'm wondering. 441 00:24:24,026 --> 00:24:30,826 In the next five to 10 years, when you put on your local-first lens, like what 442 00:24:30,826 --> 00:24:34,876 is the rails equivalent for local-first? 443 00:24:34,896 --> 00:24:40,046 Should I think about Automerge becoming more and more like a new 444 00:24:40,076 --> 00:24:44,416 kind of rails that's less of an app framework, but more of like a. 445 00:24:44,961 --> 00:24:49,841 A data framework that takes over more and more app framework responsibilities. 446 00:24:50,051 --> 00:24:52,181 Can you paint a bit of that picture for me? 447 00:24:52,531 --> 00:24:54,701 I think the analogy is really good, actually. 448 00:24:54,721 --> 00:24:59,311 I, yeah, I would think of Automerge maybe like as the active record component of 449 00:24:59,311 --> 00:25:01,531 Rails or so it's the data component. 450 00:25:01,551 --> 00:25:04,621 it's not a whole app framework by itself, but you could definitely 451 00:25:04,631 --> 00:25:08,304 imagine building an app framework where it's an important part of it. 452 00:25:08,509 --> 00:25:12,519 And the rest of the app framework would have to do stuff like reactivity of 453 00:25:12,569 --> 00:25:17,989 updating the user interface in response to edits that have happened and figuring 454 00:25:17,989 --> 00:25:21,279 out how to handle user inputs, blah, blah, blah, all that sort of things. 455 00:25:21,939 --> 00:25:26,329 So I think that framework doesn't exist yet, but I would really love 456 00:25:26,329 --> 00:25:32,189 to see somebody build the equivalent of rails, for local-first software. 457 00:25:32,659 --> 00:25:34,839 So what are the missing pieces for that? 458 00:25:34,899 --> 00:25:39,559 So you've mentioned that the way how you and Peter have met is through 459 00:25:39,559 --> 00:25:41,319 Peter's previous work on Heroku. 460 00:25:42,149 --> 00:25:46,179 So Heroku, I think, played a major role in making rails. 461 00:25:46,259 --> 00:25:46,759 So. 462 00:25:47,284 --> 00:25:50,924 Easy for developers since it's not just easy to work with it locally, but it's 463 00:25:50,934 --> 00:25:53,214 also easy to roll it out into production. 464 00:25:53,634 --> 00:25:58,714 So what does it mean for me right now, if I'm building my first little app, my first 465 00:25:58,714 --> 00:26:03,234 little prototype with Automerge locally, what does it mean for me to roll that out, 466 00:26:03,244 --> 00:26:07,524 that I can share it with my friends and use it sort of in a, in a bigger scale? 467 00:26:07,734 --> 00:26:07,964 Yeah. 468 00:26:07,964 --> 00:26:11,554 So at the moment It still requires a fair amount of. 469 00:26:12,229 --> 00:26:13,499 The stuff you have to write yourself. 470 00:26:13,629 --> 00:26:17,199 So for example, you know, we provide as part of automated repos, some 471 00:26:17,199 --> 00:26:19,159 integrations with like React or. 472 00:26:19,609 --> 00:26:23,759 It's failed to also as examples of how you can build use interfaces 473 00:26:23,759 --> 00:26:27,459 on top of Automerge, but you know, it's very just basic example code. 474 00:26:27,719 --> 00:26:31,739 I think it's not like an entire framework, but it's something that hopefully 475 00:26:31,739 --> 00:26:33,299 people can use to start building apps. 476 00:26:34,129 --> 00:26:36,629 Likewise for like the network synchronization. 477 00:26:37,174 --> 00:26:40,984 We have a sync server, it's open source and quite simple, and you can just 478 00:26:41,134 --> 00:26:44,594 deploy it yourself, but it lacks all of the features that you might want. 479 00:26:44,594 --> 00:26:48,584 So there's no authentication, for example, which is something 480 00:26:48,704 --> 00:26:49,824 probably most apps will want. 481 00:26:50,174 --> 00:26:53,734 Really, we would like end to end encryption for the data synchronization 482 00:26:53,754 --> 00:26:57,864 for many applications as well, so the server doesn't have to store 483 00:26:57,864 --> 00:27:01,804 the plain text of your documents and a whole bunch of other things 484 00:27:01,894 --> 00:27:03,324 related to synchronization. 485 00:27:03,374 --> 00:27:05,274 So I think we will always want. 486 00:27:05,694 --> 00:27:08,644 The option for people to develop these things themselves and run 487 00:27:08,644 --> 00:27:09,894 it themselves if they want to. 488 00:27:10,114 --> 00:27:14,534 But at the same time, I think there's a lot that could happen around having 489 00:27:14,534 --> 00:27:17,854 it's kind of packaged up in a nicer way where maybe there's a hosted cloud 490 00:27:17,854 --> 00:27:22,814 service that just provides a syncing service for local-first apps and if you. 491 00:27:23,169 --> 00:27:27,159 Choose a certain framework which might be Automerge based and a certain 492 00:27:27,189 --> 00:27:30,789 networking layer, then you can just use this synchronization service and 493 00:27:30,909 --> 00:27:32,589 you don't have to run your own servers. 494 00:27:32,649 --> 00:27:37,089 And that would be the sort of Heroku equivalent I would see of, of this world. 495 00:27:37,269 --> 00:27:39,559 So I really hope somebody builds that. 496 00:27:39,689 --> 00:27:44,379 and a part of the vision of local-first is that, you know, we'll probably 497 00:27:44,379 --> 00:27:48,549 have to have cloud services involved in this data synchronization, but 498 00:27:48,549 --> 00:27:52,299 if we can make the synchronization protocols an open standard. 499 00:27:52,514 --> 00:27:55,954 Then hopefully there can be multiple different providers that can interoperate. 500 00:27:55,974 --> 00:28:00,004 And so if it decides that one particular provider has changed their pricing 501 00:28:00,004 --> 00:28:02,674 in a way that's too expensive or they're too unreliable or whatever. 502 00:28:03,114 --> 00:28:05,504 You should be able to just point your app at a different provider 503 00:28:05,534 --> 00:28:06,864 and just continue working. 504 00:28:07,414 --> 00:28:10,924 And in some way, like Heroku had this as well, in that, you know, you didn't 505 00:28:10,924 --> 00:28:15,154 have to write custom, you have to use custom Heroku APIs to write your 506 00:28:15,154 --> 00:28:18,414 app, anything, you know, you just write a standard Rails app and you 507 00:28:18,434 --> 00:28:20,194 deploy it by pushing to a Git repo. 508 00:28:20,194 --> 00:28:23,224 And there was just a small amount of Heroku specific configuration. 509 00:28:23,434 --> 00:28:26,634 And if you wanted to, you would always be able to take your app and run it on 510 00:28:26,634 --> 00:28:28,244 a different hosting provider as well. 511 00:28:28,594 --> 00:28:33,199 And so again, I think that's sort of Style I would like for local-first software 512 00:28:33,199 --> 00:28:38,419 too, that we have this interoperability and we have multiple companies, could 513 00:28:38,429 --> 00:28:40,059 be startups, could be big companies. 514 00:28:40,059 --> 00:28:44,199 I don't really mind providing this kind of cloud syncing services for 515 00:28:44,199 --> 00:28:48,569 local-first software in such a way that it can interop and you can easily 516 00:28:48,569 --> 00:28:49,999 switch from one provider to another. 517 00:28:50,089 --> 00:28:54,349 I think that that would be really my dream for an ecosystem that's working well. 518 00:28:54,909 --> 00:28:56,169 That sounds incredible. 519 00:28:56,169 --> 00:28:58,479 and I'd love to love to see that. 520 00:28:58,479 --> 00:29:02,069 It kind of makes me a bit reminiscent of the days of like 521 00:29:02,139 --> 00:29:04,449 torrenting, et cetera, peer to peer. 522 00:29:04,659 --> 00:29:09,579 We've talked to Peter in, uh, in a previous episode about peer to peer and 523 00:29:09,579 --> 00:29:14,589 there's some real technical challenges that we, that need to be overcome and 524 00:29:14,589 --> 00:29:18,969 maybe can't be overcome in the, in the shorter term, but I'm wondering. 525 00:29:19,349 --> 00:29:23,939 How that sort of more abstract syncing service would compare to 526 00:29:23,939 --> 00:29:25,549 some of the existing technologies. 527 00:29:25,549 --> 00:29:29,339 I've mentioned peer to peer there because what was so interesting about 528 00:29:29,339 --> 00:29:33,439 it is like that, it's that you formed the sort of ad hoc network where 529 00:29:33,439 --> 00:29:36,589 people didn't, there was no server where it's something needed to be. 530 00:29:37,019 --> 00:29:40,249 deploy to, but things just started working together. 531 00:29:40,279 --> 00:29:44,579 So with that syncing service that you're mentioning, that could be kind 532 00:29:44,579 --> 00:29:49,909 of a platform agnostic, would that be similar to peer to peer in that regard? 533 00:29:50,209 --> 00:29:54,009 Or would you still need to kind of deploy a quote unquote backend 534 00:29:54,039 --> 00:29:58,739 app to that syncing service that it actually does perform the work 535 00:29:58,739 --> 00:30:02,669 you want to have performed for your particular local-first step? 536 00:30:02,979 --> 00:30:03,479 I think. 537 00:30:03,689 --> 00:30:09,389 The best results for, you know, for user quality of software would be for it to 538 00:30:09,399 --> 00:30:13,479 use peer to peer when it's available and use a cloud service when not. 539 00:30:13,629 --> 00:30:17,469 I think doing only peer to peer is really difficult because, for example, 540 00:30:17,479 --> 00:30:20,369 you can only talk to another peer while it's online at the same time. 541 00:30:20,409 --> 00:30:22,559 And if you've got two devices that are never online at the 542 00:30:22,559 --> 00:30:25,149 same time, then you can never synchronize data with between them. 543 00:30:25,379 --> 00:30:25,559 So. 544 00:30:26,154 --> 00:30:29,904 That sucks pretty badly because people do just close their laptop from time to time 545 00:30:29,904 --> 00:30:31,854 or turn off their smartphone or whatever. 546 00:30:32,124 --> 00:30:36,074 So I think pure peer to peer just doesn't work reliably enough. 547 00:30:36,134 --> 00:30:40,674 Plus there's all of the problems with like NAT traversal and just the networking 548 00:30:40,674 --> 00:30:42,224 infrastructure doesn't work well enough. 549 00:30:42,304 --> 00:30:44,764 However, when peer to peer does work, it's amazing. 550 00:30:44,804 --> 00:30:48,534 And so if you've got two devices on the same network in the same building, it 551 00:30:48,624 --> 00:30:54,829 seems outrageous to send all of your data via AWS US East One in Virginia, 552 00:30:54,979 --> 00:30:59,289 if you could just send it via the local wifi from one device to another, right? 553 00:30:59,389 --> 00:31:03,229 So then opportunistically using peer to peer when it happens to 554 00:31:03,239 --> 00:31:05,429 be available is an amazing thing. 555 00:31:05,539 --> 00:31:08,649 And it's, you know, it provides a lot of robustness and 556 00:31:08,679 --> 00:31:10,449 independence from the network. 557 00:31:10,449 --> 00:31:13,549 So that, for example, if you've got your laptop and your phone, and you're 558 00:31:13,549 --> 00:31:16,809 in some remote location where you don't have internet access, you can still 559 00:31:16,819 --> 00:31:18,319 sync data between the two of them. 560 00:31:18,444 --> 00:31:21,214 And, you know, we have a sort of rudimentary version of that with 561 00:31:21,284 --> 00:31:25,784 say, AirDrop on Apple devices, but that's like one off file transfers 562 00:31:25,784 --> 00:31:29,414 really should be able to just do that for live synchronization as well. 563 00:31:29,494 --> 00:31:33,804 So I feel like the combination of Cloud and peer to peer just 564 00:31:33,804 --> 00:31:35,094 gives you capabilities that. 565 00:31:35,624 --> 00:31:37,664 only cloud or only peer to peer doesn't. 566 00:31:37,834 --> 00:31:40,924 And so that really seems to me like the most promising 567 00:31:40,974 --> 00:31:42,784 direction is to combine the two. 568 00:31:42,954 --> 00:31:46,134 And the nice thing with CRDTs is that they just don't care what 569 00:31:46,134 --> 00:31:47,424 your networking layer is, right? 570 00:31:47,834 --> 00:31:51,264 All you need is some way of getting some bytes from one device to another. 571 00:31:51,524 --> 00:31:52,074 That's all they need. 572 00:31:52,224 --> 00:31:56,744 And whether that goes via a local network or peer to peer over the internet via 573 00:31:56,794 --> 00:32:01,614 a distributed hash table or via a cloud service or via multiple cloud services. 574 00:32:01,614 --> 00:32:06,264 CRDT doesn't care that any communication channel will do. 575 00:32:06,804 --> 00:32:08,514 That makes a, makes a lot of sense. 576 00:32:08,514 --> 00:32:13,284 And this sort of hybrid nature where it optimistically uses the close peer 577 00:32:13,304 --> 00:32:17,534 connection, where if that works, then the experience is even better, but it kind of 578 00:32:17,534 --> 00:32:20,594 falls back to the cloud where it needs to. 579 00:32:20,594 --> 00:32:25,054 And it also will give you some benefits maybe such as backup, et cetera. 580 00:32:25,054 --> 00:32:27,464 So that future sounds amazing. 581 00:32:27,644 --> 00:32:29,944 So one thing with these cloud services. 582 00:32:30,114 --> 00:32:34,494 Is that, you know, in the traditional way of building web apps, a lot of your 583 00:32:34,854 --> 00:32:36,834 application logic lives in the backend. 584 00:32:36,864 --> 00:32:40,784 You know, you have a backend database running on a server and then you wrap it 585 00:32:40,784 --> 00:32:46,074 with some server side code written using some server side web framework, and then 586 00:32:46,074 --> 00:32:47,694 you put it all behind a load balancer. 587 00:32:47,704 --> 00:32:50,794 And so you've got this, all this huge infrastructure on the backend. 588 00:32:50,974 --> 00:32:54,194 And one of the promises I see of local-firsts. 589 00:32:54,679 --> 00:32:58,199 Is that actually because we've moved all of the interesting application 590 00:32:58,199 --> 00:33:03,189 logic to the client app, to the end user device, the server side that remains 591 00:33:03,189 --> 00:33:07,169 can be really simple and actually not contain any app specific code at all. 592 00:33:07,219 --> 00:33:12,619 so my vision for these syncing services for local-first software 593 00:33:13,049 --> 00:33:15,689 is that there's virtually no application code on the server. 594 00:33:16,454 --> 00:33:19,974 The server is just this generic piece of software where you just 595 00:33:19,974 --> 00:33:21,234 take it off the shelf and run it. 596 00:33:21,364 --> 00:33:23,914 And, you know, you can just use a hosted cloud service. 597 00:33:24,054 --> 00:33:29,284 Maybe AWS will run a local-first backend service and charge you a 598 00:33:29,284 --> 00:33:31,494 few cents per gigabyte to use it. 599 00:33:31,524 --> 00:33:32,494 And that would be amazing. 600 00:33:32,664 --> 00:33:34,824 It can be, you know, this generic thing. 601 00:33:34,844 --> 00:33:38,534 So you don't have every single app reinventing its own backend service. 602 00:33:38,784 --> 00:33:43,504 You know, so much work in building a web app goes into reinventing this 603 00:33:43,554 --> 00:33:46,734 backend infrastructure that every single company has to reinvent again. 604 00:33:47,024 --> 00:33:51,734 And so if we can make the data sync protocol and the data storage on the 605 00:33:51,734 --> 00:33:55,584 servers efficient, like loading and synchronization of large collections of 606 00:33:55,684 --> 00:33:57,484 documents, all of that can be generic. 607 00:33:57,544 --> 00:34:00,694 So if one person is then building a graphics app and another person 608 00:34:00,694 --> 00:34:03,254 is building a spreadsheet and another person is building a 609 00:34:03,844 --> 00:34:05,644 document editor, they can all use. 610 00:34:05,644 --> 00:34:10,704 The same syncing service as the backend that I think is part of the economic 611 00:34:10,704 --> 00:34:14,434 value proposition of, local-first software is that actually, you know, 612 00:34:14,434 --> 00:34:17,554 we can just save ourselves a huge amount of software engineering work 613 00:34:17,724 --> 00:34:19,854 by making these backends generic. 614 00:34:20,344 --> 00:34:22,344 I couldn't agree more with that vision. 615 00:34:22,384 --> 00:34:23,899 I totally want that. 616 00:34:24,039 --> 00:34:27,139 Do you think Automerge will be the foundation for that? 617 00:34:27,179 --> 00:34:32,989 Is there something more generic, something more abstract of like an open syncing 618 00:34:33,019 --> 00:34:34,849 protocol, whatever that might be? 619 00:34:35,159 --> 00:34:40,939 and Automerge would be one of multiple that implement compatibility with that. 620 00:34:41,449 --> 00:34:45,459 If someone is interested in that vision right now, is there anything that 621 00:34:45,469 --> 00:34:49,989 someone can take a look at and maybe deploy an early version of that already? 622 00:34:50,454 --> 00:34:55,904 Yeah, I think Automerge is trying to be a solution for that, and I would 623 00:34:55,904 --> 00:35:00,424 love for the Automerge protocols to be open standards one day. 624 00:35:00,754 --> 00:35:04,424 I think, you know, we've thought about engaging with the IETF, for example, 625 00:35:04,434 --> 00:35:07,474 for standardization, although I think right now is just too early because 626 00:35:08,024 --> 00:35:11,294 it's all still very much work in progress and it hasn't settled enough 627 00:35:11,304 --> 00:35:13,124 yet to be ready for standardization. 628 00:35:13,329 --> 00:35:15,659 But in the long term, that's something we would definitely like. 629 00:35:15,899 --> 00:35:19,169 And we would like there to be multiple interoperable implementations that 630 00:35:19,169 --> 00:35:22,559 can all talk to each other and which are compatible with each other. 631 00:35:22,719 --> 00:35:25,769 So yes, whether that ends up being exactly the Automerge wire 632 00:35:25,769 --> 00:35:29,389 protocol or something a bit more abstract, I I'm not entirely sure. 633 00:35:29,539 --> 00:35:32,009 I mean, other people are working on similar things. 634 00:35:32,089 --> 00:35:36,559 So one project that comes to mind is braid, for example, which they are 635 00:35:36,759 --> 00:35:42,249 engaging with the IETF and they're trying to build some standards or extensions 636 00:35:42,489 --> 00:35:45,249 to HTTP to enable data synchronization. 637 00:35:45,319 --> 00:35:49,579 And they're trying to do it in a way which is not specific to any particular CRDT 638 00:35:49,579 --> 00:35:53,809 library or even using other approaches such as operational transformation. 639 00:35:53,819 --> 00:35:55,149 So they're trying to be generic. 640 00:35:55,279 --> 00:35:58,599 What I'm not sure yet is whether you can be generic and still 641 00:35:58,599 --> 00:35:59,699 get good enough performance. 642 00:35:59,909 --> 00:36:00,949 that's a trade off there. 643 00:36:00,999 --> 00:36:03,899 So in the automotive sync protocol, we're able to make a lot of optimizations. 644 00:36:04,944 --> 00:36:09,324 because we know a lot about the types of data and how they're exchanged and 645 00:36:09,334 --> 00:36:13,724 we can control the data compression and the data formats and so on. 646 00:36:13,824 --> 00:36:18,124 Because we control the stack, we can do a lot of interesting optimizations 647 00:36:18,184 --> 00:36:21,764 there, which are more difficult if you have a generic protocol. 648 00:36:21,794 --> 00:36:26,379 So I think that waits to be, we'll have to wait and see how 649 00:36:26,389 --> 00:36:27,709 that develops in the future. 650 00:36:27,749 --> 00:36:31,989 And I certainly believe some kind of protocol will become a widely 651 00:36:31,999 --> 00:36:36,169 used open standard for synchronous for data sync in local-first apps. 652 00:36:36,169 --> 00:36:38,519 It might be Automerge or it might be something else, but that's 653 00:36:38,769 --> 00:36:40,509 generally the direction we're heading. 654 00:36:41,029 --> 00:36:43,879 I'm really looking forward to that point. 655 00:36:43,899 --> 00:36:46,639 I mean, local-first already today. 656 00:36:47,014 --> 00:36:52,434 Is providing so much value, both to developers and to end users by 657 00:36:52,794 --> 00:36:56,604 simplifying the developer experience by making apps faster, giving 658 00:36:56,604 --> 00:36:58,594 you data ownership, et cetera. 659 00:36:58,864 --> 00:37:01,844 But I think once we've reached that point where there's a more. 660 00:37:02,089 --> 00:37:07,329 General purpose, generic syncing service that works possibly also across apps 661 00:37:07,469 --> 00:37:12,129 that people can put a little node of that, for example, on a Raspberry Pi 662 00:37:12,159 --> 00:37:14,039 running next to their home router. 663 00:37:14,399 --> 00:37:16,259 I'm really looking forward to that. 664 00:37:16,259 --> 00:37:17,599 So I can't wait for that. 665 00:37:17,919 --> 00:37:21,359 Looking forward to maybe having you back in a year from now to hear 666 00:37:21,359 --> 00:37:25,129 some more progress update where things add in that regard, but I'm 667 00:37:25,129 --> 00:37:26,349 really looking forward to that. 668 00:37:26,804 --> 00:37:29,194 Yeah, it's good to be very exciting to see what people build. 669 00:37:30,204 --> 00:37:37,354 So besides your work on Automerge, you're also involved in the new project called 670 00:37:37,354 --> 00:37:44,294 Bluesky, which came out of Twitter or now called X as I think was sort of also like 671 00:37:44,294 --> 00:37:46,864 a research project inside of Twitter. 672 00:37:46,914 --> 00:37:49,304 And that was now took its own path. 673 00:37:49,584 --> 00:37:52,084 So, and you're involved there as an advisor. 674 00:37:52,484 --> 00:37:56,414 I'm wondering whether there's any connection to your interest 675 00:37:56,444 --> 00:37:59,634 in local-first as well, or whether those are separate paths. 676 00:38:00,544 --> 00:38:03,324 That is a sort of, um, high level connection. 677 00:38:03,324 --> 00:38:08,819 I would say, you know, Bluesky is a social network it's decentralized and it aims 678 00:38:08,949 --> 00:38:14,339 to provide a bunch of features which just don't exist on like Twitter and 679 00:38:14,339 --> 00:38:16,569 Facebook and a centralized social network. 680 00:38:16,599 --> 00:38:20,609 So in particular, it's built on an open protocol and there are multiple 681 00:38:20,979 --> 00:38:24,269 different implementations, interoperable implementations of that protocol. 682 00:38:24,724 --> 00:38:28,944 And moreover, multiple hosting providers that can run 683 00:38:29,034 --> 00:38:30,354 different parts of the system. 684 00:38:30,834 --> 00:38:35,514 And Bluesky is designed in such a way that it's very easy to move your account 685 00:38:35,524 --> 00:38:37,404 from one provider to another, for example. 686 00:38:37,484 --> 00:38:41,654 So for example, if you don't agree with one provider's moderation policies, 687 00:38:42,544 --> 00:38:45,754 it's fine, you can go to a different one, who's more aligned with you, or 688 00:38:45,754 --> 00:38:49,214 you could even run your own if you're technically, enthusiastic enough. 689 00:38:49,324 --> 00:38:51,654 So on a technical level, a lot of the implementation of. 690 00:38:52,009 --> 00:38:55,279 Bluesky looks quite different from something like Automerge. 691 00:38:55,279 --> 00:38:59,479 There's no CRDTs in Bluesky, for example, but the sort of philosophy and the 692 00:38:59,479 --> 00:39:04,459 values that it embeds in the software are actually quite similar to local-first. 693 00:39:04,519 --> 00:39:08,859 This idea that users should control their own data, you know, you should 694 00:39:09,119 --> 00:39:12,509 always be able to have a copy of your own data that you can just take with 695 00:39:12,509 --> 00:39:14,399 you or move to a different provider. 696 00:39:14,519 --> 00:39:15,299 That concept is. 697 00:39:15,814 --> 00:39:20,234 Exists very much across both local-first and Bluesky in the case of Bluesky, of 698 00:39:20,234 --> 00:39:21,794 course, you know, it's a social network. 699 00:39:21,794 --> 00:39:25,664 So the entire social network consists of the data from many different people, the 700 00:39:25,664 --> 00:39:27,684 posts, the likes, the follows and so on. 701 00:39:27,694 --> 00:39:31,514 But the way it works is that all of the data from a particular user goes 702 00:39:31,544 --> 00:39:35,464 into a repository, which you can think of a bit like as a git repository. 703 00:39:35,954 --> 00:39:41,054 And so every post that you make, every user you follow, every like you make. 704 00:39:41,639 --> 00:39:45,149 Every user action of your own goes into your own repository, and that is your 705 00:39:45,149 --> 00:39:48,589 own, and you can download a copy of it, and on the server, it's literally just 706 00:39:48,589 --> 00:39:51,839 a SQLite database, there's a separate SQLite database for every single user, 707 00:39:52,019 --> 00:39:55,569 and you can just get a copy of it, and even if your provider just suddenly 708 00:39:55,569 --> 00:39:57,449 disappears, you can upload a copy of that. 709 00:39:58,084 --> 00:40:02,144 To a different provider, change your user ID to point to the new provider 710 00:40:02,264 --> 00:40:03,824 and everything just continues working. 711 00:40:03,904 --> 00:40:08,694 And so that idea of having easy interoperability and easy migration 712 00:40:08,694 --> 00:40:13,074 paths from one provider to another, that's something that I think both 713 00:40:13,144 --> 00:40:15,564 Bluesky and local-first share. 714 00:40:15,644 --> 00:40:18,324 But then the, otherwise the implementations end up being different. 715 00:40:18,334 --> 00:40:21,674 Like it doesn't really make sense to have a local-first social network, because for 716 00:40:21,674 --> 00:40:25,294 example, working offline makes sense if you're talking about a document editor. 717 00:40:25,724 --> 00:40:28,264 It doesn't really make sense in a social network because the whole point 718 00:40:28,264 --> 00:40:31,474 is communicating with other people so that the offline aspects, for example, 719 00:40:31,474 --> 00:40:36,464 don't really feature in Bluesky, but sort of the data ownership aspects do. 720 00:40:37,084 --> 00:40:41,984 I agree that there is a big difference between a social network like Bluesky. 721 00:40:42,329 --> 00:40:47,059 And more like productivity or personal apps, I'm still curious, 722 00:40:47,069 --> 00:40:51,519 given that they share a bunch of similar values and some technical 723 00:40:51,529 --> 00:40:57,099 similarities to better understand what if you were to try to build Bluesky 724 00:40:57,149 --> 00:40:59,139 with a more local-first approach. 725 00:40:59,199 --> 00:41:02,969 There's a few technologies that leverage syncing behavior for 726 00:41:02,969 --> 00:41:08,089 SQLite or maybe replacing SQLite with Automerge just in theory. 727 00:41:08,339 --> 00:41:12,919 I'd be very curious to understand, is there a certain impedance mismatch 728 00:41:13,129 --> 00:41:17,969 that you'd be running into by trying to build something like a social 729 00:41:17,969 --> 00:41:20,649 network with a local-first approach? 730 00:41:20,709 --> 00:41:24,369 I'd be curious to understand where you really run into troubles there. 731 00:41:24,584 --> 00:41:28,414 Yeah, so the data for one individual user, you could easily put in 732 00:41:28,414 --> 00:41:31,914 an Automerge document just as well as you put it in SQLite. 733 00:41:32,174 --> 00:41:34,364 I think that that would make fairly little difference that you 734 00:41:34,364 --> 00:41:38,104 could certainly use Automerge to synchronize the data for a given user. 735 00:41:38,264 --> 00:41:42,264 What's different in a social network is that you have these global 736 00:41:42,274 --> 00:41:46,014 views, which are aggregated over everybody, which is just not something 737 00:41:46,134 --> 00:41:47,254 that exists in a document editor. 738 00:41:47,604 --> 00:41:49,854 So like in a social network, you know, want to know all of 739 00:41:49,854 --> 00:41:50,924 the likes on a particular post. 740 00:41:51,509 --> 00:41:56,029 And if each user writes their like to their own repository, that means you 741 00:41:56,029 --> 00:41:59,119 have to index all of the repositories, look for all of the repositories that 742 00:41:59,129 --> 00:42:02,779 contain a like of a particular content, piece of content, and then add them up. 743 00:42:02,789 --> 00:42:04,179 And that gives you your number of likes. 744 00:42:04,289 --> 00:42:07,589 Or if you want to get all of the replies on a particular thread, again, you 745 00:42:07,589 --> 00:42:10,529 have to look at all of the posts that have been made by any user anywhere 746 00:42:10,529 --> 00:42:14,529 in the network and find all the sign reply to a particular piece of content. 747 00:42:14,579 --> 00:42:18,959 That just requires this kind of global view of everything, if you want to do 748 00:42:18,969 --> 00:42:24,009 it properly, you can kind of do it in a somewhat local version, which is kind of 749 00:42:24,009 --> 00:42:26,099 what ActivityPub and Mastodon try to do. 750 00:42:26,109 --> 00:42:29,559 So there's no global index in with Mastodon. 751 00:42:29,579 --> 00:42:33,489 There's, you know, no, nobody really maintains a copy of the entire network, 752 00:42:33,519 --> 00:42:39,069 but if user A replies to user B, then the User A's server sends a notification 753 00:42:39,069 --> 00:42:43,319 to user B's server, and therefore user B's server finds out about this reply, 754 00:42:43,379 --> 00:42:44,959 just adds it to its local database. 755 00:42:45,159 --> 00:42:49,189 But that way you can end up with a problem of different servers seeing 756 00:42:49,189 --> 00:42:54,529 different reply threads, because not every reply is notified to every server. 757 00:42:54,589 --> 00:42:59,074 And so then you get Weird inconsistencies are depending on which server you're on. 758 00:42:59,084 --> 00:43:02,874 You see a different set of replies to a particular post, which is a 759 00:43:02,874 --> 00:43:06,364 bit strange, but that's just a part of the way that Mastodon works. 760 00:43:06,364 --> 00:43:10,334 And that's something we try to avoid in Bluesky by instead saying, 761 00:43:10,334 --> 00:43:14,324 okay, like the individual repos is just a single user's data. 762 00:43:14,424 --> 00:43:17,979 And then in order to do something like a reply thread, Actually, we have a big 763 00:43:18,449 --> 00:43:22,539 indexing service that works a bit like a web search engine, which crawls the 764 00:43:22,539 --> 00:43:26,159 content of all of the individual user repositories and aggregates it all. 765 00:43:26,574 --> 00:43:27,894 And assembles the reply threads. 766 00:43:28,264 --> 00:43:31,864 And so that's something where there's no equivalent to that in local-first 767 00:43:31,884 --> 00:43:35,774 software, I think, because that's just something that like document editing 768 00:43:35,774 --> 00:43:37,034 style apps just don't need to do. 769 00:43:37,064 --> 00:43:40,654 They just don't need to actually do aggregations across many apps. 770 00:43:40,994 --> 00:43:44,544 I would say that maybe an exception to that is if you want to do search across 771 00:43:44,544 --> 00:43:47,844 many documents, for example, in that case, you do need to build a search index. 772 00:43:48,489 --> 00:43:52,759 But it's still a search index containing only the documents for a particular 773 00:43:52,799 --> 00:43:56,039 user, or maybe all of the documents for a particular company, but it's not all 774 00:43:56,119 --> 00:43:57,539 of the documents in the entire world. 775 00:43:57,909 --> 00:43:59,039 That makes a lot of sense. 776 00:43:59,049 --> 00:44:03,219 And I think it's sort of intuitive where like local-first starts out really dense 777 00:44:03,229 --> 00:44:07,719 about like your own documents, maybe the documents just on your other device 778 00:44:07,749 --> 00:44:09,869 or on the device of a friend of yours. 779 00:44:10,259 --> 00:44:15,559 So the network, the suspending is like still pretty dense and this is what 780 00:44:15,559 --> 00:44:20,209 makes all of those technologies work almost trivially, but the more you go 781 00:44:20,209 --> 00:44:25,579 global with this to sort of like social network level, this is where that, uh, 782 00:44:25,579 --> 00:44:29,549 is really put, put to the test and it's probably not the best starting point 783 00:44:30,029 --> 00:44:33,659 that being said, I think this might still also be an interesting project 784 00:44:33,659 --> 00:44:40,994 for some, some folks who might want to rebuild an app in a local-first way, but 785 00:44:41,024 --> 00:44:45,844 there might still be some more global nature to some parts of the data that 786 00:44:45,844 --> 00:44:48,714 maybe could be complimented in some way. 787 00:44:48,734 --> 00:44:51,734 Maybe there's some new architectural patterns that are emerging. 788 00:44:52,064 --> 00:44:57,334 for Overtone, for example, I'm trying to build the app in a local-first way, 789 00:44:57,354 --> 00:45:01,224 where really like all of the, your music metadata and actually your app. 790 00:45:01,694 --> 00:45:08,694 Your music data is locally available if possible, but music as such has 791 00:45:08,704 --> 00:45:13,094 also a very global aspect to it right in the world of Spotify, you have 792 00:45:13,154 --> 00:45:17,614 practically like infinite amounts of music that you can't just like all. 793 00:45:17,819 --> 00:45:23,449 locally download there's too much and also other people have other kinds of music. 794 00:45:23,729 --> 00:45:28,759 So I'm also trying to explore sort of hybrid solutions there, which are 795 00:45:28,799 --> 00:45:30,379 really interesting design challenges. 796 00:45:30,479 --> 00:45:34,449 I'm eager to share more of that on a separate occasion. 797 00:45:34,499 --> 00:45:37,399 And you've actually already provided me some great feedback and some 798 00:45:37,399 --> 00:45:39,029 personal conversations before. 799 00:45:39,619 --> 00:45:42,609 So, yeah, this is a really interesting case study in a. 800 00:45:42,854 --> 00:45:46,864 And I love exploring pushing local-first a little bit to its 801 00:45:46,884 --> 00:45:49,644 limits through various app use cases. 802 00:45:50,034 --> 00:45:54,674 So your involvement in Bluesky is a very interesting, at least 803 00:45:54,704 --> 00:45:56,694 theoretical case study at this point. 804 00:45:56,814 --> 00:46:01,734 So you've mentioning working offline for Bluesky. 805 00:46:01,949 --> 00:46:05,089 And that it might be not the primary use case. 806 00:46:05,329 --> 00:46:09,969 I want to use this as a segue, as I see a little bit of confusion sometimes 807 00:46:09,989 --> 00:46:15,739 on Twitter, where people synonymously talk about local-first and offline 808 00:46:15,759 --> 00:46:20,109 first, and there is a difference and I want to share a little bit 809 00:46:20,119 --> 00:46:24,719 more broadly what that difference is, what is a offline-first app? 810 00:46:24,739 --> 00:46:26,169 What is a local-first app? 811 00:46:26,429 --> 00:46:27,569 Where are they different? 812 00:46:27,569 --> 00:46:30,749 So maybe you can share your perspective on that topic. 813 00:46:31,179 --> 00:46:34,989 Yeah, I would say that local-first includes offline first, but it tries 814 00:46:34,989 --> 00:46:36,649 to be a lot more than that as well. 815 00:46:37,029 --> 00:46:40,529 So the term offline first existed long before local-first, and 816 00:46:40,529 --> 00:46:41,829 obviously we were aware of it. 817 00:46:41,939 --> 00:46:46,009 And in fact, we modeled the term local-first after offline first to some 818 00:46:46,009 --> 00:46:50,869 degree, because we thought it was a good term, and it captured something that we 819 00:46:50,869 --> 00:46:52,979 wanted, but it was not really sufficient. 820 00:46:53,129 --> 00:46:55,919 Because yes, having users being able to work offline is, 821 00:46:55,919 --> 00:46:57,519 it's Obviously a good idea. 822 00:46:57,519 --> 00:47:02,719 It seems ridiculous if people can't work offline, but we wanted to also 823 00:47:02,719 --> 00:47:07,639 capture this idea of personal data ownership so that the data is yours 824 00:47:07,679 --> 00:47:09,269 and it can't be taken away from you. 825 00:47:09,559 --> 00:47:14,774 So in particular, for example, if there's some software that Stops working. 826 00:47:14,824 --> 00:47:18,504 If the company that made the software goes out of business, then I would 827 00:47:18,514 --> 00:47:19,914 argue that's not local-first. 828 00:47:19,934 --> 00:47:21,774 So it could be offline first. 829 00:47:21,814 --> 00:47:25,314 So it could be that, you know, it's a nice Google Docs style document 830 00:47:25,314 --> 00:47:29,824 editor just take Google Docs as an example, like, okay, you know, it. 831 00:47:29,974 --> 00:47:30,754 It works fine. 832 00:47:30,824 --> 00:47:33,724 You can even, if you choose the right settings, make it work 833 00:47:33,724 --> 00:47:37,604 offline, and you can, you can edit your docs in whatever way you want. 834 00:47:37,734 --> 00:47:42,254 But if Google decides to just discontinue the service, hypothetically, or if 835 00:47:42,304 --> 00:47:46,504 Google just decides to block your account because some automated system has flagged 836 00:47:46,554 --> 00:47:50,624 you as violating the terms of service, whether you did or not doesn't matter. 837 00:47:50,844 --> 00:47:52,154 You basically have no recourse. 838 00:47:52,314 --> 00:47:54,904 And at that point, you're just locked out and you lose all of your data. 839 00:47:54,954 --> 00:48:00,139 And so The fact that the app allowed you to work offline is kind of beside 840 00:48:00,139 --> 00:48:03,519 the point then because you still don't have ownership of the data. 841 00:48:03,859 --> 00:48:07,869 And so it's that, this idea that you should not, never be 842 00:48:07,869 --> 00:48:09,009 locked out of your own data. 843 00:48:09,599 --> 00:48:13,379 That's really something that we wanted to capture in the idea of local-first. 844 00:48:13,839 --> 00:48:16,429 And so now if you can, can't be locked out of your data, that 845 00:48:16,729 --> 00:48:19,369 kind of implies that you must have the data on your own device. 846 00:48:19,919 --> 00:48:23,559 Which then also implies that you can probably edit it offline, because if 847 00:48:23,559 --> 00:48:27,639 you've got it locally anyway, then why not just enable offline editing? 848 00:48:28,279 --> 00:48:31,369 But the kind of the chain of reasoning goes in a different direction. 849 00:48:31,369 --> 00:48:34,719 We would start with the data ownership and then offline editing 850 00:48:34,719 --> 00:48:36,309 follows from that as a consequence. 851 00:48:36,854 --> 00:48:39,964 That makes a lot of sense, and I think that makes it really clear. 852 00:48:40,034 --> 00:48:44,574 I see a lot of people referring to offline first, almost synonymously as 853 00:48:44,734 --> 00:48:49,444 to some glorified version of aggressive caching, but the way how you lined it 854 00:48:50,034 --> 00:48:52,134 out here makes that a lot more clear. 855 00:48:52,154 --> 00:48:54,454 And I suppose this is not just having access. 856 00:48:54,844 --> 00:49:00,244 To some form of the data that you can like download a CSV from all of your user 857 00:49:00,244 --> 00:49:05,364 data, but that the software is actually still fully functional or as functional 858 00:49:05,434 --> 00:49:10,374 as somehow possible, even in the worst case where the folks who are building the 859 00:49:10,374 --> 00:49:12,894 software are no longer able to work on it. 860 00:49:13,384 --> 00:49:18,984 And to really provide a better alternative to SaaS software X shuts 861 00:49:18,984 --> 00:49:22,154 down and the entire app is just. 862 00:49:22,469 --> 00:49:24,609 It's gone with probably all of your data. 863 00:49:24,969 --> 00:49:28,129 So I think that's a really clear alternative. 864 00:49:28,299 --> 00:49:29,109 Yeah, exactly. 865 00:49:29,109 --> 00:49:33,739 Like I, you know, you do get this thing all the time when some SaaS, startup 866 00:49:33,759 --> 00:49:38,309 shuts down and they give you two weeks to download a zip file of JSON. 867 00:49:39,309 --> 00:49:41,079 You know, what can you do with that zip file of JSON? 868 00:49:41,099 --> 00:49:43,289 You can't re upload it into any other software. 869 00:49:43,289 --> 00:49:46,619 So basically it's just big fat middle finger to the users. 870 00:49:46,869 --> 00:49:52,689 So really local-first is an attempt to overcome that in a way that,, you 871 00:49:52,689 --> 00:49:55,969 know, at the very least, you know, for example, if the software can operate 872 00:49:55,969 --> 00:49:59,179 peer to peer, that could mean then at least you have a peer to peer fallback. 873 00:49:59,199 --> 00:50:02,449 So even if all of the cloud services go away, it could still operate. 874 00:50:02,569 --> 00:50:06,299 Or if it uses a backend service that's interoperable, so you can 875 00:50:06,299 --> 00:50:07,619 switch it to a different provider. 876 00:50:07,919 --> 00:50:11,509 That means then you could still use the software that, you know, maybe you 877 00:50:11,669 --> 00:50:16,869 purchase a license to the software in sort of the traditional non subscription type 878 00:50:16,889 --> 00:50:21,639 business model, and then you could use it in perpetuity, perhaps by pointing it at a 879 00:50:21,639 --> 00:50:24,939 different syncing backend, or in the worst case, running your own syncing backend, 880 00:50:24,939 --> 00:50:28,749 if you really must, but ideally just switching it over to a different provider. 881 00:50:28,859 --> 00:50:33,105 And I'm hoping that's like the local-first term should , try to encapsulate 882 00:50:33,105 --> 00:50:35,523 and capture those types of values. 883 00:50:35,863 --> 00:50:36,913 I fully agree. 884 00:50:36,973 --> 00:50:42,743 I'm curious now that you've been thinking about local-first now for more than 10 885 00:50:42,753 --> 00:50:48,803 years, and we've come really far in that period of time when it comes to CRDTs 886 00:50:49,373 --> 00:50:52,613 and Automerge is production ready to use. 887 00:50:52,828 --> 00:50:57,038 At the same time, given the ambitions that you've outlined for, it feels 888 00:50:57,038 --> 00:50:59,408 like we're just getting started. 889 00:50:59,648 --> 00:51:05,288 I do think that already is a good time to really switch your default instead 890 00:51:05,288 --> 00:51:09,928 of going cloud first, go local-first for app use cases where it's possible. 891 00:51:10,478 --> 00:51:14,178 But I think it's still very much the minority of developers. 892 00:51:14,503 --> 00:51:16,093 Who built this way. 893 00:51:16,113 --> 00:51:20,153 And given that you've seen such a broad spectrum of different data 894 00:51:20,153 --> 00:51:24,533 architectures that you've also outlined brilliantly in the book, Data Intensive 895 00:51:24,533 --> 00:51:31,643 Applications, I'm curious what you see as things that still hold back 896 00:51:32,013 --> 00:51:34,263 local-first to become more mainstream. 897 00:51:34,293 --> 00:51:38,233 Is it just a matter of time that there's more progress around 898 00:51:38,283 --> 00:51:40,603 Automerge around other technologies? 899 00:51:41,003 --> 00:51:43,533 Are there some other things that you would like to see? 900 00:51:44,033 --> 00:51:48,773 Yeah, I mean, there's, it's such a big conceptual shift, I think, which is a 901 00:51:48,773 --> 00:51:53,023 challenge, you know, because there's a huge amount of say, educational 902 00:51:53,023 --> 00:51:57,773 materials on how to build web apps, you know, entire university courses 903 00:51:57,773 --> 00:52:01,763 are built around the idea of teaching people how to do this thing, coding boot 904 00:52:01,803 --> 00:52:07,143 camps, documentation for huge amount of software projects, books, videos, you 905 00:52:07,143 --> 00:52:10,483 name it, you know, everything is that there's just so much infrastructure 906 00:52:10,493 --> 00:52:12,898 on teaching people how to build it. 907 00:52:13,068 --> 00:52:17,298 Apps in the centralized cloud way and local-first is just much newer. 908 00:52:17,298 --> 00:52:21,188 And so it hasn't had the benefits of decades of investment. 909 00:52:21,268 --> 00:52:23,758 Moreover, you know, there's the cloud providers have a strong 910 00:52:23,758 --> 00:52:26,498 commercial incentive to produce good quality documentation 911 00:52:26,498 --> 00:52:27,958 on how to use their services. 912 00:52:28,348 --> 00:52:32,258 So it's not surprising that there's good documentation available for those things. 913 00:52:32,418 --> 00:52:36,328 And I'm hoping that at some point there will be big companies built 914 00:52:36,338 --> 00:52:40,018 on the local-first paradigm as well, which then are similarly able to. 915 00:52:40,508 --> 00:52:44,658 Fund the development of this sort of documentation and learning 916 00:52:44,668 --> 00:52:47,508 materials and so on, but it's just going to take a while. 917 00:52:47,598 --> 00:52:51,378 So I would see that as probably one of the biggest challenges. 918 00:52:51,498 --> 00:52:54,978 It's just a new way of thinking and people are not familiar with it. 919 00:52:55,148 --> 00:53:00,748 I think once people get it, then a lot of people seem to get excited 920 00:53:00,748 --> 00:53:02,888 about it and buy into it as well. 921 00:53:02,948 --> 00:53:04,148 And, you know, sometimes there's. 922 00:53:04,983 --> 00:53:07,303 There's concerns that, you know, this is not for all apps. 923 00:53:07,303 --> 00:53:10,883 And I'm the first to acknowledge, yes, local-first is not for every single app. 924 00:53:10,883 --> 00:53:14,723 There's some apps which are best to build in a sort of centralized cloud way. 925 00:53:15,323 --> 00:53:15,983 That's totally fine. 926 00:53:16,183 --> 00:53:19,383 So I think part of it is also helping people understand for which 927 00:53:19,383 --> 00:53:22,513 types of apps would you pick a local-first approach versus for which 928 00:53:22,513 --> 00:53:24,833 do you pick a centralized approach. 929 00:53:24,943 --> 00:53:29,893 And then of course, like just the general ecosystem needs, needs a lot more work. 930 00:53:29,893 --> 00:53:33,203 So, you know, the software libraries that we use, things like Automerge 931 00:53:33,223 --> 00:53:37,708 are They're pretty robust already, but it's still fairly new software compared 932 00:53:37,738 --> 00:53:41,758 to, you know, a web framework that has been around for 20 years or more. 933 00:53:42,368 --> 00:53:46,258 Uh, so one thing that I find encouraging is just within the 934 00:53:46,258 --> 00:53:48,208 last year or so, it seems that. 935 00:53:48,738 --> 00:53:54,148 A whole bunch of startups have started using the local-first term just on 936 00:53:54,148 --> 00:53:59,358 their product marketing pages as just something they assume readers 937 00:53:59,358 --> 00:54:00,758 of the page will be familiar with. 938 00:54:01,018 --> 00:54:02,368 And that I find very encouraging. 939 00:54:02,368 --> 00:54:06,328 It's, it sort of shows that, you know, people are buying into the idea 940 00:54:06,398 --> 00:54:09,758 that enough that they are willing to, you know, have their product 941 00:54:09,988 --> 00:54:14,628 foundation on it and their marketing around it, explaining to users why 942 00:54:14,628 --> 00:54:16,638 it's valuable to have local-first. 943 00:54:16,828 --> 00:54:18,438 And I think this is the way it will succeed. 944 00:54:18,438 --> 00:54:21,968 You know, it's the local-first will succeed only if many, many people in 945 00:54:21,968 --> 00:54:25,208 many, many different companies are able to use it to their advantage in 946 00:54:25,208 --> 00:54:28,898 order to provide a better experience to their users and their customers. 947 00:54:29,128 --> 00:54:32,718 And Build sustainable businesses on top of the idea and so on. 948 00:54:32,718 --> 00:54:35,438 So It has to work for everybody. 949 00:54:35,438 --> 00:54:38,988 And I think it will work for everybody because it's, you know, it's a win win. 950 00:54:38,988 --> 00:54:40,768 it's good for the app developers. 951 00:54:40,768 --> 00:54:41,988 It's good for the users. 952 00:54:42,118 --> 00:54:45,438 I think questions still to be had about exactly what the business models look 953 00:54:45,438 --> 00:54:49,268 like, but I think that can probably also be figured out and then that 954 00:54:49,268 --> 00:54:50,988 way it works well across the board. 955 00:54:51,653 --> 00:54:56,893 Yeah, I love that observation and I agree, I think some of the favorite 956 00:54:56,893 --> 00:55:02,373 tools that I'm using, they are all like, maybe not adhering to all seven 957 00:55:02,573 --> 00:55:06,953 local-first principles, but directionally, they are going in the direction of 958 00:55:06,953 --> 00:55:12,423 local-first, and it's almost like a quality badge that some products associate 959 00:55:12,423 --> 00:55:16,373 themselves with say like, Hey, we're trying to build this app local-first. 960 00:55:16,393 --> 00:55:20,183 And I, as a user know, Oh, this means it's probably one of the 961 00:55:20,193 --> 00:55:22,293 fastest app experiences that I get. 962 00:55:22,633 --> 00:55:26,763 I feel much better about the data that I'm putting into it. 963 00:55:26,973 --> 00:55:29,973 So it's just, it gives me a much better baseline in terms 964 00:55:29,973 --> 00:55:32,013 of my expectations as a user. 965 00:55:32,513 --> 00:55:35,473 And I'm happy for the developers building it since they probably 966 00:55:35,473 --> 00:55:37,113 also have much more fun time. 967 00:55:37,183 --> 00:55:41,158 So, but you've also mentioned the question marks around the 968 00:55:41,168 --> 00:55:42,928 business model of local-first. 969 00:55:42,948 --> 00:55:48,418 And I remember from like the good old days when you downloaded software and 970 00:55:48,418 --> 00:55:53,058 you needed to buy it, you needed a serial number, but then there were also 971 00:55:53,108 --> 00:55:58,448 a large group of people who would just crack software and use it illegally. 972 00:55:58,903 --> 00:56:04,803 And I think at that point, it was really seen as a solution that SaaS would just 973 00:56:04,923 --> 00:56:07,443 rent out your software on a monthly basis. 974 00:56:07,933 --> 00:56:11,643 And that sort of solved, the entire pirated software problem. 975 00:56:12,093 --> 00:56:16,213 So I'm wondering, is local-first pointing in a direction to go 976 00:56:16,213 --> 00:56:18,333 back towards download software? 977 00:56:18,393 --> 00:56:19,253 Hopefully. 978 00:56:19,668 --> 00:56:24,718 Pay for that serial number, is there a best of both worlds, something that's not 979 00:56:24,728 --> 00:56:30,308 quite you rent your software AKA cloud and has all the problems, but maybe as 980 00:56:30,308 --> 00:56:36,548 a business, you do don't need to worry about pirated software and you get paid 981 00:56:36,558 --> 00:56:39,978 if you choose to have a paid plan as well. 982 00:56:40,168 --> 00:56:43,088 Do you have thoughts on what a business model in the local-first 983 00:56:43,108 --> 00:56:44,438 first world looks like? 984 00:56:44,548 --> 00:56:48,048 Yeah, I personally wouldn't mind going back to the model of license 985 00:56:48,048 --> 00:56:49,998 keys and perpetual licenses. 986 00:56:50,258 --> 00:56:54,658 I personally quite liked it, but I do totally understand that for the companies 987 00:56:54,658 --> 00:56:58,118 making the software, like having recurring revenue is really, really nice. 988 00:56:58,548 --> 00:57:01,648 Even besides the piracy things you mentioned. 989 00:57:01,788 --> 00:57:04,718 And to some extent, I think there's no nothing stopping people just. 990 00:57:05,018 --> 00:57:08,788 Doing subscription apps, if they're local-first as well, you know, just 991 00:57:08,788 --> 00:57:12,188 the fact that we've moved some of the logic from a server backend into 992 00:57:12,188 --> 00:57:15,688 the client doesn't stop you from being able to do a subscription. 993 00:57:16,008 --> 00:57:19,418 We can just tell people it's SaaS and sell it in the same way. 994 00:57:19,418 --> 00:57:21,058 And maybe that will work just fine. 995 00:57:21,188 --> 00:57:27,618 I mean, It is true that because we have this idea of the user data ownership 996 00:57:27,678 --> 00:57:32,838 in local-first, you can't quite hold a gun to the user's head in the same 997 00:57:32,838 --> 00:57:35,558 way and saying like, if you don't pay your subscription, we will delete 998 00:57:35,558 --> 00:57:39,438 all your data, which is something that cloud software can very much do. 999 00:57:39,578 --> 00:57:43,968 And so it's possible that that means that then, you know, more people will drop 1000 00:57:43,968 --> 00:57:45,598 off and stop paying the subscription. 1001 00:57:45,808 --> 00:57:46,668 You know, you could make this. 1002 00:57:46,998 --> 00:57:50,848 the software simply not work anymore if the user hasn't paid their subscription. 1003 00:57:50,848 --> 00:57:54,518 And of course, people could go in with a hex editor and change 1004 00:57:54,518 --> 00:57:56,618 it so that it remove that check. 1005 00:57:57,208 --> 00:57:59,708 But to be honest, not many people are going to do that probably. 1006 00:57:59,758 --> 00:58:01,978 If they did, they would be in the same category as the people 1007 00:58:01,978 --> 00:58:05,918 who did, who pirated licensed keys in the old software model. 1008 00:58:05,928 --> 00:58:09,068 Like there's no way you can extract any money from them anyway. 1009 00:58:09,893 --> 00:58:12,433 Basically, it's probably not worth worrying about them too much and 1010 00:58:12,433 --> 00:58:14,733 instead focus on those users. 1011 00:58:14,733 --> 00:58:16,743 You can monetize who will pay their bills. 1012 00:58:16,853 --> 00:58:19,313 And you know, as long as a reasonable percentage of the 1013 00:58:19,313 --> 00:58:21,183 people pay, that's still fine. 1014 00:58:21,283 --> 00:58:25,773 Peter van Hardenberg likes to say that back in the day of pirated software, 1015 00:58:25,773 --> 00:58:29,073 people would worry that, you know, 95 percent of software is pirated 1016 00:58:29,083 --> 00:58:30,583 and only 5 percent of users pay. 1017 00:58:31,123 --> 00:58:35,173 But actually with freemium software, A lot of starters would be very happy with a 5 1018 00:58:35,203 --> 00:58:37,643 percent conversion rates of free to paid. 1019 00:58:37,983 --> 00:58:39,373 That's a really good conversion rate. 1020 00:58:39,743 --> 00:58:44,033 So actually if you view it through that angle, you know, just. 1021 00:58:44,518 --> 00:58:48,698 Not worrying too much about the people who are not going to pay anyway, and make 1022 00:58:48,698 --> 00:58:52,468 sure that you provide a good experience for those customers who do want to pay. 1023 00:58:52,558 --> 00:58:56,218 I think it's, it should be fine to build a solid businesses that way. 1024 00:58:56,598 --> 00:58:57,208 I agree. 1025 00:58:57,308 --> 00:59:02,478 And I'm looking forward to see which sort of models do emerge. 1026 00:59:02,858 --> 00:59:07,148 And if anything, I think the cloud has really rewarded. 1027 00:59:07,548 --> 00:59:12,778 a very small number of like huge kind of monopoly like companies. 1028 00:59:13,318 --> 00:59:18,338 And I'm kind of nostalgic about the days where you had a lot more smaller 1029 00:59:18,348 --> 00:59:23,328 software vendors who really put a lot of care into for a particular audience 1030 00:59:23,348 --> 00:59:26,528 might be a niche audience built the best possible software for them. 1031 00:59:26,618 --> 00:59:29,868 And those are then probably also the people who would pay for software. 1032 00:59:29,868 --> 00:59:32,208 So I'm optimistic and I'm looking forward to see. 1033 00:59:32,483 --> 00:59:36,343 Which sort of business models will emerge and yeah, can't 1034 00:59:36,343 --> 00:59:38,293 wait to see where this is going. 1035 00:59:38,433 --> 00:59:38,763 Yeah. 1036 00:59:38,763 --> 00:59:39,243 that's one of 1037 00:59:39,243 --> 00:59:39,313 the 1038 00:59:39,383 --> 00:59:43,643 things that makes me excited about local-first as well as hopefully it 1039 00:59:43,643 --> 00:59:47,943 should just become a lot cheaper to build and run software because cloud 1040 00:59:47,943 --> 00:59:51,063 software is just ridiculously expensive because like you need a backend team 1041 00:59:51,063 --> 00:59:55,583 and the front end team and the backend team needs to be on call 24/7 in case 1042 00:59:55,833 --> 00:59:59,233 the servers go down and then, you know, suddenly you've got a huge team and costs. 1043 00:59:59,518 --> 01:00:01,608 A lot of money just to pay all those developers. 1044 01:00:01,938 --> 01:00:05,248 And then you have to have a mainstream app for a big audience in 1045 01:00:05,248 --> 01:00:06,438 order to have a big enough market. 1046 01:00:07,028 --> 01:00:10,728 And so that then cuts out all of this kind of indie software developers 1047 01:00:10,728 --> 01:00:11,728 that you were talking about. 1048 01:00:11,858 --> 01:00:15,208 And so we're hoping with local-first software, if we can just commoditize 1049 01:00:15,218 --> 01:00:18,588 the whole backend so that app developers don't have to write their own backend. 1050 01:00:18,598 --> 01:00:22,768 All you're doing is pulling some local-first framework off the shelf. 1051 01:00:23,263 --> 01:00:26,483 And writing your custom app logic in your front end, it just becomes a 1052 01:00:26,573 --> 01:00:28,163 so much cheaper to develop the app. 1053 01:00:28,243 --> 01:00:31,303 You don't have to worry about the whole 24/7 on call rotation. 1054 01:00:31,403 --> 01:00:34,943 And then that makes it economically feasible again, to have these niche apps 1055 01:00:35,103 --> 01:00:36,863 that are built by one or two people. 1056 01:00:37,373 --> 01:00:39,663 And they only have a small customer base, but that's fine. 1057 01:00:39,673 --> 01:00:42,673 You, all you need to do is provide a decent income for those two people. 1058 01:00:42,743 --> 01:00:44,273 And then you can have these niche apps that. 1059 01:00:44,763 --> 01:00:47,743 Really perfectly serve a particular audience and just 1060 01:00:47,973 --> 01:00:49,293 do that one thing really well. 1061 01:00:49,483 --> 01:00:51,193 That's something I would, I would really like to see. 1062 01:00:51,373 --> 01:00:54,203 And we're starting to see beginnings of this, for example, like one 1063 01:00:54,203 --> 01:00:58,703 of one of our big contributors to Automerge works on an app for 1064 01:00:59,163 --> 01:01:01,763 assistant directors of movie shoots. 1065 01:01:02,433 --> 01:01:06,273 to plan their schedule of when they're going to shoot what and which actor 1066 01:01:06,283 --> 01:01:10,093 they need for which scene on which set, with which props, et cetera. 1067 01:01:10,253 --> 01:01:13,943 And, you know, it's a super niche piece of software, but I really, really 1068 01:01:13,943 --> 01:01:17,873 want him to succeed because I think it's just a great example of if we 1069 01:01:17,873 --> 01:01:22,303 can make it easy for him to build this kind of software for his particular. 1070 01:01:22,673 --> 01:01:26,733 Use case, then we can do the same thing for 10, 000 other niches as well. 1071 01:01:27,243 --> 01:01:28,963 Yeah, I fully agree. 1072 01:01:29,023 --> 01:01:31,283 This is something I'm super excited about. 1073 01:01:31,283 --> 01:01:38,373 local-first as a whole is if he goes for life and realize how little in some 1074 01:01:38,373 --> 01:01:41,193 ways software has penetrated our real. 1075 01:01:41,293 --> 01:01:44,703 Live where you interact with something and then you think 1076 01:01:44,703 --> 01:01:48,083 about, wait, we have computers, we have technologies to solve this. 1077 01:01:48,433 --> 01:01:52,363 Why hasn't it arrived in these parts of our life yet? 1078 01:01:52,403 --> 01:01:54,343 Where would make life better? 1079 01:01:54,393 --> 01:01:57,983 And I think the answer is typically incentive models of the cloud. 1080 01:01:58,213 --> 01:02:01,363 If you build something for the cloud, you build it for like a, you need to 1081 01:02:01,363 --> 01:02:03,453 build it for a huge audience, et cetera. 1082 01:02:03,473 --> 01:02:04,703 Otherwise it's not worth it. 1083 01:02:04,733 --> 01:02:07,403 Particularly if you go venture capital based. 1084 01:02:08,028 --> 01:02:12,778 So I think this is where local-first really completely flips the moth, 1085 01:02:12,888 --> 01:02:17,718 allows people who are passionate about a particular use case, a particular 1086 01:02:17,718 --> 01:02:23,078 niche to go for that niche and that you don't need to worry about reaching 1087 01:02:23,138 --> 01:02:25,508 a giant audience if you don't want to. 1088 01:02:25,508 --> 01:02:28,448 And I think local-first can really change the economics there. 1089 01:02:28,998 --> 01:02:31,218 So I'm super excited about that. 1090 01:02:31,218 --> 01:02:33,158 That's almost like a second order effect. 1091 01:02:33,498 --> 01:02:37,698 And I'm sure there will be others that I can't really think about right now. 1092 01:02:37,993 --> 01:02:40,373 But I have a gut feeling that it will be a good one. 1093 01:02:41,133 --> 01:02:46,393 So yeah, Martin, this has been a real pleasure to have you on the show today 1094 01:02:46,393 --> 01:02:51,983 and sharing all of those anecdotes, the thoughts on the, where things are 1095 01:02:51,983 --> 01:02:53,843 coming from, where things are going. 1096 01:02:54,293 --> 01:02:57,483 So do you have anything else that you want to share with the 1097 01:02:57,483 --> 01:02:58,583 audience before wrapping up? 1098 01:02:58,783 --> 01:02:59,353 Not really. 1099 01:02:59,393 --> 01:03:03,993 I'm, just very happy if people are interested in local-firsts. 1100 01:03:04,013 --> 01:03:08,313 So, I mean, thank you to you for running this podcast for helping, 1101 01:03:08,393 --> 01:03:10,133 popularize the idea further. 1102 01:03:10,193 --> 01:03:13,743 And thank you to everyone who's listening and for being interested in it. 1103 01:03:13,783 --> 01:03:18,653 And I hope the community will continue growing further as we get more people. 1104 01:03:18,883 --> 01:03:23,043 You know, just building it in the direction for what they want it to be. 1105 01:03:23,333 --> 01:03:27,983 So I think, you know, we, we can just provide a set of starting values and 1106 01:03:27,983 --> 01:03:32,283 some technical tooling, but in the end, it'll all depend on what the 1107 01:03:32,283 --> 01:03:34,723 community decides to build around it. 1108 01:03:34,763 --> 01:03:37,793 And so I'm really excited to see what will come when, as people 1109 01:03:37,813 --> 01:03:39,313 take these ideas and run with them. 1110 01:03:39,713 --> 01:03:40,193 Awesome. 1111 01:03:40,213 --> 01:03:40,603 Yeah. 1112 01:03:40,653 --> 01:03:44,563 Whenever we do our next show together, I'm sure there will be a lot more apps 1113 01:03:44,563 --> 01:03:49,083 being built in local-first that we can already point to that did not exist today. 1114 01:03:49,463 --> 01:03:50,883 So I'm really looking forward to that. 1115 01:03:51,093 --> 01:03:52,613 Martin, thank you so much for coming on. 1116 01:03:53,503 --> 01:03:54,163 Thank you, Johannes. 1117 01:03:54,163 --> 01:03:54,633 It's been great. 1118 01:03:55,173 --> 01:03:57,713 Thank you for listening to the localfirst.fm podcast. 1119 01:03:57,953 --> 01:04:01,683 If you've enjoyed this episode and haven't done so already, please subscribe and 1120 01:04:01,683 --> 01:04:03,443 leave a review wherever you're listening. 1121 01:04:03,813 --> 01:04:05,243 Please also tell your friends about it. 1122 01:04:05,253 --> 01:04:08,823 If you think they could be interested in local-first, if you have feedback, 1123 01:04:08,863 --> 01:04:12,603 questions or ideas for the podcast, please get in touch via hello at 1124 01:04:12,603 --> 01:04:18,383 localfirst.fm or use the feedback form on our website, special thanks to Expo and 1125 01:04:18,383 --> 01:04:20,433 Crab Nebula for supporting this podcast. 1126 01:04:20,833 --> 01:04:21,593 See you next time.