1 00:00:00,000 --> 00:00:05,153 Imagine if you could mock up an app just based on React use state 2 00:00:05,153 --> 00:00:08,639 or like equivalent things, and you build your UI around that. 3 00:00:08,906 --> 00:00:14,358 but then magically your app actually works and like all of the status persistent 4 00:00:14,398 --> 00:00:18,538 and you can share it with other users and, you have permissions on there and 5 00:00:18,935 --> 00:00:21,255 you still only wrote front end code. 6 00:00:21,915 --> 00:00:23,455 That's kind of the Jazz story 7 00:00:24,005 --> 00:00:26,195 Welcome to the localfirst.fm podcast. 8 00:00:26,465 --> 00:00:29,385 I'm your host, Johannes Schickling, and I'm a web developer, a 9 00:00:29,385 --> 00:00:32,475 startup founder, and love the craft of software engineering. 10 00:00:32,895 --> 00:00:36,435 For the past few years, I've been on a journey to build a modern, high quality 11 00:00:36,435 --> 00:00:38,145 music app using web technologies. 12 00:00:38,645 --> 00:00:42,485 And in doing so, I've been falling down the rabbit hole of local-first software. 13 00:00:43,175 --> 00:00:46,175 This podcast is your invitation to join me on that journey. 14 00:00:47,065 --> 00:00:49,550 In this episode, I'm speaking to Anselm Eickhoff. 15 00:00:49,880 --> 00:00:52,560 Creator of Jazz and founder of Garden Computing. 16 00:00:53,070 --> 00:00:58,030 In this conversation, we dive deep into Jazz to learn how it works and which use 17 00:00:58,030 --> 00:01:02,550 cases it's a good fit for by exploring various apps already built on top of Jazz. 18 00:01:03,330 --> 00:01:07,960 Before getting started, also a big thank you to Rosicorp and PowerSync 19 00:01:07,960 --> 00:01:09,350 for supporting this podcast. 20 00:01:09,780 --> 00:01:11,590 And now my interview with Anselm. 21 00:01:13,117 --> 00:01:15,107 Hey Anselm, so nice to have you on the show. 22 00:01:15,107 --> 00:01:15,807 How are you doing? 23 00:01:16,407 --> 00:01:17,487 Hey Johannes, doing good. 24 00:01:17,487 --> 00:01:17,977 How are you? 25 00:01:18,817 --> 00:01:19,687 I'm doing great. 26 00:01:19,757 --> 00:01:22,927 I was looking forward to today talking to you about Jazz. 27 00:01:23,307 --> 00:01:28,227 I know a little bit about Jazz and as I'm generally trying to scan the 28 00:01:28,227 --> 00:01:33,497 local-first ecosystem, but super excited to have you on the show and dive deeper, 29 00:01:33,527 --> 00:01:37,607 learn a lot more about Jazz, but before we dig in, do you mind giving a quick 30 00:01:37,617 --> 00:01:39,347 background and introduce yourself? 31 00:01:40,057 --> 00:01:40,897 Oh yeah, of course. 32 00:01:41,167 --> 00:01:43,727 I guess I've always been like interested in the web. 33 00:01:43,727 --> 00:01:48,097 I think it technically, I started with like Flash for people who remember 34 00:01:48,097 --> 00:01:51,477 that, but I very quickly got into making websites, just static ones 35 00:01:51,477 --> 00:01:56,167 first, kind of doing web design for local shops in my hometown and 36 00:01:56,167 --> 00:01:57,657 that became more and more serious. 37 00:01:57,657 --> 00:02:01,477 I learned about Rails and like building whole web apps and what that even meant. 38 00:02:01,507 --> 00:02:06,227 And I guess most of my career kind of spent being like a full 39 00:02:06,227 --> 00:02:11,207 stack consultant, building apps for lots of different industries. 40 00:02:11,417 --> 00:02:16,857 And typically I would be just like one man army doing like product design and 41 00:02:16,857 --> 00:02:21,907 building the backend and the front end and just building kind of the first version 42 00:02:21,907 --> 00:02:23,937 of that app that was ready for production. 43 00:02:24,112 --> 00:02:26,302 And then doing the next one and the next one and so on. 44 00:02:27,012 --> 00:02:28,915 And that was lots of fun. 45 00:02:28,915 --> 00:02:32,865 And I learned a lot, but over time, especially when you build lots of apps 46 00:02:32,865 --> 00:02:37,232 that are very different in nature, like who they serve, how they work. 47 00:02:37,642 --> 00:02:41,442 You still notice that there's so many things that you have to do again and 48 00:02:41,442 --> 00:02:44,292 again and again, and they don't even really have to do with each app. 49 00:02:44,292 --> 00:02:45,042 And you're, you're. 50 00:02:45,042 --> 00:02:48,072 You're using these tools that are supposed to be like high level 51 00:02:48,082 --> 00:02:51,362 frameworks for building web apps, but you still need to do so much 52 00:02:51,362 --> 00:02:52,982 yourself, redundantly each time. 53 00:02:52,982 --> 00:02:57,002 Like people who build web apps will know stuff like, why do you have 54 00:02:57,002 --> 00:03:00,832 to do user auth and permissions every time or like file uploads, 55 00:03:00,882 --> 00:03:02,652 this is like super simple stuff. 56 00:03:03,128 --> 00:03:05,078 and that always like nagged me. 57 00:03:05,178 --> 00:03:07,018 and particularly like, it seemed like. 58 00:03:07,318 --> 00:03:11,048 What you're really trying to do is just share state between 59 00:03:11,048 --> 00:03:12,448 different users of the app. 60 00:03:12,448 --> 00:03:16,928 And why, why do I have to build a whole stack and why is it so weird to do it? 61 00:03:17,528 --> 00:03:20,368 But I never really had a good, good solution for it. 62 00:03:20,368 --> 00:03:20,628 Right. 63 00:03:20,638 --> 00:03:24,288 And that's kind of what, what brought me where I am today with Jazz. 64 00:03:24,288 --> 00:03:26,768 And yeah, happy to tell you more about that. 65 00:03:27,200 --> 00:03:31,187 Yeah, that journey definitely resonates and, sort of in a similar 66 00:03:31,467 --> 00:03:36,910 counter reaction, in, in 2016, just led me back then to starting GraphQL, 67 00:03:36,910 --> 00:03:38,630 which later turned into Prisma. 68 00:03:38,630 --> 00:03:43,590 So I feel like that's a common, somewhat common story to like, from like the 69 00:03:43,600 --> 00:03:48,673 previous trauma of like doing something over and over again in a way that 70 00:03:48,673 --> 00:03:52,918 doesn't quite satisfy you, where you feel like, Oh man, we can do so much better. 71 00:03:53,138 --> 00:03:55,218 so that story definitely resonates. 72 00:03:55,638 --> 00:03:58,948 I'd be actually intrigued to hear a little bit more about some of the 73 00:03:58,958 --> 00:04:04,175 specific aspects, but I'm sure you'll, you'll cover that in comparison to Jazz. 74 00:04:04,555 --> 00:04:08,815 So, and Jazz is actually not quite the only thing you're doing 75 00:04:08,815 --> 00:04:12,245 since you're doing this under the umbrella of Garden Computing. 76 00:04:12,545 --> 00:04:17,145 So before diving into Jazz, do you mind giving a quick idea of like, 77 00:04:17,155 --> 00:04:18,905 what is that umbrella and what. 78 00:04:19,265 --> 00:04:20,435 led you to that? 79 00:04:20,758 --> 00:04:21,478 Yeah, sure. 80 00:04:21,478 --> 00:04:26,765 So it actually started with an app called Garden, which was kind of like 81 00:04:26,855 --> 00:04:32,875 my take on what should a Notion clone look like, what kind of other ideas do I 82 00:04:32,885 --> 00:04:37,488 have, I was really fascinated by Notion when it came out and by Figma just like 83 00:04:37,488 --> 00:04:43,028 setting this new standard of like, it not just being like a higher fidelity app. 84 00:04:43,493 --> 00:04:49,853 But one where like multiplayer and like rich multi user interaction is like baked 85 00:04:49,973 --> 00:04:54,463 kind of into the very fabric of the app and then the app itself is just like kind 86 00:04:54,463 --> 00:04:56,163 of like features on top of that, right? 87 00:04:56,583 --> 00:05:01,572 And I was like, this is cool, but I think It still doesn't feel fundamental enough. 88 00:05:01,642 --> 00:05:05,762 Like the multiplayer ness of it and like also the aspects that we 89 00:05:05,762 --> 00:05:08,852 now call local-first that I didn't really have a name for back then. 90 00:05:09,188 --> 00:05:11,908 and I was like, okay, I want to do something like that, but I want to do 91 00:05:11,948 --> 00:05:15,518 that part even better and then build like even cooler features on top. 92 00:05:15,888 --> 00:05:17,258 And that, that was Garden. 93 00:05:17,278 --> 00:05:20,158 And yeah, I did a bunch of experiments there and that's. 94 00:05:20,718 --> 00:05:25,968 That's pretty much what, what led me to what, what Jazz became as for 95 00:05:25,968 --> 00:05:30,728 like Garden Computing as an idea for a company or bigger umbrella. 96 00:05:31,022 --> 00:05:34,252 I can get more into that later, but basically the idea is that. 97 00:05:34,595 --> 00:05:38,835 I'm really fascinated by abstractions, by like powerful abstractions, by 98 00:05:38,835 --> 00:05:43,710 abstractions that are tall and like span many levels of, of understanding. 99 00:05:43,957 --> 00:05:47,087 And very often they come from like academia and research, right? 100 00:05:47,087 --> 00:05:50,767 That's where people find like really new, better ways of 101 00:05:50,827 --> 00:05:52,287 describing and building things. 102 00:05:52,767 --> 00:05:57,437 But they're obviously very abstract, very hard to approach for most people. 103 00:05:57,967 --> 00:05:59,837 and from my experience as a. 104 00:06:00,202 --> 00:06:06,212 Full stack web dev, I'm, I'm like very in touch with what people are using day 105 00:06:06,212 --> 00:06:10,342 to day and what, what the mainstream developer is like and cares about. 106 00:06:10,922 --> 00:06:15,252 and I just love the idea of taking these new ideas and kind of like 107 00:06:15,572 --> 00:06:20,172 finding ways to package them in a way that makes sense for the mainstream. 108 00:06:20,172 --> 00:06:21,316 And that actually makes. 109 00:06:21,837 --> 00:06:24,427 What we use in the mainstream, a little more enlightened. 110 00:06:24,427 --> 00:06:28,347 So I think in the broadest sense, that's, that's what Garden Computing 111 00:06:28,347 --> 00:06:33,027 for me is about and like Jazz and local-first is kind of like 112 00:06:33,227 --> 00:06:34,777 the first step in that journey. 113 00:06:35,430 --> 00:06:39,190 And I love the vibe overall of like Garden Computing. 114 00:06:39,550 --> 00:06:45,000 A garden is something that I think that's just, I'd say if you'd ask anyone, 115 00:06:45,300 --> 00:06:50,680 they'd probably associate it with like a nice, comfortable, homey feeling. 116 00:06:50,920 --> 00:06:54,370 If you think about a garden, does this maybe even, you have a very personal 117 00:06:54,370 --> 00:06:58,590 relationship of like, maybe you put together the garden, maybe you care 118 00:06:58,610 --> 00:07:02,490 after it, or maybe not, maybe it looks a little bit wilder, but there's something 119 00:07:02,490 --> 00:07:08,200 very unique and something very personal to our garden compared to like a very 120 00:07:08,620 --> 00:07:13,900 Industrial, like hyperscale, like that doesn't sound like a garden to me. 121 00:07:14,430 --> 00:07:18,103 and also like the use case that you've mentioned sort of like a 122 00:07:18,353 --> 00:07:22,153 Notion esque thing, I think Notion is also like there, there's this 123 00:07:22,183 --> 00:07:23,903 term of like a digital garden. 124 00:07:24,210 --> 00:07:27,610 so all of that is like a vibe that very much resonates. 125 00:07:27,670 --> 00:07:32,190 And it also resonates that you're saying you didn't actually start right away. 126 00:07:32,405 --> 00:07:38,465 with designing Jazz as a local-first tool, but that you're rather stumbling 127 00:07:38,475 --> 00:07:41,245 into it through working on an actual app. 128 00:07:41,245 --> 00:07:45,075 Since there's also the analogy for me, the parallel that while working 129 00:07:45,095 --> 00:07:49,885 on Overtone, I also realized, okay, this is a data foundation that I'm 130 00:07:49,885 --> 00:07:53,675 working on that doesn't just work well for Overtone, but also for other apps. 131 00:07:53,915 --> 00:07:57,640 So I think this is one of the most authentic ways to Really 132 00:07:57,790 --> 00:08:00,450 think of a new data abstraction. 133 00:08:00,820 --> 00:08:04,920 So now with that background, can you give me an introduction to Jazz? 134 00:08:05,403 --> 00:08:05,673 Yeah. 135 00:08:05,673 --> 00:08:09,637 So like, to audiences like this, I introduced Jazz just as 136 00:08:09,667 --> 00:08:14,113 like, a framework for building web apps in a local-first way. 137 00:08:14,368 --> 00:08:16,568 That's probably the simplest way to put it. 138 00:08:16,588 --> 00:08:20,868 That of course requires you to already know what local-first means. 139 00:08:21,418 --> 00:08:27,838 So I think maybe a nice way to explain it is to go a bit more in depth on like how 140 00:08:27,878 --> 00:08:32,438 through trying to build Garden, I kind of discovered what I thought it needed to be. 141 00:08:32,868 --> 00:08:35,668 Because in many ways I didn't like sit down and be like, 142 00:08:35,698 --> 00:08:36,778 Oh, I want to build this app. 143 00:08:36,788 --> 00:08:38,818 I want to build it in local-first ways. 144 00:08:39,165 --> 00:08:42,275 and then I'll make a local-first framework to build the app because. 145 00:08:42,845 --> 00:08:45,895 When I started building the app, I didn't even know about local-first. 146 00:08:45,915 --> 00:08:47,345 I didn't know about that as a term. 147 00:08:47,812 --> 00:08:51,202 I saw apps like, like Notion and Figma. 148 00:08:51,532 --> 00:08:58,748 and I guess systems like Git, where it feels different from a traditional 149 00:08:58,748 --> 00:09:02,058 SaaS app with a centralized server and it has these really nice 150 00:09:02,058 --> 00:09:05,858 properties and it actually feels like it's suddenly very easy to do 151 00:09:05,898 --> 00:09:08,178 multiplayer, to have offline support. 152 00:09:08,613 --> 00:09:13,443 And to like be really serious and honest about the fact that what you're building 153 00:09:13,443 --> 00:09:17,853 with your app is a distributed system and not like some thin client around 154 00:09:17,853 --> 00:09:22,203 like the app basically just running on another computer, on one other computer. 155 00:09:22,770 --> 00:09:25,290 so I was like, okay, I want my app to be like that. 156 00:09:25,640 --> 00:09:28,730 And I started building the app and I had all of these crazy ideas in 157 00:09:28,730 --> 00:09:30,560 terms of like features for Garden. 158 00:09:30,590 --> 00:09:33,500 Part of it was even like, it should be like a visual programming 159 00:09:33,500 --> 00:09:34,760 language in there and like. 160 00:09:35,170 --> 00:09:38,580 I actually didn't get too far on that because very soon I was like, okay, 161 00:09:38,580 --> 00:09:41,170 what's, what's the infrastructure I need. 162 00:09:41,230 --> 00:09:46,290 That's like fabric that, that just has in the data layer, multiplayer 163 00:09:46,290 --> 00:09:50,590 and users and permissions and sharing and working on your device, but still 164 00:09:50,600 --> 00:09:52,010 being able to sync to the cloud. 165 00:09:52,510 --> 00:09:55,480 So I started building that just as part of Garden, right. 166 00:09:55,893 --> 00:09:58,123 and very soon just through like. 167 00:09:58,443 --> 00:10:00,783 abstracting and encapsulating the code. 168 00:10:00,783 --> 00:10:03,593 I had this like separate layer that did all of that. 169 00:10:03,973 --> 00:10:07,823 and a big part of what made that layer possible was learning about, 170 00:10:08,183 --> 00:10:12,897 Ink and Switch and their blog posts and publications, seeing auto merge 171 00:10:12,897 --> 00:10:17,637 as the first CRDT that I encountered and being like, Oh, even just the idea 172 00:10:17,637 --> 00:10:22,140 of having like, synced state between two text editors is super interesting. 173 00:10:22,140 --> 00:10:23,640 Like, let's. 174 00:10:24,740 --> 00:10:26,800 Build the layer around that. 175 00:10:26,810 --> 00:10:30,987 And then once I had that layer, I looked at it and I was like, damn, this is like 176 00:10:30,987 --> 00:10:33,507 really interesting, not just for Garden. 177 00:10:33,800 --> 00:10:36,870 but I kind of want to build every app ever like this now. 178 00:10:37,220 --> 00:10:40,390 thinking of all the apps I had built in the past, all the other apps I 179 00:10:40,390 --> 00:10:43,590 still wanted to build or the apps I didn't even know I could build yet. 180 00:10:44,380 --> 00:10:47,640 And I'm like, if I feel like that, probably other people will too. 181 00:10:47,640 --> 00:10:51,010 They just don't know yet that it's even possible to have this abstraction. 182 00:10:51,010 --> 00:10:53,110 So therefore I should probably try. 183 00:10:53,590 --> 00:10:54,890 And make this a framework. 184 00:10:54,910 --> 00:10:57,960 And that's, that's the origin story of Jazz, right? 185 00:10:58,407 --> 00:10:59,637 That makes a lot of sense. 186 00:10:59,677 --> 00:11:06,137 And, it also, there's, this interesting dance of, being irritated 187 00:11:06,147 --> 00:11:10,487 and confused by some problems, this desire of like, could we do better? 188 00:11:10,717 --> 00:11:12,497 You kind of hope we could do better. 189 00:11:12,497 --> 00:11:15,387 You don't quite know yet how to do better. 190 00:11:15,577 --> 00:11:18,487 You see some proof for other apps. 191 00:11:19,262 --> 00:11:22,772 Being able to build something in an experience that you wouldn't quite 192 00:11:22,802 --> 00:11:24,812 know how you would replicate that. 193 00:11:25,112 --> 00:11:31,015 You go on like looking around for ideas and luckily they're, very smart 194 00:11:31,015 --> 00:11:35,685 people, like the folks associated with Ink and Switch who are also like 195 00:11:35,775 --> 00:11:37,985 write about that and inspire others. 196 00:11:38,035 --> 00:11:41,675 And that leads you to maybe also like be very. 197 00:11:42,115 --> 00:11:46,820 compelled by those ideas, but maybe you have some slightly different takes. 198 00:11:46,820 --> 00:11:49,360 And so this is where, where it evolves. 199 00:11:49,717 --> 00:11:50,937 that makes a lot of sense. 200 00:11:50,957 --> 00:11:55,397 And I see a lot of like parallels there for like past endeavors and 201 00:11:55,477 --> 00:11:57,107 current endeavors that I'm on. 202 00:11:57,477 --> 00:12:00,337 So this is what led to Jazz. 203 00:12:00,337 --> 00:12:05,017 And I think there's like a lot of similarities for how other data 204 00:12:05,077 --> 00:12:09,963 technologies, like in the local-first space came to be and, throughout the 205 00:12:09,973 --> 00:12:15,003 further conversation, I'm sure we'll learn about what makes the specific flavor 206 00:12:15,053 --> 00:12:21,113 of Jazz, how that compares to others, but maybe we can best approach that 207 00:12:21,163 --> 00:12:27,233 by talking a little bit more about the applications that, Jazz wants to empower. 208 00:12:27,553 --> 00:12:33,597 So can you, give me an idea of like, what is like a typical app that, Is 209 00:12:33,607 --> 00:12:35,517 just naturally now built with Jazz. 210 00:12:35,517 --> 00:12:38,777 And what are some apps that you've like intended Jazz for? 211 00:12:39,327 --> 00:12:39,717 Right. 212 00:12:40,010 --> 00:12:44,230 I guess one thing I will add in terms of like, what's special about Jazz 213 00:12:44,260 --> 00:12:48,130 and we'll go more in depth about that later, but like while building it 214 00:12:48,130 --> 00:12:52,360 as part of Garden, I realized that the responsibility of this layer. 215 00:12:52,620 --> 00:12:58,000 It's actually not just a data layer, it also needs to, or like, I wanted it to 216 00:12:58,010 --> 00:13:04,560 also handle user identity and permissions because that's other, other, because 217 00:13:04,570 --> 00:13:08,920 like, that's what allows you to go from having a local-first app that kind of 218 00:13:08,920 --> 00:13:13,910 syncs between your devices as a single player user to just extending that 219 00:13:13,920 --> 00:13:15,980 model very naturally to multiplayer. 220 00:13:16,500 --> 00:13:20,120 and it just always felt like these two things, user identity and permissions 221 00:13:20,140 --> 00:13:21,930 also need to be part of that abstraction. 222 00:13:21,930 --> 00:13:25,740 And that's kind of, that's the most special thing about Jazz, I would say. 223 00:13:26,330 --> 00:13:31,220 and that has enabled it to support quite a, like, wide range of different 224 00:13:31,250 --> 00:13:33,140 apps that, that even surprised me. 225 00:13:33,533 --> 00:13:37,913 and you kind of, you have apps that are like obviously local-first and are like 226 00:13:37,933 --> 00:13:42,193 a very good fit, and they are some of the ones that, that already felt the 227 00:13:42,193 --> 00:13:44,303 strongest benefit from adopting Jazz. 228 00:13:44,700 --> 00:13:47,520 for example, like I, I think Garden is a good example. 229 00:13:47,530 --> 00:13:50,710 We're actually almost at a point now where we can start building Garden 230 00:13:50,710 --> 00:13:52,880 again, based on top of what Jazz is now. 231 00:13:53,242 --> 00:13:55,052 That's, it's like Notion. 232 00:13:55,052 --> 00:13:56,972 It's very clearly a local-first app. 233 00:13:57,752 --> 00:14:02,842 One of my favorite early adopters, they're an app called Invoice Radar, 234 00:14:02,882 --> 00:14:08,532 which is basically, it lets freelancers collect invoices automatically from 235 00:14:08,532 --> 00:14:12,312 like cloud providers and other things they use that send them invoices, 236 00:14:13,392 --> 00:14:16,992 manage them, and then submit them to tax authorities, for example. 237 00:14:17,777 --> 00:14:23,197 And that's an area where like, yeah, having it local-first is really important. 238 00:14:23,227 --> 00:14:27,147 And the people who were building the app already, I think also without 239 00:14:27,177 --> 00:14:31,087 knowing the term at the beginning, knew that they wanted to build it that way. 240 00:14:31,497 --> 00:14:34,667 And then they found Jazz and they're like, Oh, there's like a framework that 241 00:14:34,942 --> 00:14:36,432 Just lets you build apps like that. 242 00:14:36,432 --> 00:14:40,612 And once they started building it with that, they were just able to get to 243 00:14:40,612 --> 00:14:43,042 like an MVP of their apps so quickly. 244 00:14:43,552 --> 00:14:46,752 So that's kind of like, almost like an obvious success story. 245 00:14:46,752 --> 00:14:46,982 Right. 246 00:14:46,982 --> 00:14:50,625 But then there's other ones that are really surprising that start to push 247 00:14:50,625 --> 00:14:55,312 the boundaries of what a local-first app is, or does the framework even 248 00:14:55,322 --> 00:14:57,222 only need to be for local-first app? 249 00:14:57,568 --> 00:15:02,217 one I'm building myself with, my girlfriend that I presented in Berlin 250 00:15:02,902 --> 00:15:06,892 at our local-first conference is an app called Succulent, which is 251 00:15:06,912 --> 00:15:11,722 basically a Hootsuite alternative, like a social media scheduling tool. 252 00:15:12,302 --> 00:15:17,472 And it's like 90 percent a local-first app where you can like plan drafts 253 00:15:17,482 --> 00:15:20,822 for Instagram posts, for example, on your device and you prepare 254 00:15:20,822 --> 00:15:23,592 them with the pictures and the descriptions and the hashtags. 255 00:15:24,177 --> 00:15:27,947 But then it has this component that's like not local-first at all, because like in 256 00:15:27,947 --> 00:15:32,557 order to meaningfully schedule posts to be posted, you need to have a server worker. 257 00:15:33,117 --> 00:15:36,847 and, typically this would mean that, well, you just need to build it as 258 00:15:36,847 --> 00:15:40,607 a centralized, like, SaaS app where all this logic runs on a server. 259 00:15:40,607 --> 00:15:43,594 But, What I realized with Jazz is like, you can actually take this 260 00:15:43,594 --> 00:15:47,444 local-first concept further and the server worker can just become yet another 261 00:15:47,444 --> 00:15:50,104 local-first client to the shared state. 262 00:15:50,484 --> 00:15:54,014 And then you get this really funky arrangement of like, you have 263 00:15:54,054 --> 00:15:57,144 this local-first app for authoring all this stuff and then just this 264 00:15:57,144 --> 00:16:00,424 little worker that whenever you're online and your stuff gets synced. 265 00:16:00,984 --> 00:16:04,044 It will know about what you're trying to do and then you can go 266 00:16:04,054 --> 00:16:07,314 offline again and it will post your posts for you by like interacting 267 00:16:07,314 --> 00:16:09,534 with the meta API, for example. 268 00:16:09,884 --> 00:16:13,554 So that was already a bit of a stretch of what Jazz can do. 269 00:16:13,890 --> 00:16:17,960 But honestly, the most ambitious and most out there things in terms of 270 00:16:17,960 --> 00:16:21,460 what you can build with Jazz have been from like other early adopters. 271 00:16:21,460 --> 00:16:27,335 So one of the crazier ones is This guy Nikita is building an app called 272 00:16:27,755 --> 00:16:29,385 LearnAnything, and you can check it out. 273 00:16:29,385 --> 00:16:30,145 It's already public. 274 00:16:30,145 --> 00:16:33,415 You can go to, I think, Learn Anything. 275 00:16:33,415 --> 00:16:33,595 xyz. 276 00:16:34,585 --> 00:16:37,795 It's, it's like a cross between Quora and Reddit. 277 00:16:37,795 --> 00:16:42,170 It's like a learning community where you can be like, I want to learn how to play 278 00:16:42,170 --> 00:16:44,390 the guitar, or I want to learn TypeScript. 279 00:16:44,800 --> 00:16:48,150 and for each topic that you might want to learn, you find this like 280 00:16:48,500 --> 00:16:52,640 community curated list of like really good links to other resources, 281 00:16:52,640 --> 00:16:54,840 like videos, blog posts, whatever. 282 00:16:55,164 --> 00:16:57,154 and that's just the social network, right? 283 00:16:57,534 --> 00:17:01,707 And the crazy thing is, he's already getting a bunch of impressions just from 284 00:17:02,127 --> 00:17:07,142 SEO, so you have like lots of, First time visitors and all of the state that 285 00:17:07,142 --> 00:17:11,602 needs to be loaded for each of these potentially huge topics, which have like 286 00:17:11,632 --> 00:17:13,372 thousands of links or something like that. 287 00:17:13,802 --> 00:17:18,552 And he decided to completely pivot his stack to just use Jazz for everything. 288 00:17:19,082 --> 00:17:24,117 And I think one of his motivations is that, For each individual user, he 289 00:17:24,117 --> 00:17:27,927 actually wants the experience to be local-first in the sense that you can 290 00:17:27,937 --> 00:17:31,897 also have your own kind of like notion, like notes about the topic and your 291 00:17:31,897 --> 00:17:36,477 learning progress in there and manage your own collection of links and so on. 292 00:17:37,267 --> 00:17:40,257 But then through sharing it with others, again, it needs to have the 293 00:17:40,257 --> 00:17:42,467 scaling properties of a social network. 294 00:17:42,807 --> 00:17:47,367 And that really, really stretched Jazz, but he was able to kind of like, Self 295 00:17:47,387 --> 00:17:51,587 publicly launched already and a version of his app completely built on Jazz. 296 00:17:51,587 --> 00:17:53,627 And so far it seems to be working. 297 00:17:53,997 --> 00:17:55,977 So, so that's kind of an interesting one. 298 00:17:56,320 --> 00:17:59,680 another one, which is very early and we'll have to see if it works, but 299 00:17:59,680 --> 00:18:03,430 it's basically like a local-first spreadsheet app, which is just like 300 00:18:03,720 --> 00:18:07,440 really intense in terms of like how much data there's in it and how like 301 00:18:07,450 --> 00:18:10,000 finally granular the interaction will be. 302 00:18:10,335 --> 00:18:14,425 And then the last use case I'll mention also really surprised me 303 00:18:14,425 --> 00:18:19,255 because it actually uses Jazz to do much less than a whole app where, 304 00:18:19,495 --> 00:18:24,435 it's at this huge enterprise and they have like CI pipelines for like 305 00:18:24,435 --> 00:18:26,145 their build processes or whatever. 306 00:18:26,415 --> 00:18:29,372 but it's really hard to look at them and see what's going on, which builds 307 00:18:29,372 --> 00:18:31,052 are passing, which ones are failing. 308 00:18:31,527 --> 00:18:35,327 And it's all in this like super old system with a really clunky API. 309 00:18:35,327 --> 00:18:37,927 And this person just wanted to build like a dashboard for that. 310 00:18:37,927 --> 00:18:38,157 Right. 311 00:18:38,157 --> 00:18:39,187 And that's really annoying. 312 00:18:39,470 --> 00:18:43,010 They decided to use Jazz basically just as a layer that makes that 313 00:18:43,040 --> 00:18:49,560 clunky old API real time and really easy to build UIs around. 314 00:18:50,080 --> 00:18:55,560 So they again have like a server worker that makes requests to that API and 315 00:18:55,580 --> 00:19:01,277 then maintains like a version of the state of all of the stuff in Jazz. 316 00:19:01,947 --> 00:19:06,907 And then they built a really thin client with Jazz and the two, like 317 00:19:07,127 --> 00:19:08,847 the status shared between the two. 318 00:19:08,847 --> 00:19:11,987 And then they were able to super quickly build a really nice dashboard, 319 00:19:12,257 --> 00:19:14,897 where you see a real time updates of what's actually going on. 320 00:19:15,304 --> 00:19:18,344 and I, I think you can start to see like how these are actually all. 321 00:19:18,722 --> 00:19:20,382 Really weirdly different. 322 00:19:20,882 --> 00:19:26,792 And yet everyone was able to use Jazz as this like small tool that 323 00:19:26,802 --> 00:19:28,295 does a lot very successfully. 324 00:19:28,299 --> 00:19:31,285 and I have to say as a caveat as well, these are very brave people. 325 00:19:31,295 --> 00:19:33,369 Like Jazz is early in many ways. 326 00:19:33,669 --> 00:19:35,839 Some of its APIs are clunky as well. 327 00:19:35,839 --> 00:19:40,939 The documentation really isn't there yet, but all the important like magic 328 00:19:40,949 --> 00:19:44,269 is already there and I think that's what allowed all these people to move quite 329 00:19:44,269 --> 00:19:49,029 quickly and confidently and the parts that still have friction are problematic. 330 00:19:49,029 --> 00:19:50,599 They were kind of able to work around it. 331 00:19:50,669 --> 00:19:53,879 I think that's kind of a good representation of where we're at as well. 332 00:19:54,179 --> 00:19:55,429 That sounds incredible. 333 00:19:55,449 --> 00:19:59,269 That's such a wide range of different apps and different use cases. 334 00:19:59,505 --> 00:20:03,125 you mentioning InvoiceRadar, for example, I'm actually one of the 335 00:20:03,185 --> 00:20:07,226 early users of InvoiceRadar, I've been using it for multiple months 336 00:20:07,226 --> 00:20:12,452 now, and I can confidently say that, I would have probably not started to 337 00:20:12,452 --> 00:20:14,552 adopt it if it wasn't local-first. 338 00:20:14,862 --> 00:20:19,742 Not because of like, that I say like, okay, now I have this bar Everything has 339 00:20:19,742 --> 00:20:23,912 to be local-first, like I still adopt other tools, but in this particular thing 340 00:20:23,962 --> 00:20:31,340 is, one of the, main ways, how this tool works is by getting access, like actually 341 00:20:31,350 --> 00:20:36,215 log in access to the various places that you where I pay for an invoice. 342 00:20:36,225 --> 00:20:42,325 So this tool needs access to my Notion, to my Slack, to my Hetzner columns, 343 00:20:42,325 --> 00:20:46,765 to all those like very critical places I wouldn't give anyone access who I 344 00:20:46,775 --> 00:20:48,970 wouldn't really, really, really trust. 345 00:20:49,410 --> 00:20:53,860 And that level of trust, I can't just give that to like an arbitrary 346 00:20:53,870 --> 00:20:57,763 SaaS startup, that wasn't around like a couple of years ago. 347 00:20:57,793 --> 00:21:01,023 Even if it was around, I would still have trust issues. 348 00:21:01,463 --> 00:21:03,723 And that trust issues thing. 349 00:21:03,963 --> 00:21:08,357 They very elegantly address by, saying like, Hey, the entire 350 00:21:08,387 --> 00:21:10,517 thing runs all on your computer. 351 00:21:10,807 --> 00:21:11,047 Like. 352 00:21:11,442 --> 00:21:15,742 All of like the login credentials, et ceterall of that, like not running in the 353 00:21:15,742 --> 00:21:18,372 cloud, like all remains on your computer. 354 00:21:18,845 --> 00:21:24,265 and so this is how that afforded me the trust and I've been using it. 355 00:21:24,665 --> 00:21:26,948 And, it works amazing. 356 00:21:26,988 --> 00:21:32,695 And I think it's built by folks, who are like very confident in 357 00:21:32,705 --> 00:21:34,205 sort of like front end development. 358 00:21:34,205 --> 00:21:37,692 And I think Jazz empowers them to like leverage their strength. 359 00:21:38,277 --> 00:21:42,680 And a lot of like the data moving around, that is taken care of. 360 00:21:42,680 --> 00:21:46,460 So that is like a use case that I can already as a user speak to. 361 00:21:46,460 --> 00:21:49,980 And then I want to also hear more about the Learn Anything use case, 362 00:21:50,300 --> 00:21:55,501 since that's, to me, seems like it's actually stretching, quite on 363 00:21:55,501 --> 00:21:59,293 the boundaries of where local-first is even considered a good fit. 364 00:21:59,333 --> 00:22:04,118 I think, if you hear about local-first, like where App use case works well, 365 00:22:04,448 --> 00:22:09,988 that's more around like data that's all like centered around a small entity, 366 00:22:09,988 --> 00:22:14,418 whether it's one user, whether it's one document, one workspace, one small team, 367 00:22:14,758 --> 00:22:18,638 but the more I think it's actually used sort of like as the counterexample, 368 00:22:18,668 --> 00:22:24,038 the more something is seen as a social network, the more local-first also 369 00:22:24,038 --> 00:22:28,808 actually becomes increasingly tricky to model around, to scale, et cetera. 370 00:22:28,838 --> 00:22:34,118 So I'd love to hear a little bit more how, Learn Anything and how Jazz helps with 371 00:22:34,118 --> 00:22:37,638 this sort of like end boss of use cases. 372 00:22:37,942 --> 00:22:39,442 Yeah, I'll, I'll go into that. 373 00:22:39,442 --> 00:22:43,030 There's two more things I want to say about Invoice Radar, because, I think 374 00:22:43,030 --> 00:22:47,100 that ties in quite nicely with what makes Jazz special, particularly for 375 00:22:47,100 --> 00:22:51,320 like your particular sensibilities as a user where like, yeah, you need to 376 00:22:51,320 --> 00:22:53,140 put your login credentials in there. 377 00:22:53,515 --> 00:22:54,635 Why can you trust it? 378 00:22:54,635 --> 00:22:58,945 And part of the answer is, well, it, because it only runs on your device, 379 00:22:58,985 --> 00:23:03,555 but then even then you might want to, and I think they're working on like a 380 00:23:03,555 --> 00:23:05,895 mobile companion app to Invoice Radar. 381 00:23:05,955 --> 00:23:09,275 So you can also just like scan and paper invoices with your phone. 382 00:23:10,065 --> 00:23:15,655 So obviously it's like 2024, you want sync between your devices, right? 383 00:23:16,002 --> 00:23:20,072 Maybe you're no longer just like a solo freelancer, but you have like a small 384 00:23:20,092 --> 00:23:23,702 company and you want other people in your team to submit invoices as well. 385 00:23:23,702 --> 00:23:28,322 And how do you do that while maintaining the trust that you have with the 386 00:23:28,322 --> 00:23:29,552 credentials and your invoices? 387 00:23:30,142 --> 00:23:33,022 And Jazz's answer there is exactly what I mentioned earlier that. 388 00:23:33,822 --> 00:23:37,332 User identity and permission is also part of the abstraction that 389 00:23:37,332 --> 00:23:42,112 it offers you, and it solves those in a local-first way as well. 390 00:23:42,132 --> 00:23:46,182 And we, again, we'll go into that later, but basically it uses public key 391 00:23:46,192 --> 00:23:48,642 cryptography to do permissions and auth. 392 00:23:49,012 --> 00:23:54,160 And what that means is that, Their app can actually use my infrastructure 393 00:23:54,160 --> 00:23:57,940 to sync data between your devices or between members of your team. 394 00:23:58,570 --> 00:24:03,640 But my infrastructure only ever sees encrypted data and that way you can 395 00:24:03,640 --> 00:24:07,050 still trust that app despite having these modern properties of like 396 00:24:07,310 --> 00:24:10,300 sync, cloud persistence, and so on. 397 00:24:10,617 --> 00:24:15,117 for them, what it meant was that they envisioned their app initially as 398 00:24:15,137 --> 00:24:16,967 only like a single player experience. 399 00:24:16,967 --> 00:24:18,537 And it already makes a lot of sense there. 400 00:24:18,537 --> 00:24:19,437 And they were like, okay. 401 00:24:19,847 --> 00:24:23,537 Later on, maybe in a year or a bit more, we'll add like team and 402 00:24:23,547 --> 00:24:27,027 organization features, and that'll probably be like a huge topic, right? 403 00:24:27,387 --> 00:24:32,227 But because they build it with Jazz, the idea of users and permissions is just 404 00:24:32,227 --> 00:24:38,097 like baked in and literally all they had to do to make it multiplayer was to 405 00:24:38,117 --> 00:24:40,297 build the UI for a little invite button. 406 00:24:40,937 --> 00:24:45,427 and their, their app was like multiplayer team ready from day one 407 00:24:45,467 --> 00:24:50,027 while preserving all of these like privacy and data protection guarantees. 408 00:24:50,547 --> 00:24:53,117 Anyways, just like a short addition to that. 409 00:24:53,707 --> 00:24:57,027 I'm also really excited about Learn Anything for exactly the reasons that 410 00:24:57,027 --> 00:25:01,337 you mentioned, because I didn't think that quote unquote local-first could 411 00:25:01,337 --> 00:25:05,880 stretch that far and that's maybe where I'll go into a bit of a spicy take 412 00:25:05,880 --> 00:25:11,500 and ask the question of like, Just how useful as a term is local-first 413 00:25:11,520 --> 00:25:16,120 really, because it's really good at describing local-first apps, right? 414 00:25:16,160 --> 00:25:21,690 But the abstractions that we build to make local-first possible, or at least in my 415 00:25:21,690 --> 00:25:25,600 case, what I'm trying to build with Jazz, it actually feels like something slightly 416 00:25:25,610 --> 00:25:30,170 more general than that, where like one thing I like to call it is like it's 417 00:25:30,190 --> 00:25:34,487 distributed state, and you already see that a little bit with apps like Succulent 418 00:25:34,487 --> 00:25:36,490 that has a server component, I don't know. 419 00:25:36,500 --> 00:25:39,410 We have a couple examples with server components that already stretches it, 420 00:25:39,410 --> 00:25:44,180 but it's still just Jazz and it's, it's distributed state, not just across end 421 00:25:44,180 --> 00:25:46,490 user clients, but across server workers. 422 00:25:46,840 --> 00:25:49,510 But again, the trust relationships are now explicit. 423 00:25:49,510 --> 00:25:52,490 It's not just frontend and backend, but all these individual things. 424 00:25:52,750 --> 00:25:55,140 The way it works in Jazz, by the way, is that the server workers 425 00:25:55,150 --> 00:25:57,920 also have an account like a user and you need to invite them. 426 00:25:58,302 --> 00:26:02,522 Two specific pieces of data for them to be able to see it and do stuff with it. 427 00:26:03,245 --> 00:26:05,985 so I really liked this idea of distributed state. 428 00:26:06,005 --> 00:26:11,098 And then, I also had this like coming to Jesus moment with Jazz where 429 00:26:11,098 --> 00:26:16,993 I'm like, what I'm building here is actually a distributed database. 430 00:26:17,083 --> 00:26:19,653 And I have to be honest with myself that it's a database. 431 00:26:19,653 --> 00:26:23,347 And, I don't know how many people that are listening or watching 432 00:26:23,347 --> 00:26:25,027 this are familiar with Redis. 433 00:26:25,457 --> 00:26:29,047 But one way I always like looking at Redis is that it's like, it's, it's 434 00:26:29,057 --> 00:26:31,177 kind of like an exploded database. 435 00:26:31,557 --> 00:26:35,627 It doesn't give you the nice high level relational API that, that usual 436 00:26:35,637 --> 00:26:38,367 databases have, but it gives you all the little tools that you need 437 00:26:38,367 --> 00:26:40,087 to kind of build your own database. 438 00:26:40,437 --> 00:26:44,655 So you can have like your raw key value store and then different ways 439 00:26:44,655 --> 00:26:48,115 to build indices or like spatial lookup structures and stuff like that. 440 00:26:48,115 --> 00:26:49,455 And that's really powerful. 441 00:26:49,945 --> 00:26:51,625 And Jazz is kind of similar in a way. 442 00:26:51,625 --> 00:26:55,015 It's like, I would say it's like an exploded distributed database 443 00:26:55,035 --> 00:26:56,405 with permissions built in. 444 00:26:56,405 --> 00:26:59,485 And once you start thinking about it like that. 445 00:27:00,110 --> 00:27:04,540 There's suddenly way more use cases where it can be a useful tool, including 446 00:27:04,540 --> 00:27:09,250 stuff like the, being this like real time layer in a purely backend setting, 447 00:27:09,260 --> 00:27:15,430 or you could imagine using Jazz as like a, distributing configuration for apps. 448 00:27:15,430 --> 00:27:19,530 So like anything that's a distributed system where you might have network 449 00:27:19,530 --> 00:27:25,100 failures, nodes going offline, but you want to have meaningfully shared state 450 00:27:25,110 --> 00:27:27,240 with like History and auditability. 451 00:27:27,240 --> 00:27:28,940 You can actually use Jazz for that. 452 00:27:28,940 --> 00:27:33,220 And I think even though I'm trying really hard to envision all these different use 453 00:27:33,220 --> 00:27:37,080 cases and build for it, there's probably a ton more that people will come up 454 00:27:37,080 --> 00:27:41,850 with, just by having something that's so flexible without like a narrow minded 455 00:27:41,870 --> 00:27:45,430 use case of like, this is for local-first apps or like, this is a database. 456 00:27:45,750 --> 00:27:46,430 Does that make sense? 457 00:27:47,013 --> 00:27:47,613 Totally. 458 00:27:47,680 --> 00:27:48,000 yeah. 459 00:27:48,060 --> 00:27:53,350 And I would love to dig in a little bit more into the social network aspect. 460 00:27:53,350 --> 00:27:59,390 I think the exploded database analogy is, is very useful and maybe that also 461 00:27:59,440 --> 00:28:04,017 addresses a little bit how, Jazz is able to stretch beyond that, but can you 462 00:28:04,017 --> 00:28:05,807 make the, a little bit more specific? 463 00:28:06,010 --> 00:28:06,740 when you. 464 00:28:07,070 --> 00:28:11,937 Remember other people, me included, saying that, for local-first, anything 465 00:28:11,937 --> 00:28:17,117 that's looks and smells like a social network or like a global, like basically 466 00:28:17,127 --> 00:28:21,937 if you have a lot of strongly connected, a vast set of strongly connected data 467 00:28:21,937 --> 00:28:27,807 points, this is where local-first has a harder time to sync all of that. 468 00:28:27,837 --> 00:28:31,177 And it seems like that would mean you need to sync literally everything. 469 00:28:31,427 --> 00:28:32,427 So you need to. 470 00:28:33,142 --> 00:28:38,272 Chop off certain points in the everything is connected graph to not 471 00:28:38,272 --> 00:28:43,802 let the user wait forever until all the graph data is there, but to only 472 00:28:43,802 --> 00:28:45,932 show the user what they actually need. 473 00:28:46,342 --> 00:28:47,912 So how do you work around 474 00:28:47,962 --> 00:28:48,192 that? 475 00:28:48,232 --> 00:28:50,312 Or do you need to sync everything? 476 00:28:50,352 --> 00:28:53,332 That's kind of like, other than the like user identity and 477 00:28:53,332 --> 00:28:55,032 permissions making Jazz special. 478 00:28:55,042 --> 00:28:58,562 That's I think the only other big point that makes Jazz special 479 00:28:58,562 --> 00:29:01,692 is that from the beginning I kind of knew that it had to be. 480 00:29:02,187 --> 00:29:07,077 Super granular when it comes to which chunks of data are you loading? 481 00:29:07,087 --> 00:29:11,327 And it's, it's much more, it's basically on demand by default. 482 00:29:11,937 --> 00:29:16,157 And the underlying data model is like an infinitely big graph of 483 00:29:16,157 --> 00:29:17,747 data that can reference each other. 484 00:29:17,747 --> 00:29:18,377 And you like. 485 00:29:18,792 --> 00:29:21,592 Load sub graphs of that as needed. 486 00:29:21,982 --> 00:29:27,582 And for like a very local-first or classical app, that means, well, you 487 00:29:27,582 --> 00:29:31,882 kind of end up everything that one user needs or like a small team of people 488 00:29:31,882 --> 00:29:36,350 needs and there it's very obvious how that works well, I think the surprising 489 00:29:36,360 --> 00:29:40,340 insight is maybe that even in something crazy like a social network, even where 490 00:29:40,340 --> 00:29:44,240 you have single nodes, like people who might have a lot of followers, it's 491 00:29:44,270 --> 00:29:49,600 actually still quite like manageable graphs that are quite independent. 492 00:29:50,150 --> 00:29:57,190 And what doesn't work is in my design sense, you can't ask the app developer 493 00:29:57,190 --> 00:30:00,770 to have to come up with the boundary of like, what is a chunk of data that 494 00:30:00,770 --> 00:30:02,450 makes sense to be loaded at once. 495 00:30:02,810 --> 00:30:06,770 I think maybe you could get away with it for an app like Notion where like 496 00:30:06,790 --> 00:30:10,670 the document is an obvious boundary to do that for, but even there it's 497 00:30:10,680 --> 00:30:14,510 kind of annoying and gets in the way, particularly with sharing and so on. 498 00:30:14,840 --> 00:30:18,610 So I think you just have to adapt that like a hundred percent granular mindset. 499 00:30:18,970 --> 00:30:22,953 And then it turns out, Even the very highly connected graphs, they're actually 500 00:30:22,953 --> 00:30:27,853 manageable in size, and it is feasible to load them to display, for example, one 501 00:30:27,863 --> 00:30:32,223 learning topic and Learn Anything, even if it has thousands of links and thousands 502 00:30:32,223 --> 00:30:34,113 of people interacting with that topic. 503 00:30:34,353 --> 00:30:38,523 That's actually, in the grand scheme of things, not that much data to sync. 504 00:30:39,063 --> 00:30:42,877 And on my infrastructure, which is kind of inherently distributed. 505 00:30:42,877 --> 00:30:46,980 It's like, obviously geographically distributed because that's like a nice 506 00:30:47,010 --> 00:30:50,040 metric to kind of chunk data up against. 507 00:30:50,322 --> 00:30:55,072 you can also start doing something very similar to sharding where you basically 508 00:30:55,522 --> 00:31:00,512 co locate data that is often accessed together, again, on a very granular level. 509 00:31:00,512 --> 00:31:04,072 And then suddenly even this like really hot data with lots of 510 00:31:04,082 --> 00:31:06,192 people interacting easily fits. 511 00:31:06,517 --> 00:31:09,697 into a single node, even a single core, and it's feasible to 512 00:31:09,697 --> 00:31:13,067 sync it to clients who all want roughly the same stuff anyways. 513 00:31:13,470 --> 00:31:18,690 and if you're being honest, like databases face exactly that problem and that the 514 00:31:18,690 --> 00:31:24,380 way it's solved usually is just by scaling it,, like making your database node huge 515 00:31:24,380 --> 00:31:28,870 so it can fit all of the data for all of the users and then distributing and 516 00:31:28,870 --> 00:31:33,700 scaling databases is a hugely complicated topic and I think in many ways local-first 517 00:31:33,720 --> 00:31:37,410 is actually an answer to that in the sense that in the most extreme case 518 00:31:37,410 --> 00:31:41,757 you're like well we only need to worry about the data of one user and we'll 519 00:31:41,757 --> 00:31:46,987 have a system that manages the data for one user, which is their machine. 520 00:31:47,730 --> 00:31:52,690 but then the abstractions you build to make that possible, if you include 521 00:31:52,690 --> 00:31:57,180 the granularity, actually also let you do everything in between where, 522 00:31:57,754 --> 00:32:04,174 yeah, you, you can have a couple of nodes collaborating to sync and 523 00:32:04,194 --> 00:32:09,059 persist and serve like, Subgraphs of that, like infinitely big data. 524 00:32:09,059 --> 00:32:09,929 Does that make sense? 525 00:32:10,312 --> 00:32:11,492 That makes total sense. 526 00:32:11,502 --> 00:32:14,872 And before we're going even deeper here, and I think we're stretching a 527 00:32:14,872 --> 00:32:18,752 little bit into some like implementation details here, et cetera, which are super 528 00:32:18,762 --> 00:32:23,312 interesting, but maybe we take a little step back as a application developer 529 00:32:23,312 --> 00:32:25,697 who wants to build something with Jazz. 530 00:32:25,697 --> 00:32:28,600 Maybe you can walk us through, what does that look like? 531 00:32:28,600 --> 00:32:33,440 So just to give a little bit of like a spectrum of options, we had Matt 532 00:32:33,440 --> 00:32:37,398 Wonlaw on the show where we, for example, talked about CR SQLite, 533 00:32:37,398 --> 00:32:42,771 where the idea was that, you replicate a SQLite database across devices. 534 00:32:43,031 --> 00:32:46,651 So this is where you have already Something that developers are 535 00:32:46,651 --> 00:32:50,231 very familiar with, which is a relational database that you can 536 00:32:50,231 --> 00:32:52,535 just embed in the app and then query. 537 00:32:52,535 --> 00:32:53,655 So that's one approach. 538 00:32:53,915 --> 00:32:58,755 we heard from the folks working on AutoMerge, which is a CRDT based 539 00:32:59,035 --> 00:33:03,935 system, so where you rather think less about a database that's replicated. 540 00:33:04,630 --> 00:33:10,263 But more about individual documents, that are being replicated and state 541 00:33:10,283 --> 00:33:16,353 based as you change the CRDT document, those state changes are being propagated. 542 00:33:16,730 --> 00:33:20,576 and there could be also other options, for LiveStore, for example, I'm following more 543 00:33:20,576 --> 00:33:26,546 of like a, what I consider a combination of both approaches where you distribute 544 00:33:26,886 --> 00:33:32,076 a event log and you recompute a, in this case, a SQLite database from it. 545 00:33:32,086 --> 00:33:37,483 So there's various flavors, various trade offs, which path have you've been 546 00:33:37,693 --> 00:33:40,973 going down with Jazz and maybe also why. 547 00:33:41,506 --> 00:33:41,886 Yeah. 548 00:33:42,336 --> 00:33:46,466 So the meta comment there is that like, after you think about it for a really 549 00:33:46,466 --> 00:33:50,686 long time, a lot of these approaches end up actually being the same, but it 550 00:33:50,686 --> 00:33:54,986 really matters, I think, in terms of contrasting different frameworks and 551 00:33:54,996 --> 00:33:59,626 solutions and introducing people to the idea in the first place, from which 552 00:33:59,656 --> 00:34:01,596 angle you approach it and like the. 553 00:34:01,891 --> 00:34:06,271 It's like a replicated local database that's relational is a very obvious one. 554 00:34:06,271 --> 00:34:08,571 And there's a lot of people doing that really well now. 555 00:34:08,828 --> 00:34:11,168 the document one is an obvious one. 556 00:34:11,468 --> 00:34:14,398 I think you'll be able to predict what, what my issue with 557 00:34:14,398 --> 00:34:15,898 it is that it like makes you. 558 00:34:16,143 --> 00:34:18,763 Put the boundaries, but I'm basically doing that. 559 00:34:18,763 --> 00:34:20,303 I'm doing what AutoMerge is doing. 560 00:34:20,313 --> 00:34:24,453 It looks like state, and I'll say that a bit more precisely in a second, 561 00:34:24,583 --> 00:34:26,173 but again, it's a bit more granular. 562 00:34:26,193 --> 00:34:30,993 And the way I describe it typically, like the audience that I have in mind 563 00:34:31,033 --> 00:34:35,923 is actually not full stack developers or backend developers who are very 564 00:34:35,923 --> 00:34:41,143 familiar with relational databases, but in my case, frontend developers who 565 00:34:41,143 --> 00:34:45,988 are familiar with Local UI state on the one hand and kind of making requests 566 00:34:45,988 --> 00:34:49,828 to APIs as like the only external system they ever need to worry about. 567 00:34:49,828 --> 00:34:55,748 So the story I tell this Imagine Frontend developer is that imagine 568 00:34:55,758 --> 00:35:01,928 if you could kind of mock up an app just based on local, like React use 569 00:35:01,938 --> 00:35:06,368 state or like equivalent things, and you build your UI around that. 570 00:35:06,634 --> 00:35:12,663 but then magically your app actually works and like all of the status persistent 571 00:35:12,703 --> 00:35:17,343 and you can share it with other users and, you have permissions on there and 572 00:35:18,113 --> 00:35:20,433 you still only wrote front end code. 573 00:35:21,093 --> 00:35:25,373 That's kind of the Jazz story and that's what the API looks and feels like. 574 00:35:25,753 --> 00:35:29,343 So if, if you build an app with Jazz, typically the first thing you do is. 575 00:35:30,038 --> 00:35:33,518 You actually do something kind of database y, which is that you define a schema 576 00:35:33,568 --> 00:35:38,178 just to describe kind of what is the shape of data, which kinds of objects 577 00:35:38,208 --> 00:35:40,158 are the main abstractions in my app. 578 00:35:40,581 --> 00:35:44,771 interestingly, you don't have to model users at all because that's just baked in. 579 00:35:44,771 --> 00:35:48,541 So it's very nicely like, what are just the concepts that are 580 00:35:48,551 --> 00:35:52,033 specific to your domain that you're, addressing with your app. 581 00:35:52,583 --> 00:35:58,513 And once you have the schema, you can just start having state of objects in 582 00:35:58,513 --> 00:36:00,333 that schema and build UI around it. 583 00:36:00,783 --> 00:36:04,633 And you can create objects of different types out of your schema locally, and you 584 00:36:04,633 --> 00:36:08,566 can create like, groups, which is kind of like the permission structure in Jazz 585 00:36:08,596 --> 00:36:15,036 and put objects in groups and then like give users access rights to groups, all 586 00:36:15,176 --> 00:36:19,256 like you can do these things literally in an on click handler of a button. 587 00:36:19,971 --> 00:36:23,941 And it feels kind of illegal because of how simple it is, but that's it. 588 00:36:23,951 --> 00:36:27,651 That's how you build apps with Jazz and you can get very far with just that. 589 00:36:28,061 --> 00:36:30,321 As apps get more complicated, you can kind of. 590 00:36:31,026 --> 00:36:35,616 abstract things all kind of similarly to how there are solutions for not 591 00:36:35,626 --> 00:36:38,106 letting UI state get too complex. 592 00:36:38,546 --> 00:36:41,816 and the other thing you might need to start, if you want to talk to external 593 00:36:41,816 --> 00:36:46,676 systems like third party APIs, you can build the server workers that I 594 00:36:46,676 --> 00:36:48,046 talked about a couple of times now. 595 00:36:48,096 --> 00:36:49,161 But the nice thing is you can build. 596 00:36:49,331 --> 00:36:51,901 If you also write them in TypeScript, for example, you just 597 00:36:51,901 --> 00:36:55,311 share the same data schema that you're using for the front end. 598 00:36:55,601 --> 00:36:59,381 And it really just feels like one, one small addition to your 599 00:36:59,511 --> 00:37:01,151 otherwise purely front end code. 600 00:37:01,611 --> 00:37:03,931 That's, that's kind of the Jazz experience, right? 601 00:37:04,775 --> 00:37:05,855 That makes a lot of sense. 602 00:37:05,875 --> 00:37:07,365 And I've just in parallel. 603 00:37:07,630 --> 00:37:11,560 going through the Jazz landing page here, where you have, this 604 00:37:11,560 --> 00:37:16,410 really cool chat app and 174 lines of code embedded here as well. 605 00:37:16,410 --> 00:37:20,070 We can just see exactly that, like a little schema definition 606 00:37:20,070 --> 00:37:21,690 of this case for this chat app. 607 00:37:21,690 --> 00:37:23,680 There's just like a message. 608 00:37:23,855 --> 00:37:26,685 Class, a message concept and a chat concept. 609 00:37:27,048 --> 00:37:27,728 and that's it. 610 00:37:27,758 --> 00:37:33,151 You can use it right away in your React code, in your other code, and fire away. 611 00:37:33,571 --> 00:37:38,411 and you've also have here the user concept where you see like, okay, 612 00:37:38,821 --> 00:37:43,611 something is owned by me and then the chat, for example, is owned by a group. 613 00:37:44,158 --> 00:37:48,978 what if I want to go a little bit more specific here and enforce 614 00:37:48,978 --> 00:37:54,043 certain Permission rules, that are more specific to my app. 615 00:37:54,690 --> 00:37:57,080 what is the story in progression there? 616 00:37:57,673 --> 00:38:03,063 So the way that that works is that it doesn't get more complicated than groups 617 00:38:03,063 --> 00:38:04,683 and objects belonging to the group. 618 00:38:04,683 --> 00:38:08,743 So like whenever you create an object in Jazz and like, I should say 619 00:38:08,743 --> 00:38:12,313 the name for them, we call them co values, like collaborative values. 620 00:38:12,333 --> 00:38:14,463 You have like co maps that are kind of like. 621 00:38:14,898 --> 00:38:19,128 JavaScript objects, co lists that are like collaborative arrays, basically. 622 00:38:19,558 --> 00:38:24,348 and just like you can represent a lot of different kinds of data with JSON, you 623 00:38:24,348 --> 00:38:29,188 can represent a lot of different kinds of collaborative data with co values, right? 624 00:38:29,968 --> 00:38:32,218 And each co value has to belong to a group. 625 00:38:32,308 --> 00:38:36,678 The group is like the scope for permissions, and it simply has user 626 00:38:36,718 --> 00:38:38,768 accounts in it with a certain role. 627 00:38:39,238 --> 00:38:43,128 The three roles that exist are Reader, Writer, or Admin. 628 00:38:43,478 --> 00:38:45,358 They do exactly what it says on the tin. 629 00:38:45,781 --> 00:38:49,611 and they then influence what people can do on co values. 630 00:38:49,611 --> 00:38:52,511 We can talk in detail later how that works under the hood, because 631 00:38:52,511 --> 00:38:53,911 I think that's interesting as well. 632 00:38:53,911 --> 00:38:55,771 But for now, that's all you need to know. 633 00:38:55,771 --> 00:39:00,181 And that maps quite naturally on onto a lot of stuff that you want to do in apps. 634 00:39:00,521 --> 00:39:03,211 But then the question is what about more complicated situations? 635 00:39:03,231 --> 00:39:05,981 And the answer there again is the granularity. 636 00:39:06,321 --> 00:39:12,548 Because if you wanted to every, each co value, like imagine like a kind 637 00:39:12,548 --> 00:39:17,293 of tree of co values representing the state of a more complicated document 638 00:39:17,313 --> 00:39:19,083 or even like a folder of documents. 639 00:39:19,703 --> 00:39:22,563 The way that looks like in Jazz is that they're actually each 640 00:39:22,593 --> 00:39:27,393 individual CRDTs that just have plain data as values in their fields. 641 00:39:28,168 --> 00:39:30,518 Or they can have references to other co values. 642 00:39:30,548 --> 00:39:33,478 And that's how you build this, like, potentially infinitely big graph, 643 00:39:33,478 --> 00:39:36,018 and you, like, load whatever you need to, like, display right now, 644 00:39:36,018 --> 00:39:37,378 or what you want to have offline. 645 00:39:37,898 --> 00:39:41,258 But the nice thing is that the groups that these co values belong 646 00:39:41,258 --> 00:39:44,678 to, and the permission structures, therefore, are kind of orthogonal 647 00:39:44,698 --> 00:39:46,078 to the, like, data references. 648 00:39:46,118 --> 00:39:49,993 So you can reference a co value, That belongs to a different group that 649 00:39:50,003 --> 00:39:53,343 has different members or where the same members have different roles. 650 00:39:53,763 --> 00:39:57,583 And that way you can build permission structures that are just as granular. 651 00:39:57,583 --> 00:40:03,293 And you can even have like something like a notion document where like a small block 652 00:40:03,343 --> 00:40:05,413 might only be editable by some people. 653 00:40:05,830 --> 00:40:06,710 does that make sense? 654 00:40:07,093 --> 00:40:07,623 totally. 655 00:40:07,703 --> 00:40:13,543 you, you've been mentioning the reference concept that is giving you the kind of 656 00:40:13,543 --> 00:40:19,043 like a relation for a key kind of concept between different kinds of documents, 657 00:40:19,563 --> 00:40:22,333 and I think this is also describing the. 658 00:40:22,613 --> 00:40:27,823 the boundary between one thing that needs to be synced and then another 659 00:40:27,823 --> 00:40:29,323 thing that needs to be synced. 660 00:40:29,373 --> 00:40:34,873 And if you model a thing like a network with that, how does, 661 00:40:34,996 --> 00:40:39,576 Jazz, how does it know where to, uh, how much it needs to sync? 662 00:40:39,576 --> 00:40:40,816 Where does it need to stop? 663 00:40:41,116 --> 00:40:46,476 Is there, so one analogy, for example, in GraphQL . maybe not everyone is familiar 664 00:40:46,476 --> 00:40:51,216 with that, but it's like a query language that is language agnostic and can be 665 00:40:51,226 --> 00:40:52,886 implemented with any sort of backend. 666 00:40:53,186 --> 00:40:58,196 And this is where you can also define a schema kind of similar to this here. 667 00:40:58,563 --> 00:41:04,763 and aside from the schema, describes the potential graph of queries, or 668 00:41:04,923 --> 00:41:07,713 set of queries in a specific query. 669 00:41:08,080 --> 00:41:12,156 you need to very explicitly say, those are the things that I want to query. 670 00:41:12,176 --> 00:41:18,200 So let's say we model a file system from this, where we have folders and files 671 00:41:18,450 --> 00:41:22,890 and folders can have folders and folders can have folders in a GraphQL query. 672 00:41:23,185 --> 00:41:27,855 You need to say, actually, I want to, you need to explicitly lay out. 673 00:41:27,875 --> 00:41:30,365 I want to go like all the way to like level three. 674 00:41:30,795 --> 00:41:34,515 So you need to say, I want to grab the folders and in that folders, I'm 675 00:41:34,515 --> 00:41:36,065 going to grab again, the folders. 676 00:41:36,065 --> 00:41:39,905 And I want to, there again, grab the folders, but you can't self 677 00:41:39,915 --> 00:41:42,835 recursively, infinitely, traverse. 678 00:41:43,385 --> 00:41:50,375 Is there a similar kind of explicit depth to how jazz should sync something. 679 00:41:50,655 --> 00:41:56,965 Is that determined at runtime by a React component, for example, is 680 00:41:56,965 --> 00:41:58,375 there some sort of middle ground? 681 00:41:58,385 --> 00:41:59,255 How does that work? 682 00:41:59,665 --> 00:42:03,828 So there are kind of, and it's a really good question because like, that's kind 683 00:42:03,828 --> 00:42:06,168 of, you need a system that solves that. 684 00:42:06,168 --> 00:42:09,998 If you don't have the explicit boundary of like, this is, we can 685 00:42:10,008 --> 00:42:11,548 either sync all of that or nothing. 686 00:42:11,548 --> 00:42:11,838 Right. 687 00:42:12,048 --> 00:42:14,198 And the file system is a good example because it's. 688 00:42:14,503 --> 00:42:17,633 It's kind of potentially infinitely deep, but you're probably only ever looking 689 00:42:17,633 --> 00:42:19,853 at a subset, so how do you do that? 690 00:42:19,863 --> 00:42:24,233 And the way, the quick and dirty way you do it in Jazz, which is actually 691 00:42:24,233 --> 00:42:29,333 really fun to just, again, super quickly build your eyes that work, is that, 692 00:42:29,706 --> 00:42:35,266 Jazz tries really hard to make covalues look like just plain JSON objects. 693 00:42:35,756 --> 00:42:40,096 And if you have co values with references to each other, they look like JSON trees. 694 00:42:40,536 --> 00:42:43,086 So what do you do then if like at some point you might 695 00:42:43,086 --> 00:42:44,476 not have a co value loaded? 696 00:42:44,506 --> 00:42:48,576 Well, then it just says that it's in a TypeScript sense that field is 697 00:42:48,616 --> 00:42:51,006 either the reference thing or null. 698 00:42:51,394 --> 00:42:55,580 And,, if you try and render a specific tree in a React component, 699 00:42:55,590 --> 00:43:00,460 you can basically just use optional chaining to like render like this far. 700 00:43:00,460 --> 00:43:03,270 And if it's not loaded, show like a little spinner or something. 701 00:43:03,820 --> 00:43:08,843 But the funny thing then is that Jazz notices what you are trying to access. 702 00:43:09,275 --> 00:43:12,065 And it's like, Oh, you're trying to render like three levels deep. 703 00:43:12,065 --> 00:43:16,015 And you try to access this thing that we don't have yet in the background 704 00:43:16,085 --> 00:43:18,625 triggers a sync of the needed co value. 705 00:43:19,025 --> 00:43:22,445 And once that's available locally, it re renders your component. 706 00:43:22,445 --> 00:43:26,275 And now that's not null anymore, but you actually have the JSON state 707 00:43:26,435 --> 00:43:28,195 for that co value and you render it. 708 00:43:28,715 --> 00:43:33,725 So very naturally by like building your UI and just deciding to render. 709 00:43:34,170 --> 00:43:37,830 What do you want to render it will lazily load exactly what's needed. 710 00:43:38,230 --> 00:43:41,723 And you can even manually do pagination like that by just having 711 00:43:41,723 --> 00:43:45,583 a little stateful, like, oh, I want to render 10 items and then you only 712 00:43:45,583 --> 00:43:47,633 drill down into the first 10 items. 713 00:43:47,653 --> 00:43:51,158 And then like you hit a button or you reach the end of a scroll list or like. 714 00:43:51,518 --> 00:43:54,498 Elements become visible on the screen and you just ask Jazz to 715 00:43:54,768 --> 00:43:58,118 access more of them, even if they're right now, not, not available. 716 00:43:58,388 --> 00:43:59,888 And in the background, it will load more. 717 00:44:00,298 --> 00:44:01,528 That's the quick and dirty way. 718 00:44:01,528 --> 00:44:03,348 Super nice for prototyping stuff. 719 00:44:03,895 --> 00:44:08,315 It's a bit weird in terms of user experience, because you end up with a lot 720 00:44:08,315 --> 00:44:12,525 of spinners and they like, they resolve really quickly because Jazz is fast, 721 00:44:12,575 --> 00:44:14,905 but it still looks unfamiliar to people. 722 00:44:15,455 --> 00:44:21,895 So if you want to give people a more polished experience of maybe one Loading 723 00:44:21,905 --> 00:44:24,855 thing until a bunch of status available. 724 00:44:24,855 --> 00:44:26,285 That makes sense as a unit. 725 00:44:26,855 --> 00:44:32,065 There is a way of specifically specifying a loading depth and that's. 726 00:44:32,905 --> 00:44:38,135 That kind of looks like GraphQL lite, but because you only need to specify 727 00:44:38,135 --> 00:44:41,805 fields that are references, you don't need to say which plain data fields 728 00:44:41,805 --> 00:44:43,415 you need because they're always loaded. 729 00:44:43,941 --> 00:44:46,381 yeah, you, you, it's, it's actually very similar to Prisma. 730 00:44:46,391 --> 00:44:51,221 You just say which references you want resolved and then the Jazz hooks. 731 00:44:51,511 --> 00:44:54,761 Won't give you anything until all of that is loaded and then 732 00:44:54,761 --> 00:44:55,981 they give it to you as a chunk. 733 00:44:56,431 --> 00:44:57,411 That makes a lot of sense. 734 00:44:57,421 --> 00:45:02,181 So you're basically just specifying sort of the graph of the references, 735 00:45:02,261 --> 00:45:06,971 not the individual fields of a document, since you typically want a document 736 00:45:06,991 --> 00:45:08,911 as a whole, that makes a lot of sense. 737 00:45:08,921 --> 00:45:12,941 And that's also, as I'm thinking through how I would model something for Overtone. 738 00:45:13,185 --> 00:45:17,565 when I have a music app and I want to listen to music, if I'm currently 739 00:45:17,895 --> 00:45:22,970 ermbarking on a train journey or on a like traveling somewhere where 740 00:45:22,970 --> 00:45:24,630 I don't have perfect connectivity. 741 00:45:25,240 --> 00:45:31,860 I want to like that lazy loading just in time as I like click on a playlist. 742 00:45:32,326 --> 00:45:36,096 if I don't have connectivity, then at that point, it kind of breaks a 743 00:45:36,106 --> 00:45:38,016 bit of like that local-first promise. 744 00:45:38,440 --> 00:45:42,290 but I also understand like, let's say, Spotify is thinking 745 00:45:42,290 --> 00:45:44,160 about building it in that way. 746 00:45:44,350 --> 00:45:50,430 Spotify can't just sync the entire catalog of like all of Spotify on a single device. 747 00:45:50,610 --> 00:45:52,730 So there needs to be like some cutoff point. 748 00:45:53,160 --> 00:45:58,420 And I think while prototyping doing the just in time lazy loading, that's great. 749 00:45:58,720 --> 00:46:02,020 But then as an app developer, in this case, for example, me building 750 00:46:02,040 --> 00:46:04,320 Overtone, as I better know, okay. 751 00:46:04,580 --> 00:46:08,070 I want you to find some rules of like, that stuff should always 752 00:46:08,070 --> 00:46:11,690 be there, like prepared for me going on a, on a train journey. 753 00:46:12,050 --> 00:46:13,830 And that would probably in this case be. 754 00:46:14,225 --> 00:46:18,215 For all of my playlists, make sure like all of like the tracks for the 755 00:46:18,215 --> 00:46:22,285 individual playlists are at least the metadata is there and possibly 756 00:46:22,285 --> 00:46:25,825 then have like also some rules for pre downloading some tracks. 757 00:46:25,825 --> 00:46:27,731 If I have the rights to do so. 758 00:46:28,118 --> 00:46:29,028 that makes a lot of sense. 759 00:46:29,038 --> 00:46:35,648 And that seems like Jazz provides a really nice trade off of making, providing a 760 00:46:35,768 --> 00:46:41,218 easy way right away to prototype and then, dial it in to match the user 761 00:46:41,218 --> 00:46:42,578 experience that you want to provide. 762 00:46:43,135 --> 00:46:46,565 And I guess I met the comment here with like, because you actually just 763 00:46:46,565 --> 00:46:50,665 now asked a very precise, interesting question, which is like, well, what 764 00:46:50,665 --> 00:46:54,385 if you ask it to load a chunk of data and not give it to you until all of 765 00:46:54,385 --> 00:46:59,025 it is there, but then your connection drops, what should actually happen? 766 00:46:59,025 --> 00:47:01,994 And like nothing being loaded, then it's actually a. 767 00:47:02,058 --> 00:47:04,748 Like you said, an outcome that violates local-first a bit. 768 00:47:04,748 --> 00:47:09,308 So there, then we need to be more refined and be like, well, maybe show 769 00:47:09,308 --> 00:47:13,178 a spinner for everything for like two seconds and then give up and just show 770 00:47:13,178 --> 00:47:15,098 me everything that was actually loaded. 771 00:47:15,545 --> 00:47:19,975 and what we're getting to there is that I think like, look, I think 772 00:47:19,975 --> 00:47:25,415 it's starting to become clear how local-first in general is this cool 773 00:47:25,415 --> 00:47:29,225 new way of building app and how Jazz in particular things really deeply, how to 774 00:47:29,225 --> 00:47:30,925 make that easy for you as a developer. 775 00:47:31,348 --> 00:47:35,068 But most of the challenges with local-first and with multiplayer, by the 776 00:47:35,068 --> 00:47:40,078 way, I think are UX challenges where we're like, well, what, what should happen? 777 00:47:40,418 --> 00:47:43,308 And that's something that we figure out as we try to build 778 00:47:43,308 --> 00:47:44,828 and dog food, our own apps. 779 00:47:45,548 --> 00:47:51,189 As we see what, our first adopters build with it and what makes sense 780 00:47:51,199 --> 00:47:54,339 to their particular developers and how you want to expose all of these 781 00:47:54,339 --> 00:47:55,839 different, like, is it loading? 782 00:47:55,849 --> 00:47:57,119 Is it locally available? 783 00:47:57,339 --> 00:47:58,489 Is it locally available? 784 00:47:58,489 --> 00:48:03,859 But it's like, not quite up to date with what we know the syncing server has, but 785 00:48:03,859 --> 00:48:05,549 we didn't have a chance to get that yet. 786 00:48:05,549 --> 00:48:07,729 And there's like so much complexity in there. 787 00:48:07,979 --> 00:48:11,989 And in different situations, you need to expose like more or less of that. 788 00:48:11,999 --> 00:48:14,049 So I think beyond just like. 789 00:48:14,439 --> 00:48:18,059 Making the sync and making the data persistence and making the permissions 790 00:48:18,089 --> 00:48:22,109 work, which like we're pretty good with now, there'll be a lot of like 791 00:48:22,119 --> 00:48:27,059 API design and also like educating developers and just figuring out UX 792 00:48:27,389 --> 00:48:29,619 together, like as a field, I think. 793 00:48:30,102 --> 00:48:31,192 I definitely agree. 794 00:48:31,232 --> 00:48:34,442 And like just the scenarios that we've now went through over the 795 00:48:34,442 --> 00:48:38,132 last couple of minutes, I think already go surprisingly deep. 796 00:48:38,482 --> 00:48:42,912 For example, like the partial, like if you want to load everything and then you say, 797 00:48:42,942 --> 00:48:47,292 okay, I don't have everything, in some cases, it's fine to show a partial set. 798 00:48:47,632 --> 00:48:53,002 In some other cases, it might be like really nerve wracking for a user where if 799 00:48:53,002 --> 00:48:57,162 you don't signal like, Hey, we've just, we, we can't say this is everything. 800 00:48:57,162 --> 00:49:00,952 We've just fetched so much since otherwise a user might assume, Oh my gosh. 801 00:49:00,952 --> 00:49:02,962 Like this app has like lost some of my data. 802 00:49:03,227 --> 00:49:07,557 and so this might, in some cases might be better to not show anything 803 00:49:07,947 --> 00:49:11,747 and like explicitly let the user know, like, Hey, we're sorry. 804 00:49:12,004 --> 00:49:15,294 when you come online again, we'll do our best to get everything in here. 805 00:49:15,584 --> 00:49:18,934 sometimes you also like from the data you fetch, maybe you want to like, 806 00:49:19,174 --> 00:49:22,284 let's say you, you shouldn't build a bank account this way, but let's say 807 00:49:22,284 --> 00:49:25,854 you build a bank account and you've just fetched a bit of like your, 808 00:49:26,154 --> 00:49:28,124 your like transactional history. 809 00:49:28,714 --> 00:49:35,094 And it misses your latest, like, big check that you cashed in. 810 00:49:35,414 --> 00:49:38,174 Basically you added money to your bank account and it's not in there. 811 00:49:38,404 --> 00:49:42,794 And you think, Oh my gosh, like my bank account is like lost all of that money. 812 00:49:42,994 --> 00:49:47,244 Obviously you won't build an app like that, but I think the analogy kind of 813 00:49:47,244 --> 00:49:52,384 like translates where you derive data from other data and where it could be 814 00:49:52,384 --> 00:49:53,964 like really bad, you missed something. 815 00:49:53,964 --> 00:49:58,164 So this is really interesting to dig into the user experience aspects. 816 00:49:58,164 --> 00:50:01,904 And that might also make for a really interesting future conversation, 817 00:50:02,244 --> 00:50:07,701 but I want to, Dig a little bit more into, into another related topic, 818 00:50:07,751 --> 00:50:10,411 which is the localfirst.fm podcast. 819 00:50:10,661 --> 00:50:14,551 And what brings all of us together is that we think we can do better 820 00:50:14,551 --> 00:50:18,591 how we build apps, at least in many app use cases, and Jazz shows for 821 00:50:18,591 --> 00:50:20,971 how many app use cases that applies. 822 00:50:21,331 --> 00:50:26,736 And so that means We, as a whole, as an ecosystem, we need to convince 823 00:50:26,736 --> 00:50:30,766 the people who are not yet in that small but growing ecosystem. 824 00:50:30,766 --> 00:50:34,526 We need to convince them that we have a very interesting way how to 825 00:50:34,536 --> 00:50:39,386 build apps better, that are simpler to build, better for end users, etc. 826 00:50:39,696 --> 00:50:45,292 And I think each technology has their own specific, benefits, how that's, is 827 00:50:45,292 --> 00:50:50,359 a, is a good fit for, for certain app use cases and particular developer types. 828 00:50:50,369 --> 00:50:53,069 Like you want to target more like the front end developers. 829 00:50:53,502 --> 00:50:57,152 what is your approach to talking to developers? 830 00:50:57,332 --> 00:51:01,732 How do you want to market Jazz to reach the right people and sort of the, 831 00:51:01,852 --> 00:51:06,352 I think you have a very interesting take on sort of developer psychology. 832 00:51:06,959 --> 00:51:08,059 Yeah, yeah, totally. 833 00:51:08,059 --> 00:51:11,329 Because I think like, look, we're all facing the same challenge. 834 00:51:11,329 --> 00:51:16,719 Like you said of like, we understand how this is better and how it can benefit 835 00:51:16,909 --> 00:51:18,689 a lot of different kinds of apps. 836 00:51:19,172 --> 00:51:23,302 but counterintuitively it's, I don't think it's really about selling the benefits. 837 00:51:23,302 --> 00:51:26,952 I think the one big benefit that really does make sense. 838 00:51:26,952 --> 00:51:30,442 And it's valuable to people as just saying, look, like you've got like 839 00:51:30,742 --> 00:51:33,082 a 10 X better developer experience. 840 00:51:33,102 --> 00:51:34,692 It's way faster to build apps. 841 00:51:34,742 --> 00:51:36,222 It's way easier to reason about. 842 00:51:36,232 --> 00:51:37,792 There's way fewer moving parts. 843 00:51:38,042 --> 00:51:41,522 I think that's kind of universal across all the different solutions. 844 00:51:42,046 --> 00:51:45,406 different solutions differ in terms of like what traditional 845 00:51:45,426 --> 00:51:47,426 parts of the stack they replace. 846 00:51:47,916 --> 00:51:53,256 I've put myself in the shoe of like replacing a lot of the pieces because I 847 00:51:53,256 --> 00:51:58,266 do auth and permissions, and by the way, you can also store binary data in Jazz. 848 00:51:58,266 --> 00:52:02,726 So suddenly you don't need blob storage anymore and binary data just becomes 849 00:52:02,726 --> 00:52:06,806 part of the data you have locally and can be referenced just like JSON like data. 850 00:52:07,152 --> 00:52:11,262 and it's so easy to just think about what are the obvious advantages of that 851 00:52:11,262 --> 00:52:15,042 if you are totally bought into this and ready to build your app like that. 852 00:52:15,312 --> 00:52:16,857 That's kind of the easy part, right, to make. 853 00:52:17,142 --> 00:52:18,752 to explain that. 854 00:52:19,742 --> 00:52:23,872 But the biggest question is like, why should you even bother? 855 00:52:23,872 --> 00:52:28,322 And why should you give up this really proven, familiar way of building apps? 856 00:52:28,912 --> 00:52:33,632 that means the biggest challenge is that it's so new and alien and different. 857 00:52:34,092 --> 00:52:39,267 So I think the trick has to be How can we make it look familiar 858 00:52:39,337 --> 00:52:42,867 and how can we make it look like something that already exists? 859 00:52:43,127 --> 00:52:47,097 And that's, I think where exactly the different audiences or, ways of telling 860 00:52:47,117 --> 00:52:52,514 that story for different products come in because, saying that you're replicating 861 00:52:53,104 --> 00:52:55,624 a relational database into the client. 862 00:52:56,279 --> 00:53:00,119 That's taking something very familiar to like backend developers and then 863 00:53:00,119 --> 00:53:02,169 doing one little step away from that. 864 00:53:02,299 --> 00:53:04,699 And then like, Oh, and then it has all these benefits. 865 00:53:04,699 --> 00:53:04,979 Right. 866 00:53:05,332 --> 00:53:08,502 I feel like, yeah, I've made it hard for myself because I'm basically 867 00:53:08,512 --> 00:53:10,372 trying to replace the whole stack. 868 00:53:11,152 --> 00:53:15,812 And that's a story that actually, again, it works really well for 869 00:53:15,812 --> 00:53:19,812 frontend developers because the whole stack was never part of like 870 00:53:19,812 --> 00:53:21,682 where they had agency to begin with. 871 00:53:22,052 --> 00:53:22,972 So they're happy. 872 00:53:23,512 --> 00:53:26,682 Full stack developers and especially backend developers aren't so 873 00:53:26,682 --> 00:53:27,742 happy because you're like. 874 00:53:28,026 --> 00:53:30,536 You don't have to do all of that stuff anymore. 875 00:53:30,536 --> 00:53:32,786 It's replaced by this giant pile of magic. 876 00:53:33,202 --> 00:53:38,842 I think like, I mean, what we identify as developers is being 877 00:53:38,842 --> 00:53:40,952 clever and building stuff ourselves. 878 00:53:40,972 --> 00:53:41,322 Right. 879 00:53:41,752 --> 00:53:46,369 And I think a big part of what keeps really complicated stacks and ways 880 00:53:46,369 --> 00:53:50,379 of doing things in life is honestly just the IKEA effect of like. 881 00:53:50,637 --> 00:53:54,727 Well, but I built this myself and I like, I picked things that are individually 882 00:53:54,727 --> 00:53:58,987 good at what they're doing, but I put them together in this really clever 883 00:53:58,997 --> 00:54:04,507 way and local-first is like, it's just, it's so powerful that it takes away 884 00:54:04,507 --> 00:54:06,837 so much of that doing stuff yourself. 885 00:54:07,119 --> 00:54:09,869 That it's a real danger in terms of adoption and like not 886 00:54:09,979 --> 00:54:11,979 bruising people's egos secretly. 887 00:54:12,296 --> 00:54:18,349 so one attempt I had was like, well, can I kind of not make Jazz one giant 888 00:54:18,359 --> 00:54:21,979 package, but more smaller ones so people can glue stuff together again. 889 00:54:22,599 --> 00:54:27,889 And I think that's kind of counter to like what makes Jazz powerful, which is exactly 890 00:54:27,889 --> 00:54:32,389 that it is a vertically integrated thing where even the different parts of like. 891 00:54:32,692 --> 00:54:36,132 CRDT, stage sharing, and user identity and permissions. 892 00:54:36,182 --> 00:54:38,182 They are actually very tightly knit together. 893 00:54:38,202 --> 00:54:41,246 And that's why, yeah, that's what makes Jazz special, I think. 894 00:54:41,246 --> 00:54:44,909 But, the other way out of that, I think, and this is something I just have to 895 00:54:45,039 --> 00:54:50,299 do way more, is to have really good, like, under the hood documentation. 896 00:54:50,679 --> 00:54:54,571 And the cool thing is, like, I think CRDTs kind of get thrown around 897 00:54:54,571 --> 00:54:58,671 as this like mysterious new thing that magically solves everything, 898 00:54:58,671 --> 00:55:00,071 but like, it's really complicated. 899 00:55:00,071 --> 00:55:00,911 Don't worry about it. 900 00:55:00,911 --> 00:55:04,581 Like, you can read about it in some research papers if you really wanted 901 00:55:04,581 --> 00:55:09,461 to, but I think the way I've implemented CRDTs in Jazz is actually very. 902 00:55:09,687 --> 00:55:14,501 Very straightforward, in the sense that it really follows a particular viewpoint of 903 00:55:14,511 --> 00:55:20,704 CRDTs, which I think is best represented by a blog post called, like, Data Laced 904 00:55:20,704 --> 00:55:22,424 with History, I think it's called. 905 00:55:22,626 --> 00:55:26,886 And it's basically just this, the simple idea of like, look, you just keep all 906 00:55:26,886 --> 00:55:30,476 of the edit history on an object around and that's what the object actually is. 907 00:55:30,476 --> 00:55:33,296 And then the current state is just a view over that history. 908 00:55:33,479 --> 00:55:36,879 And if everyone has all of the edit operations and the full histories 909 00:55:36,879 --> 00:55:40,119 of different people collaborating on a document, then you eventually 910 00:55:40,119 --> 00:55:41,479 get the same state and that's it. 911 00:55:41,742 --> 00:55:45,192 and like, just as simply in like five or 10 more minutes, I could 912 00:55:45,192 --> 00:55:48,792 describe to you how then Jazz adds cryptography to do the like. 913 00:55:49,122 --> 00:55:52,392 Read and write access control, but it's actually not that hard. 914 00:55:52,392 --> 00:55:57,182 And I think having really neat diagrams and kind of like a medium level 915 00:55:57,182 --> 00:56:01,612 explanation that people can read through in like 15 minutes and feel like, okay, 916 00:56:01,932 --> 00:56:04,072 these are the parts that are inside Jazz. 917 00:56:04,112 --> 00:56:09,366 And now I know like, if I wanted to glue stuff myself together, what I could glue 918 00:56:09,416 --> 00:56:11,936 together or which systems I would need. 919 00:56:11,936 --> 00:56:13,236 But I won't bother. 920 00:56:13,256 --> 00:56:14,626 It's enough for me to know. 921 00:56:14,944 --> 00:56:18,514 What's going on and that in itself already makes me feel kind of clever. 922 00:56:18,834 --> 00:56:22,214 And then just going like extra deep on all the details for the people 923 00:56:22,214 --> 00:56:23,494 who want to be really, really clever. 924 00:56:23,514 --> 00:56:25,064 I think that's going to be important. 925 00:56:25,404 --> 00:56:29,244 and probably each framework has their own equivalent of doing that. 926 00:56:29,624 --> 00:56:32,214 And like, it's not necessary to use it at all, right? 927 00:56:32,214 --> 00:56:35,854 That the APIs that you use, if you build Jazz are much higher level 928 00:56:35,854 --> 00:56:39,584 and are much more in terms of like abstractions that an app needs, but. 929 00:56:39,912 --> 00:56:44,182 Yeah, I, I think DevTools, the biggest challenge is that you are 930 00:56:44,182 --> 00:56:48,202 selling to developers, so you need to speak to developers egos, right? 931 00:56:48,489 --> 00:56:48,819 Right. 932 00:56:48,859 --> 00:56:54,649 And I love the way how you framed that in the Ikea effect and how you, yeah, 933 00:56:54,649 --> 00:56:58,862 it's, it's like this delicate balance you want to, like, I think we can all get on 934 00:56:58,862 --> 00:57:05,346 the same page that we want to collapse as much complexity as much as possible, 935 00:57:05,649 --> 00:57:09,739 But developers still like love the abstractions, love putting things together 936 00:57:10,209 --> 00:57:15,192 and, like figuring out the delicate balance of having something that's already 937 00:57:15,202 --> 00:57:19,552 somewhat put together and does what they need, but then you can decompose it and 938 00:57:19,552 --> 00:57:22,142 like compose it again in a different way. 939 00:57:22,142 --> 00:57:26,102 I think that's sort of like where the, where you need to apply like 940 00:57:26,102 --> 00:57:27,792 a little bit of like special sauce. 941 00:57:28,191 --> 00:57:32,631 and I think this is what you've already, laid out very, very nicely with Jazz, with 942 00:57:32,651 --> 00:57:37,971 like the APIs look amazing and the apps that are being built on top of it already. 943 00:57:38,227 --> 00:57:40,747 I think a really, really good proof for that. 944 00:57:41,037 --> 00:57:43,297 So slightly switching gears. 945 00:57:43,587 --> 00:57:48,901 Jazz is no longer just a technology, but behind Garden Computing, you've 946 00:57:48,921 --> 00:57:53,171 also, I think you've thought about that for a longer time and recently took the 947 00:57:53,171 --> 00:57:59,571 step to actually, Turn Garden Computing into an actual company and build out a 948 00:57:59,571 --> 00:58:01,901 commercial offering around Jazz as well. 949 00:58:02,331 --> 00:58:07,204 and I think you've recently, took on a initial round of pre seed 950 00:58:07,204 --> 00:58:09,074 funding, so congrats on that. 951 00:58:09,336 --> 00:58:13,186 but I'd love to hear a little bit more about what that means for Jazz as a 952 00:58:13,186 --> 00:58:18,576 technology, what your thoughts are on possibly offering a commercial product, 953 00:58:18,846 --> 00:58:23,276 sustaining the company otherwise around that, and how you're thinking of like 954 00:58:23,606 --> 00:58:28,033 Going beyond just working on this yourself, but possibly, scaling out the 955 00:58:28,033 --> 00:58:30,143 company or like hiring other people. 956 00:58:30,393 --> 00:58:33,003 So very curious to hear your thinking on that. 957 00:58:33,275 --> 00:58:33,625 Yeah. 958 00:58:33,625 --> 00:58:37,975 So I think again, going into it from like, how did it come to be? 959 00:58:37,975 --> 00:58:42,725 I think it's important to say that, like, I'm not someone who's like trying to do a 960 00:58:42,725 --> 00:58:45,095 startup for the sake of doing a startup. 961 00:58:45,095 --> 00:58:48,605 I was very much like thinking of it as like an open source framework and 962 00:58:48,625 --> 00:58:50,805 was building that as like a good tool. 963 00:58:51,113 --> 00:58:54,933 And in a similar way where like the fact that it is a framework kind of became 964 00:58:54,933 --> 00:58:57,223 apparent to me while I was building it. 965 00:58:57,450 --> 00:59:00,500 it became apparent to me that like, okay, even if you have all of these 966 00:59:00,500 --> 00:59:05,120 abstractions for distributed state and local-first, and that's all 967 00:59:05,120 --> 00:59:06,890 like, it feels very peer to peer. 968 00:59:06,890 --> 00:59:10,090 And I think in our legacy, we have a lot of peer to peer thinking. 969 00:59:10,386 --> 00:59:13,036 and that obviously influenced me, but I had this moment where I'm 970 00:59:13,036 --> 00:59:16,716 like, okay, if I really think about what I as a user want from the app, 971 00:59:16,726 --> 00:59:18,956 for example, very pragmatically. 972 00:59:19,506 --> 00:59:23,156 I want sync between devices that works even if the devices 973 00:59:23,206 --> 00:59:24,926 aren't online at the same time. 974 00:59:25,306 --> 00:59:28,756 So I need some kind of centralized syncing infrastructure that 975 00:59:28,846 --> 00:59:30,716 also does persistence for me. 976 00:59:31,056 --> 00:59:31,416 Right. 977 00:59:31,883 --> 00:59:36,246 so that very obviously became a part of Jazz and then I'm like, it's actually 978 00:59:36,246 --> 00:59:39,926 kind of hard to run that at scale and to run it well and have it have low 979 00:59:39,926 --> 00:59:45,776 latency and so on, and that's something that a company could do as a service. 980 00:59:46,136 --> 00:59:50,041 Right?, and it being open source, of course, you can also self host your 981 00:59:50,051 --> 00:59:53,661 own version of that either on a single node for like a small app, or you can 982 00:59:53,661 --> 00:59:55,701 be brave and try and scale it yourself. 983 00:59:56,151 --> 00:59:59,031 That's totally doable, but there's just obvious value in 984 00:59:59,031 --> 01:00:00,501 someone doing that for you. 985 01:00:01,081 --> 01:00:03,676 And the interesting extra component there is that. 986 01:00:04,236 --> 01:00:07,716 Because of the encryption, you actually don't have to trust that 987 01:00:07,716 --> 01:00:09,176 infrastructure with your data. 988 01:00:09,186 --> 01:00:12,476 You can just use it for syncing and persistence, but know that it will 989 01:00:12,476 --> 01:00:16,646 never see your data, your user's data, whatever you care about. 990 01:00:16,930 --> 01:00:21,656 so there's this kind of like really useful service or product. 991 01:00:21,923 --> 01:00:26,353 presented itself to me and I'm like, okay, this doesn't just feel like it wants to 992 01:00:26,353 --> 01:00:31,443 be a framework for people to really have that local-first development experience 993 01:00:31,443 --> 01:00:34,623 where you only want to have to worry about the parts that actually make your 994 01:00:34,633 --> 01:00:40,333 app, your app, and now you don't have to solve state syncing and permissions 995 01:00:40,333 --> 01:00:44,013 yourself anymore, but you would still have to build syncing infrastructure. 996 01:00:44,033 --> 01:00:45,053 That seems kind of weird. 997 01:00:45,073 --> 01:00:45,363 Like. 998 01:00:45,573 --> 01:00:48,313 I think what you want as an application developer is to use a 999 01:00:48,313 --> 01:00:51,333 service for that, because then you're actually only left with your app. 1000 01:00:51,593 --> 01:00:53,043 That's what I would want anyways. 1001 01:00:53,313 --> 01:00:57,893 So like, okay, this is starting to feel like a company and I think I'm in a 1002 01:00:57,893 --> 01:00:59,813 good position to build that company. 1003 01:01:00,433 --> 01:01:04,793 and then it became a question of like, okay, I, for a long time, 1004 01:01:04,793 --> 01:01:06,473 my plan was to bootstrap it. 1005 01:01:06,803 --> 01:01:13,118 and I did try to go into YC and raise VC funding, but I think we, as if Field are 1006 01:01:13,118 --> 01:01:18,208 so early that it's, it's really hard for outsiders to see the potential in that. 1007 01:01:19,008 --> 01:01:23,318 and what it took for me to have any success with that was to get 1008 01:01:23,328 --> 01:01:27,058 Jazz to a state where it became obviously useful to developers. 1009 01:01:27,528 --> 01:01:30,978 And they could start telling these like first success stories of like, 1010 01:01:31,448 --> 01:01:35,628 wow, we actually built the SAP way quicker than we would have otherwise. 1011 01:01:36,218 --> 01:01:40,308 And then to do that in like a public setting, like the local-first conference 1012 01:01:40,308 --> 01:01:44,288 in Berlin, where then investors can see that and be like, Oh, this 1013 01:01:44,308 --> 01:01:46,098 actually really speaks to developers. 1014 01:01:46,098 --> 01:01:49,958 And that's like, That's like an early signal they understand, right? 1015 01:01:49,958 --> 01:01:53,108 So that's, that's what allowed me to raise that round. 1016 01:01:53,108 --> 01:01:57,318 And now I'm in the, in the very fortunate position to have investors 1017 01:01:57,318 --> 01:02:01,068 who understand how early we are and how much work it's going to take to 1018 01:02:01,068 --> 01:02:02,718 really bring this into the mainstream. 1019 01:02:03,065 --> 01:02:07,615 And starting to have the person power through like hiring my first couple 1020 01:02:07,615 --> 01:02:11,365 of employees who I'm really happy with and who, who really get it as well. 1021 01:02:11,365 --> 01:02:13,435 And they're building their own apps with it as well. 1022 01:02:13,791 --> 01:02:18,171 where I'm like, okay, we can actually speed run, the features that we 1023 01:02:18,171 --> 01:02:21,881 need to reach parity with what traditional stacks can offer you, 1024 01:02:22,071 --> 01:02:23,541 in the way that I think we need. 1025 01:02:23,621 --> 01:02:26,991 That's, that's kind of the switch that happened there for me. 1026 01:02:27,566 --> 01:02:31,693 And before I had all of these ideas in my head of what I kind of knew 1027 01:02:31,693 --> 01:02:35,486 Jazz needed to do, and believe me, I thought about everything. 1028 01:02:35,486 --> 01:02:38,156 It's all somewhere on the roadmap, but I didn't really know what 1029 01:02:38,156 --> 01:02:39,376 was most important, right? 1030 01:02:39,966 --> 01:02:43,276 But the nice thing about having early adopters is that just becomes super 1031 01:02:43,276 --> 01:02:47,046 obvious because they'll be like, They'll be blocked because Jazz doesn't have 1032 01:02:47,066 --> 01:02:49,606 like this and we just built that next. 1033 01:02:49,606 --> 01:02:52,726 And that's kind of the journey that, that I've been on actually, since before 1034 01:02:52,726 --> 01:02:54,336 the investment for about a year now. 1035 01:02:54,926 --> 01:03:00,126 and now I have the luxury of being able to like tackle a couple of these at a time. 1036 01:03:00,356 --> 01:03:01,886 that's kind of where I'm at with it. 1037 01:03:02,316 --> 01:03:04,151 And the goal is to really. 1038 01:03:04,358 --> 01:03:08,878 To build a service that makes sense both for individual developers, for 1039 01:03:08,878 --> 01:03:12,118 whom it will be the first point of contact with local-first or distributed 1040 01:03:12,308 --> 01:03:17,311 state, for small companies to build, successful apps super quickly and 1041 01:03:17,311 --> 01:03:22,531 kind of like being able to reach a much wider economy of small companies 1042 01:03:22,581 --> 01:03:26,551 and individual developers who can now meaningfully build real things that 1043 01:03:26,551 --> 01:03:29,201 are useful to people and maybe because. 1044 01:03:29,431 --> 01:03:30,921 It's so much easier to build things. 1045 01:03:30,921 --> 01:03:33,761 You can now build products that target smaller niches. 1046 01:03:34,211 --> 01:03:35,561 And that's really interesting. 1047 01:03:35,791 --> 01:03:40,181 And also to just give a tool for like bigger companies or even enterprises to 1048 01:03:40,181 --> 01:03:45,221 be like, Oh, it's actually really hard for us to build high fidelity apps. 1049 01:03:46,091 --> 01:03:47,041 Figma like notion. 1050 01:03:47,101 --> 01:03:50,591 We want these because we have lots of people and lots of teams that interact, 1051 01:03:50,971 --> 01:03:54,441 but we don't have the know how to build something like a sync engine. 1052 01:03:54,451 --> 01:03:57,191 That's just way too complex for a company to do itself. 1053 01:03:57,221 --> 01:04:01,911 But if that's now an off the shelf abstraction and there's kind of like an 1054 01:04:01,921 --> 01:04:06,651 obvious either third party service or something that you can deploy on premises. 1055 01:04:06,866 --> 01:04:09,796 That's really powerful and interesting and I think enables a lot more 1056 01:04:09,826 --> 01:04:12,776 bigger companies to build their own software as well and have it 1057 01:04:12,796 --> 01:04:17,116 immediately be as good as the best, like, SaaS apps we have right now. 1058 01:04:17,596 --> 01:04:20,836 That's, that's kind of the potential I see in it and what I'm trying to 1059 01:04:20,836 --> 01:04:22,136 address in the, in the medium term. 1060 01:04:22,495 --> 01:04:23,405 I like that a lot. 1061 01:04:23,505 --> 01:04:29,105 And that also makes me think about, like the, this concept called small giants. 1062 01:04:29,135 --> 01:04:33,785 I think it was also, I think I first learned about it on the Metamuse podcast 1063 01:04:33,815 --> 01:04:35,935 by, that Adam Wiggins did in the past. 1064 01:04:36,155 --> 01:04:37,855 Hopefully it comes back at some point. 1065 01:04:38,068 --> 01:04:42,688 but this is where they did one episode about the idea of small giants. 1066 01:04:42,688 --> 01:04:48,168 And this is basically that a very small team, possibly could be like just, 1067 01:04:48,395 --> 01:04:53,565 an individual small team, et cetera and they can build products, reach a 1068 01:04:53,565 --> 01:04:59,465 really wide audience without having to build up all of that load and to. 1069 01:04:59,675 --> 01:05:04,351 Like, for example, WhatsApp was when I think it was acquired before 1070 01:05:04,621 --> 01:05:09,521 billions of dollars by, by Facebook, was still a very, very small company. 1071 01:05:09,521 --> 01:05:13,648 I think, they've been, I don't get the numbers exactly right, right 1072 01:05:13,648 --> 01:05:18,248 now, but like, I think within 10 to 50 people where they've already. 1073 01:05:18,453 --> 01:05:20,863 Reach like billions of users. 1074 01:05:21,036 --> 01:05:24,596 I think similar for Telegram, well, Telegram is a little bit in the 1075 01:05:24,596 --> 01:05:28,776 news right now, but, I have a lot of admiration at least for like how they 1076 01:05:28,776 --> 01:05:33,456 built the product in terms of the craft, et cetera and it's also similar there. 1077 01:05:33,736 --> 01:05:38,366 There's a very small team that can still reach a very wide audience. 1078 01:05:38,366 --> 01:05:44,606 And I think this is what local-first can really empower, where you can empower 1079 01:05:44,636 --> 01:05:50,816 a lot more small giants to serve a much more richer, diverse set of use 1080 01:05:50,816 --> 01:05:56,946 cases, where a bunch of current existing products could be replaced by local-first 1081 01:05:56,967 --> 01:06:02,016 products, but not just by one local-first product, but a hundred different kinds 1082 01:06:02,016 --> 01:06:04,616 of people who have specific use cases. 1083 01:06:04,926 --> 01:06:06,736 There are a hundred different small giant. 1084 01:06:07,001 --> 01:06:10,631 Build products specifically for their use case, for their niches. 1085 01:06:10,961 --> 01:06:16,755 so instead of like having, 10 very, very large monopolies, like, dominating 1086 01:06:16,785 --> 01:06:20,998 a particular segment, let's rather have like a thousand individual 1087 01:06:20,998 --> 01:06:27,738 builders reach smaller slivers and have products that fit particular use cases. 1088 01:06:28,028 --> 01:06:30,478 And I think this is where you can empower them. 1089 01:06:30,498 --> 01:06:31,478 They can focus. 1090 01:06:31,673 --> 01:06:36,173 Similar to Invoice Radar, focus on specific use case and 1091 01:06:36,173 --> 01:06:38,173 then, use a syncing service. 1092 01:06:38,183 --> 01:06:39,613 So that makes a lot of sense. 1093 01:06:39,923 --> 01:06:42,103 And I'm looking forward to that future. 1094 01:06:42,323 --> 01:06:47,840 before we close out, I'm interested in hearing your perspective on the more, 1095 01:06:48,220 --> 01:06:52,590 the bigger web ecosystem as a whole, as you've been building apps within the 1096 01:06:52,590 --> 01:06:57,883 web space for a long time, now you're contributing a, better development suite 1097 01:06:57,893 --> 01:07:02,373 to that, but I'm curious whether you have any sort of strong opinions on the 1098 01:07:02,863 --> 01:07:04,623 web development world that we live in. 1099 01:07:04,910 --> 01:07:09,560 I think my strong opinion on it is that I kind of don't have one, or like there's 1100 01:07:09,560 --> 01:07:15,060 a lot of critical voices that complain about all kinds of things about the web 1101 01:07:15,100 --> 01:07:17,560 and its state that are completely fair. 1102 01:07:17,580 --> 01:07:18,040 Right. 1103 01:07:18,560 --> 01:07:23,360 But I think what kind of gets lost within that is that the web is actually fine. 1104 01:07:23,370 --> 01:07:24,610 And it's not only fine. 1105 01:07:24,620 --> 01:07:26,310 It's, it's like, it's amazing. 1106 01:07:26,340 --> 01:07:29,550 It's like, I think first and foremost, it's this like 1107 01:07:29,580 --> 01:07:32,680 crazy distribution mechanism. 1108 01:07:32,710 --> 01:07:37,435 and, I think, you talked about this in a previous episode, that like, you can just 1109 01:07:37,445 --> 01:07:39,575 send your grandma a link and she'll know. 1110 01:07:40,070 --> 01:07:40,980 What to do with it. 1111 01:07:40,980 --> 01:07:41,290 Right. 1112 01:07:41,730 --> 01:07:44,510 and it will, she'll see what, what you see. 1113 01:07:44,510 --> 01:07:45,850 and that's crazy. 1114 01:07:45,870 --> 01:07:48,300 That's something that is just so at the core of the web. 1115 01:07:48,300 --> 01:07:48,933 And, sure. 1116 01:07:48,933 --> 01:07:52,503 It's kind of weird that like JavaScript got tacked onto like a 1117 01:07:52,523 --> 01:07:58,783 document representation and so on, but it is a really powerful VM. 1118 01:07:59,193 --> 01:08:05,193 That is super dynamic, would make anyone who likes Lisp or Smalltalk 1119 01:08:05,253 --> 01:08:07,023 proud if you really think about it. 1120 01:08:07,023 --> 01:08:09,313 But it's like, everyone has it. 1121 01:08:09,663 --> 01:08:15,433 The best minds of our generation optimized it to the death. 1122 01:08:15,483 --> 01:08:20,713 And you just get all like, CSS is crazy, but you can do a lot with it. 1123 01:08:21,020 --> 01:08:22,700 and you just get all of that. 1124 01:08:22,700 --> 01:08:23,010 And. 1125 01:08:23,660 --> 01:08:26,840 It's kind of not doing what it was originally meant to do. 1126 01:08:26,840 --> 01:08:32,620 It's kind of like an app distribution system now, but because it's so 1127 01:08:32,620 --> 01:08:36,750 flexible and so malleable, I think my big point is actually that we can 1128 01:08:36,750 --> 01:08:38,210 just make it do whatever we want. 1129 01:08:38,383 --> 01:08:42,947 for example, when I think about Jazz and what Jazz does, the way Jazz works is, is 1130 01:08:43,087 --> 01:08:48,017 it's actually like a high level framework and then like a protocol underneath it. 1131 01:08:48,517 --> 01:08:53,385 And it's a very minimal, simple core that does like, the implementation of 1132 01:08:53,385 --> 01:08:57,985 the CRDTs and like how to sync them, how to persist them and the cryptography, 1133 01:08:57,995 --> 01:08:59,345 like how do the permissions work? 1134 01:08:59,355 --> 01:09:00,635 That's all like defined. 1135 01:09:00,645 --> 01:09:02,925 And then like you get higher level features on top. 1136 01:09:03,375 --> 01:09:06,595 And if you look at that, it's kind of like a new networking protocol. 1137 01:09:06,595 --> 01:09:11,155 And in many ways, it's like what I think the web should have been like just taking 1138 01:09:11,155 --> 01:09:12,900 seriously that we're building like this. 1139 01:09:13,140 --> 01:09:18,010 Network of distributed nodes that have partial state and being able to represent 1140 01:09:18,010 --> 01:09:20,340 user identity and permissions across that. 1141 01:09:20,543 --> 01:09:24,833 so like one kind of pessimistic take would be that like, Oh yeah, that's 1142 01:09:24,873 --> 01:09:28,853 obviously better, but we'll never get there because we're stuck with the web and 1143 01:09:28,853 --> 01:09:31,123 this like centralized client server model. 1144 01:09:31,203 --> 01:09:34,333 And that's like at odds, but like, it's not at odds at all. 1145 01:09:34,513 --> 01:09:37,473 We've got web sockets and we can just build. 1146 01:09:37,883 --> 01:09:42,123 The protocol on top of client side JavaScript and server side JavaScript 1147 01:09:42,183 --> 01:09:45,723 and hopefully soon other server side programming languages and 1148 01:09:45,723 --> 01:09:49,907 native apps and, communicate over the web socket or maybe soon web 1149 01:09:49,917 --> 01:09:52,607 transport or like HTTP 3 or whatever. 1150 01:09:52,607 --> 01:09:57,480 It's like you can actually do a lot of crazy stuff with the web and, we 1151 01:09:57,480 --> 01:10:02,718 can just like, yeah, just embrace the fact that In the history of computing, 1152 01:10:02,718 --> 01:10:04,358 we almost never replace things. 1153 01:10:04,358 --> 01:10:08,785 We just add archeological layers of like, we're building the thing that we 1154 01:10:08,785 --> 01:10:11,955 really want, but we have to build it in terms of what's already there and like 1155 01:10:11,965 --> 01:10:15,285 widely available and it's actually fine. 1156 01:10:15,315 --> 01:10:16,105 And that's, that's. 1157 01:10:16,815 --> 01:10:20,625 How like you kind of have the psychological aspect that we talked 1158 01:10:20,625 --> 01:10:24,075 about earlier, where like this crazy new thing has to look and sound 1159 01:10:24,075 --> 01:10:28,875 familiar, but also very pragmatically it has to be implemented based on 1160 01:10:29,165 --> 01:10:32,595 things that already exist where you don't have to really replace anything. 1161 01:10:33,370 --> 01:10:35,420 That's, that's kind of my take on the web, right? 1162 01:10:35,777 --> 01:10:36,097 Right. 1163 01:10:36,137 --> 01:10:36,777 I love that. 1164 01:10:36,837 --> 01:10:42,427 I did this year, I did a three week journey through some of the 1165 01:10:42,437 --> 01:10:45,317 national parks of the United States. 1166 01:10:45,327 --> 01:10:49,870 And we also, spent a couple of days at the Grand Canyon where we just See like 1167 01:10:50,205 --> 01:10:56,325 those like massive, massive, like layers of layers on top of layers that just reach 1168 01:10:56,335 --> 01:10:58,592 back, I think like millions of years. 1169 01:10:58,592 --> 01:11:03,442 I don't recall the exact facts anymore, but I think it's a very good observation 1170 01:11:03,752 --> 01:11:08,745 that, we rarely replace something categorically, but we just build on top. 1171 01:11:08,755 --> 01:11:13,475 Maybe we phase one thing out, but that takes like, decades often. 1172 01:11:13,895 --> 01:11:21,065 And, it's kind of a miracle how capable the web has gotten, given how weird 1173 01:11:21,145 --> 01:11:23,055 it is and how many words it has. 1174 01:11:23,505 --> 01:11:26,095 So I think I like that observation a lot. 1175 01:11:26,175 --> 01:11:30,905 And, yeah, given the, given often the web for me is like a love hate relationship, 1176 01:11:31,295 --> 01:11:33,235 I think the love still dominates there. 1177 01:11:33,655 --> 01:11:37,343 So, uh, Anselm, this has been a really great conversation. 1178 01:11:37,383 --> 01:11:38,923 I've learned a lot about Jazz. 1179 01:11:38,963 --> 01:11:43,873 I've been very inspired by the way, how you think about the entire space overall. 1180 01:11:44,263 --> 01:11:48,753 So maybe you want to have a, you have a last chance to plug anything, 1181 01:11:48,916 --> 01:11:53,170 give any shout outs, but other than that, I'll thank you for your time. 1182 01:11:53,773 --> 01:11:54,813 Yeah, I mean, thank you. 1183 01:11:54,813 --> 01:11:56,693 I really enjoyed this conversation as well. 1184 01:11:56,733 --> 01:12:01,023 Definitely shout outs to Ink and Switch because they are my biggest inspiration 1185 01:12:01,103 --> 01:12:04,253 and what kind of, what gave me a lot of the ideas in the first place. 1186 01:12:04,833 --> 01:12:09,613 In terms of plugging stuff, again, coming back to psychology, like I can tell 1187 01:12:09,613 --> 01:12:14,488 developers about all the advantages of Jazz and so on, but like, So far, what 1188 01:12:14,498 --> 01:12:18,908 has worked best in getting them to adopt it for even like a small experiment or 1189 01:12:18,908 --> 01:12:22,558 even getting them to start doing the guide and the official docs is just 1190 01:12:22,578 --> 01:12:27,468 being like, look, I've got these like shiny holographic stickers for Jazz. 1191 01:12:27,468 --> 01:12:30,125 And like, I've got boring stickers as well. 1192 01:12:30,125 --> 01:12:32,365 And like, everyone can get them at meetups. 1193 01:12:32,365 --> 01:12:36,125 I put them on tables and stuff, but like, if you want one of the special shiny ones, 1194 01:12:36,125 --> 01:12:37,695 you have to build something with Jazz. 1195 01:12:37,755 --> 01:12:41,295 And like, if you just do the official guide that counts as doing something with 1196 01:12:41,295 --> 01:12:45,440 Jazz Just show me like wherever you are in the world, either we meet in person 1197 01:12:45,440 --> 01:12:49,260 somewhere or I'll mail it to you, but you, you get the special shiny sticker. 1198 01:12:49,270 --> 01:12:49,520 Okay. 1199 01:12:49,520 --> 01:12:50,210 That's the deal. 1200 01:12:51,330 --> 01:12:51,890 All right. 1201 01:12:51,980 --> 01:12:53,900 There's, there's a first on the podcast. 1202 01:12:53,950 --> 01:12:56,250 There weren't any holographic stickers yet. 1203 01:12:56,630 --> 01:13:00,380 So I might just as well give this a try afterwards. 1204 01:13:00,380 --> 01:13:03,640 And the next time we see each other, I might steal one of those. 1205 01:13:04,040 --> 01:13:05,630 But thank you so much. 1206 01:13:06,890 --> 01:13:07,700 Thank you so much. 1207 01:13:07,730 --> 01:13:08,900 I really enjoy myself. 1208 01:13:08,960 --> 01:13:10,090 Thanks for having me, Johannes. 1209 01:13:10,792 --> 01:13:13,072 Thank you for listening to the Local First FM podcast. 1210 01:13:13,482 --> 01:13:16,542 If you've enjoyed this episode and haven't done so already, please 1211 01:13:16,552 --> 01:13:17,992 subscribe and leave a review. 1212 01:13:18,362 --> 01:13:20,872 Please also share this episode with your friends and colleagues. 1213 01:13:21,262 --> 01:13:24,492 Spreading the word about this podcast is a great way to support 1214 01:13:24,492 --> 01:13:25,942 it and help me keep it going. 1215 01:13:26,542 --> 01:13:30,722 A special thanks again to Rosicorp and PowerSync for supporting this podcast. 1216 01:13:31,132 --> 01:13:32,182 I'll see you next time