localfirst.fm
All episodes
October 23, 2024

#16 – Anselm Eickhoff: Jazz

#16 – Anselm Eickhoff: Jazz
Sponsored byPowerSyncRocicorp
Show notes

Transcript

0:00:00 Intro
0:00:00 Imagine if you could mock up an app just based on React use state
0:00:05 or like equivalent things, and you build your UI around that.
0:00:08 but then magically your app actually works and like all of the status persistent
0:00:14 and you can share it with other users and, you have permissions on there and
0:00:18 you still only wrote front end code.
0:00:21 That's kind of the Jazz story
0:00:24 Welcome to the localfirst.fm podcast.
0:00:26 I'm your host, Johannes Schickling, and I'm a web developer, a
0:00:29 startup founder, and love the craft of software engineering.
0:00:32 For the past few years, I've been on a journey to build a modern, high quality
0:00:36 music app using web technologies.
0:00:38 And in doing so, I've been falling down the rabbit hole of local-first software.
0:00:43 This podcast is your invitation to join me on that journey.
0:00:47 In this episode, I'm speaking to Anselm Eickhoff.
0:00:49 Creator of Jazz and founder of Garden Computing.
0:00:53 In this conversation, we dive deep into Jazz to learn how it works and which use
0:00:58 cases it's a good fit for by exploring various apps already built on top of Jazz.
0:01:03 Before getting started, also a big thank you to Rosicorp and PowerSync
0:01:07 for supporting this podcast.
0:01:09 And now my interview with Anselm.
0:01:13 Hey Anselm, so nice to have you on the show.
0:01:15 How are you doing?
0:01:16 Hey Johannes, doing good.
0:01:17 How are you?
0:01:18 I'm doing great.
0:01:19 I was looking forward to today talking to you about Jazz.
0:01:23 I know a little bit about Jazz and as I'm generally trying to scan the
0:01:28 local-first ecosystem, but super excited to have you on the show and dive deeper,
0:01:33 learn a lot more about Jazz, but before we dig in, do you mind giving a quick
0:01:37 background and introduce yourself?
0:01:40 Oh yeah, of course.
0:01:41 I guess I've always been like interested in the web.
0:01:43 I think it technically, I started with like Flash for people who remember
0:01:48 that, but I very quickly got into making websites, just static ones
0:01:51 first, kind of doing web design for local shops in my hometown and
0:01:56 that became more and more serious.
0:01:57 I learned about Rails and like building whole web apps and what that even meant.
0:02:01 And I guess most of my career kind of spent being like a full
0:02:06 stack consultant, building apps for lots of different industries.
0:02:11 And typically I would be just like one man army doing like product design and
0:02:16 building the backend and the front end and just building kind of the first version
0:02:21 of that app that was ready for production.
0:02:24 And then doing the next one and the next one and so on.
0:02:27 And that was lots of fun.
0:02:28 And I learned a lot, but over time, especially when you build lots of apps
0:02:32 that are very different in nature, like who they serve, how they work.
0:02:37 You still notice that there's so many things that you have to do again and
0:02:41 again and again, and they don't even really have to do with each app.
0:02:44 And you're, you're.
0:02:45 You're using these tools that are supposed to be like high level
0:02:48 frameworks for building web apps, but you still need to do so much
0:02:51 yourself, redundantly each time.
0:02:52 Like people who build web apps will know stuff like, why do you have
0:02:57 to do user auth and permissions every time or like file uploads,
0:03:00 this is like super simple stuff.
0:03:03 and that always like nagged me.
0:03:05 and particularly like, it seemed like.
0:03:07 What you're really trying to do is just share state between
0:03:11 different users of the app.
0:03:12 And why, why do I have to build a whole stack and why is it so weird to do it?
0:03:17 But I never really had a good, good solution for it.
0:03:20 Right.
0:03:20 And that's kind of what, what brought me where I am today with Jazz.
0:03:24 And yeah, happy to tell you more about that.
0:03:27 Yeah, that journey definitely resonates and, sort of in a similar
0:03:31 counter reaction, in, in 2016, just led me back then to starting GraphQL,
0:03:36 which later turned into Prisma.
0:03:38 So I feel like that's a common, somewhat common story to like, from like the
0:03:43 previous trauma of like doing something over and over again in a way that
0:03:48 doesn't quite satisfy you, where you feel like, Oh man, we can do so much better.
0:03:53 so that story definitely resonates.
0:03:55 I'd be actually intrigued to hear a little bit more about some of the
0:03:58 specific aspects, but I'm sure you'll, you'll cover that in comparison to Jazz.
0:04:04 So, and Jazz is actually not quite the only thing you're doing
0:04:08 since you're doing this under the umbrella of Garden Computing.
0:04:12 So before diving into Jazz, do you mind giving a quick idea of like,
0:04:17 what is that umbrella and what.
0:04:20 Garden Computing
0:04:20 Yeah, sure.
0:04:21 So it actually started with an app called Garden, which was kind of like
0:04:26 my take on what should a Notion clone look like, what kind of other ideas do I
0:04:32 have, I was really fascinated by Notion when it came out and by Figma just like
0:04:37 setting this new standard of like, it not just being like a higher fidelity app.
0:04:43 But one where like multiplayer and like rich multi user interaction is like baked
0:04:49 kind of into the very fabric of the app and then the app itself is just like kind
0:04:54 of like features on top of that, right?
0:04:56 And I was like, this is cool, but I think It still doesn't feel fundamental enough.
0:05:01 Like the multiplayer ness of it and like also the aspects that we
0:05:05 now call local-first that I didn't really have a name for back then.
0:05:09 and I was like, okay, I want to do something like that, but I want to do
0:05:11 that part even better and then build like even cooler features on top.
0:05:15 And that, that was Garden.
0:05:17 And yeah, I did a bunch of experiments there and that's.
0:05:20 That's pretty much what, what led me to what, what Jazz became as for
0:05:25 like Garden Computing as an idea for a company or bigger umbrella.
0:05:31 I can get more into that later, but basically the idea is that.
0:05:34 I'm really fascinated by abstractions, by like powerful abstractions, by
0:05:38 abstractions that are tall and like span many levels of, of understanding.
0:05:43 And very often they come from like academia and research, right?
0:05:47 That's where people find like really new, better ways of
0:05:50 describing and building things.
0:05:52 But they're obviously very abstract, very hard to approach for most people.
0:05:57 and from my experience as a.
0:06:00 Full stack web dev, I'm, I'm like very in touch with what people are using day
0:06:06 to day and what, what the mainstream developer is like and cares about.
0:06:10 and I just love the idea of taking these new ideas and kind of like
0:06:15 finding ways to package them in a way that makes sense for the mainstream.
0:06:20 And that actually makes.
0:06:21 What we use in the mainstream, a little more enlightened.
0:06:24 So I think in the broadest sense, that's, that's what Garden Computing
0:06:28 for me is about and like Jazz and local-first is kind of like
0:06:33 the first step in that journey.
0:06:35 And I love the vibe overall of like Garden Computing.
0:06:39 A garden is something that I think that's just, I'd say if you'd ask anyone,
0:06:45 they'd probably associate it with like a nice, comfortable, homey feeling.
0:06:50 If you think about a garden, does this maybe even, you have a very personal
0:06:54 relationship of like, maybe you put together the garden, maybe you care
0:06:58 after it, or maybe not, maybe it looks a little bit wilder, but there's something
0:07:02 very unique and something very personal to our garden compared to like a very
0:07:08 Industrial, like hyperscale, like that doesn't sound like a garden to me.
0:07:14 and also like the use case that you've mentioned sort of like a
0:07:18 Notion esque thing, I think Notion is also like there, there's this
0:07:22 term of like a digital garden.
0:07:24 so all of that is like a vibe that very much resonates.
0:07:27 And it also resonates that you're saying you didn't actually start right away.
0:07:32 with designing Jazz as a local-first tool, but that you're rather stumbling
0:07:38 into it through working on an actual app.
0:07:41 Since there's also the analogy for me, the parallel that while working
0:07:45 on Overtone, I also realized, okay, this is a data foundation that I'm
0:07:49 working on that doesn't just work well for Overtone, but also for other apps.
0:07:53 So I think this is one of the most authentic ways to Really
0:07:57 think of a new data abstraction.
0:08:00 So now with that background, can you give me an introduction to Jazz?
0:08:05 Jazz
0:08:05 Yeah.
0:08:05 So like, to audiences like this, I introduced Jazz just as
0:08:09 like, a framework for building web apps in a local-first way.
0:08:14 That's probably the simplest way to put it.
0:08:16 That of course requires you to already know what local-first means.
0:08:21 So I think maybe a nice way to explain it is to go a bit more in depth on like how
0:08:27 through trying to build Garden, I kind of discovered what I thought it needed to be.
0:08:32 Because in many ways I didn't like sit down and be like,
0:08:35 Oh, I want to build this app.
0:08:36 I want to build it in local-first ways.
0:08:39 and then I'll make a local-first framework to build the app because.
0:08:42 When I started building the app, I didn't even know about local-first.
0:08:45 I didn't know about that as a term.
0:08:47 I saw apps like, like Notion and Figma.
0:08:51 and I guess systems like Git, where it feels different from a traditional
0:08:58 SaaS app with a centralized server and it has these really nice
0:09:02 properties and it actually feels like it's suddenly very easy to do
0:09:05 multiplayer, to have offline support.
0:09:08 And to like be really serious and honest about the fact that what you're building
0:09:13 with your app is a distributed system and not like some thin client around
0:09:17 like the app basically just running on another computer, on one other computer.
0:09:22 so I was like, okay, I want my app to be like that.
0:09:25 And I started building the app and I had all of these crazy ideas in
0:09:28 terms of like features for Garden.
0:09:30 Part of it was even like, it should be like a visual programming
0:09:33 language in there and like.
0:09:35 I actually didn't get too far on that because very soon I was like, okay,
0:09:38 what's, what's the infrastructure I need.
0:09:41 That's like fabric that, that just has in the data layer, multiplayer
0:09:46 and users and permissions and sharing and working on your device, but still
0:09:50 being able to sync to the cloud.
0:09:52 So I started building that just as part of Garden, right.
0:09:55 and very soon just through like.
0:09:58 abstracting and encapsulating the code.
0:10:00 I had this like separate layer that did all of that.
0:10:03 and a big part of what made that layer possible was learning about,
0:10:08 Ink and Switch and their blog posts and publications, seeing auto merge
0:10:12 as the first CRDT that I encountered and being like, Oh, even just the idea
0:10:17 of having like, synced state between two text editors is super interesting.
0:10:22 Like, let's.
0:10:24 Build the layer around that.
0:10:26 And then once I had that layer, I looked at it and I was like, damn, this is like
0:10:30 really interesting, not just for Garden.
0:10:33 but I kind of want to build every app ever like this now.
0:10:37 thinking of all the apps I had built in the past, all the other apps I
0:10:40 still wanted to build or the apps I didn't even know I could build yet.
0:10:44 And I'm like, if I feel like that, probably other people will too.
0:10:47 They just don't know yet that it's even possible to have this abstraction.
0:10:51 So therefore I should probably try.
0:10:53 And make this a framework.
0:10:54 And that's, that's the origin story of Jazz, right?
0:10:58 That makes a lot of sense.
0:10:59 And, it also, there's, this interesting dance of, being irritated
0:11:06 and confused by some problems, this desire of like, could we do better?
0:11:10 You kind of hope we could do better.
0:11:12 You don't quite know yet how to do better.
0:11:15 You see some proof for other apps.
0:11:19 Being able to build something in an experience that you wouldn't quite
0:11:22 know how you would replicate that.
0:11:25 You go on like looking around for ideas and luckily they're, very smart
0:11:31 people, like the folks associated with Ink and Switch who are also like
0:11:35 write about that and inspire others.
0:11:38 And that leads you to maybe also like be very.
0:11:42 compelled by those ideas, but maybe you have some slightly different takes.
0:11:46 And so this is where, where it evolves.
0:11:49 that makes a lot of sense.
0:11:50 And I see a lot of like parallels there for like past endeavors and
0:11:55 current endeavors that I'm on.
0:11:57 So this is what led to Jazz.
0:12:00 And I think there's like a lot of similarities for how other data
0:12:05 technologies, like in the local-first space came to be and, throughout the
0:12:09 further conversation, I'm sure we'll learn about what makes the specific flavor
0:12:15 of Jazz, how that compares to others, but maybe we can best approach that
0:12:21 by talking a little bit more about the applications that, Jazz wants to empower.
0:12:27 So can you, give me an idea of like, what is like a typical app that, Is
0:12:33 just naturally now built with Jazz.
0:12:35 And what are some apps that you've like intended Jazz for?
0:12:39 Jazz early adopters
0:12:39 Right.
0:12:40 I guess one thing I will add in terms of like, what's special about Jazz
0:12:44 and we'll go more in depth about that later, but like while building it
0:12:48 as part of Garden, I realized that the responsibility of this layer.
0:12:52 It's actually not just a data layer, it also needs to, or like, I wanted it to
0:12:58 also handle user identity and permissions because that's other, other, because
0:13:04 like, that's what allows you to go from having a local-first app that kind of
0:13:08 syncs between your devices as a single player user to just extending that
0:13:13 model very naturally to multiplayer.
0:13:16 and it just always felt like these two things, user identity and permissions
0:13:20 also need to be part of that abstraction.
0:13:21 And that's kind of, that's the most special thing about Jazz, I would say.
0:13:26 and that has enabled it to support quite a, like, wide range of different
0:13:31 apps that, that even surprised me.
0:13:33 and you kind of, you have apps that are like obviously local-first and are like
0:13:37 a very good fit, and they are some of the ones that, that already felt the
0:13:42 strongest benefit from adopting Jazz.
0:13:44 for example, like I, I think Garden is a good example.
0:13:47 We're actually almost at a point now where we can start building Garden
0:13:50 again, based on top of what Jazz is now.
0:13:53 That's, it's like Notion.
0:13:55 It's very clearly a local-first app.
0:13:57 One of my favorite early adopters, they're an app called Invoice Radar,
0:14:02 which is basically, it lets freelancers collect invoices automatically from
0:14:08 like cloud providers and other things they use that send them invoices,
0:14:13 manage them, and then submit them to tax authorities, for example.
0:14:17 And that's an area where like, yeah, having it local-first is really important.
0:14:23 And the people who were building the app already, I think also without
0:14:27 knowing the term at the beginning, knew that they wanted to build it that way.
0:14:31 And then they found Jazz and they're like, Oh, there's like a framework that
0:14:34 Just lets you build apps like that.
0:14:36 And once they started building it with that, they were just able to get to
0:14:40 like an MVP of their apps so quickly.
0:14:43 So that's kind of like, almost like an obvious success story.
0:14:46 Right.
0:14:46 But then there's other ones that are really surprising that start to push
0:14:50 the boundaries of what a local-first app is, or does the framework even
0:14:55 only need to be for local-first app?
0:14:57 one I'm building myself with, my girlfriend that I presented in Berlin
0:15:02 at our local-first conference is an app called Succulent, which is
0:15:06 basically a Hootsuite alternative, like a social media scheduling tool.
0:15:12 And it's like 90 percent a local-first app where you can like plan drafts
0:15:17 for Instagram posts, for example, on your device and you prepare
0:15:20 them with the pictures and the descriptions and the hashtags.
0:15:24 But then it has this component that's like not local-first at all, because like in
0:15:27 order to meaningfully schedule posts to be posted, you need to have a server worker.
0:15:33 and, typically this would mean that, well, you just need to build it as
0:15:36 a centralized, like, SaaS app where all this logic runs on a server.
0:15:40 But, What I realized with Jazz is like, you can actually take this
0:15:43 local-first concept further and the server worker can just become yet another
0:15:47 local-first client to the shared state.
0:15:50 And then you get this really funky arrangement of like, you have
0:15:54 this local-first app for authoring all this stuff and then just this
0:15:57 little worker that whenever you're online and your stuff gets synced.
0:16:00 It will know about what you're trying to do and then you can go
0:16:04 offline again and it will post your posts for you by like interacting
0:16:07 with the meta API, for example.
0:16:09 So that was already a bit of a stretch of what Jazz can do.
0:16:13 But honestly, the most ambitious and most out there things in terms of
0:16:17 what you can build with Jazz have been from like other early adopters.
0:16:21 So one of the crazier ones is This guy Nikita is building an app called
0:16:27 LearnAnything, and you can check it out.
0:16:29 It's already public.
0:16:30 You can go to, I think, Learn Anything.
0:16:33 xyz.
0:16:34 It's, it's like a cross between Quora and Reddit.
0:16:37 It's like a learning community where you can be like, I want to learn how to play
0:16:42 the guitar, or I want to learn TypeScript.
0:16:44 and for each topic that you might want to learn, you find this like
0:16:48 community curated list of like really good links to other resources,
0:16:52 like videos, blog posts, whatever.
0:16:55 and that's just the social network, right?
0:16:57 And the crazy thing is, he's already getting a bunch of impressions just from
0:17:02 SEO, so you have like lots of, First time visitors and all of the state that
0:17:07 needs to be loaded for each of these potentially huge topics, which have like
0:17:11 thousands of links or something like that.
0:17:13 And he decided to completely pivot his stack to just use Jazz for everything.
0:17:19 And I think one of his motivations is that, For each individual user, he
0:17:24 actually wants the experience to be local-first in the sense that you can
0:17:27 also have your own kind of like notion, like notes about the topic and your
0:17:31 learning progress in there and manage your own collection of links and so on.
0:17:37 But then through sharing it with others, again, it needs to have the
0:17:40 scaling properties of a social network.
0:17:42 And that really, really stretched Jazz, but he was able to kind of like, Self
0:17:47 publicly launched already and a version of his app completely built on Jazz.
0:17:51 And so far it seems to be working.
0:17:53 So, so that's kind of an interesting one.
0:17:56 another one, which is very early and we'll have to see if it works, but
0:17:59 it's basically like a local-first spreadsheet app, which is just like
0:18:03 really intense in terms of like how much data there's in it and how like
0:18:07 finally granular the interaction will be.
0:18:10 And then the last use case I'll mention also really surprised me
0:18:14 because it actually uses Jazz to do much less than a whole app where,
0:18:19 it's at this huge enterprise and they have like CI pipelines for like
0:18:24 their build processes or whatever.
0:18:26 but it's really hard to look at them and see what's going on, which builds
0:18:29 are passing, which ones are failing.
0:18:31 And it's all in this like super old system with a really clunky API.
0:18:35 And this person just wanted to build like a dashboard for that.
0:18:37 Right.
0:18:38 And that's really annoying.
0:18:39 They decided to use Jazz basically just as a layer that makes that
0:18:43 clunky old API real time and really easy to build UIs around.
0:18:50 So they again have like a server worker that makes requests to that API and
0:18:55 then maintains like a version of the state of all of the stuff in Jazz.
0:19:01 And then they built a really thin client with Jazz and the two, like
0:19:07 the status shared between the two.
0:19:08 And then they were able to super quickly build a really nice dashboard,
0:19:12 where you see a real time updates of what's actually going on.
0:19:15 and I, I think you can start to see like how these are actually all.
0:19:18 Really weirdly different.
0:19:20 And yet everyone was able to use Jazz as this like small tool that
0:19:26 does a lot very successfully.
0:19:28 and I have to say as a caveat as well, these are very brave people.
0:19:31 Like Jazz is early in many ways.
0:19:33 Some of its APIs are clunky as well.
0:19:35 The documentation really isn't there yet, but all the important like magic
0:19:40 is already there and I think that's what allowed all these people to move quite
0:19:44 quickly and confidently and the parts that still have friction are problematic.
0:19:49 They were kind of able to work around it.
0:19:50 I think that's kind of a good representation of where we're at as well.
0:19:54 That sounds incredible.
0:19:55 That's such a wide range of different apps and different use cases.
0:19:59 you mentioning InvoiceRadar, for example, I'm actually one of the
0:20:03 early users of InvoiceRadar, I've been using it for multiple months
0:20:07 now, and I can confidently say that, I would have probably not started to
0:20:12 adopt it if it wasn't local-first.
0:20:14 Not because of like, that I say like, okay, now I have this bar Everything has
0:20:19 to be local-first, like I still adopt other tools, but in this particular thing
0:20:23 is, one of the, main ways, how this tool works is by getting access, like actually
0:20:31 log in access to the various places that you where I pay for an invoice.
0:20:36 So this tool needs access to my Notion, to my Slack, to my Hetzner columns,
0:20:42 to all those like very critical places I wouldn't give anyone access who I
0:20:46 wouldn't really, really, really trust.
0:20:49 And that level of trust, I can't just give that to like an arbitrary
0:20:53 SaaS startup, that wasn't around like a couple of years ago.
0:20:57 Even if it was around, I would still have trust issues.
0:21:01 And that trust issues thing.
0:21:03 They very elegantly address by, saying like, Hey, the entire
0:21:08 thing runs all on your computer.
0:21:10 Like.
0:21:11 All of like the login credentials, et ceterall of that, like not running in the
0:21:15 cloud, like all remains on your computer.
0:21:18 and so this is how that afforded me the trust and I've been using it.
0:21:24 And, it works amazing.
0:21:26 And I think it's built by folks, who are like very confident in
0:21:32 sort of like front end development.
0:21:34 And I think Jazz empowers them to like leverage their strength.
0:21:38 And a lot of like the data moving around, that is taken care of.
0:21:42 So that is like a use case that I can already as a user speak to.
0:21:46 And then I want to also hear more about the Learn Anything use case,
0:21:50 since that's, to me, seems like it's actually stretching, quite on
0:21:55 the boundaries of where local-first is even considered a good fit.
0:21:59 I think, if you hear about local-first, like where App use case works well,
0:22:04 that's more around like data that's all like centered around a small entity,
0:22:09 whether it's one user, whether it's one document, one workspace, one small team,
0:22:14 but the more I think it's actually used sort of like as the counterexample,
0:22:18 the more something is seen as a social network, the more local-first also
0:22:24 actually becomes increasingly tricky to model around, to scale, et cetera.
0:22:28 So I'd love to hear a little bit more how, Learn Anything and how Jazz helps with
0:22:37 Edge use cases
0:22:37 Yeah, I'll, I'll go into that.
0:22:39 There's two more things I want to say about Invoice Radar, because, I think
0:22:43 that ties in quite nicely with what makes Jazz special, particularly for
0:22:47 like your particular sensibilities as a user where like, yeah, you need to
0:22:51 put your login credentials in there.
0:22:53 Why can you trust it?
0:22:54 And part of the answer is, well, it, because it only runs on your device,
0:22:58 but then even then you might want to, and I think they're working on like a
0:23:03 mobile companion app to Invoice Radar.
0:23:05 So you can also just like scan and paper invoices with your phone.
0:23:10 So obviously it's like 2024, you want sync between your devices, right?
0:23:16 Maybe you're no longer just like a solo freelancer, but you have like a small
0:23:20 company and you want other people in your team to submit invoices as well.
0:23:23 And how do you do that while maintaining the trust that you have with the
0:23:28 credentials and your invoices?
0:23:30 And Jazz's answer there is exactly what I mentioned earlier that.
0:23:33 User identity and permission is also part of the abstraction that
0:23:37 it offers you, and it solves those in a local-first way as well.
0:23:42 And we, again, we'll go into that later, but basically it uses public key
0:23:46 cryptography to do permissions and auth.
0:23:49 And what that means is that, Their app can actually use my infrastructure
0:23:54 to sync data between your devices or between members of your team.
0:23:58 But my infrastructure only ever sees encrypted data and that way you can
0:24:03 still trust that app despite having these modern properties of like
0:24:07 sync, cloud persistence, and so on.
0:24:10 for them, what it meant was that they envisioned their app initially as
0:24:15 only like a single player experience.
0:24:16 And it already makes a lot of sense there.
0:24:18 And they were like, okay.
0:24:19 Later on, maybe in a year or a bit more, we'll add like team and
0:24:23 organization features, and that'll probably be like a huge topic, right?
0:24:27 But because they build it with Jazz, the idea of users and permissions is just
0:24:32 like baked in and literally all they had to do to make it multiplayer was to
0:24:38 build the UI for a little invite button.
0:24:40 and their, their app was like multiplayer team ready from day one
0:24:45 while preserving all of these like privacy and data protection guarantees.
0:24:50 Anyways, just like a short addition to that.
0:24:53 I'm also really excited about Learn Anything for exactly the reasons that
0:24:57 you mentioned, because I didn't think that quote unquote local-first could
0:25:01 stretch that far and that's maybe where I'll go into a bit of a spicy take
0:25:05 and ask the question of like, Just how useful as a term is local-first
0:25:11 really, because it's really good at describing local-first apps, right?
0:25:16 But the abstractions that we build to make local-first possible, or at least in my
0:25:21 case, what I'm trying to build with Jazz, it actually feels like something slightly
0:25:25 more general than that, where like one thing I like to call it is like it's
0:25:30 distributed state, and you already see that a little bit with apps like Succulent
0:25:34 that has a server component, I don't know.
0:25:36 We have a couple examples with server components that already stretches it,
0:25:39 but it's still just Jazz and it's, it's distributed state, not just across end
0:25:44 user clients, but across server workers.
0:25:46 But again, the trust relationships are now explicit.
0:25:49 It's not just frontend and backend, but all these individual things.
0:25:52 The way it works in Jazz, by the way, is that the server workers
0:25:55 also have an account like a user and you need to invite them.
0:25:58 Two specific pieces of data for them to be able to see it and do stuff with it.
0:26:03 so I really liked this idea of distributed state.
0:26:06 And then, I also had this like coming to Jesus moment with Jazz where
0:26:11 I'm like, what I'm building here is actually a distributed database.
0:26:17 And I have to be honest with myself that it's a database.
0:26:19 And, I don't know how many people that are listening or watching
0:26:23 this are familiar with Redis.
0:26:25 But one way I always like looking at Redis is that it's like, it's, it's
0:26:29 kind of like an exploded database.
0:26:31 It doesn't give you the nice high level relational API that, that usual
0:26:35 databases have, but it gives you all the little tools that you need
0:26:38 to kind of build your own database.
0:26:40 So you can have like your raw key value store and then different ways
0:26:44 to build indices or like spatial lookup structures and stuff like that.
0:26:48 And that's really powerful.
0:26:49 And Jazz is kind of similar in a way.
0:26:51 It's like, I would say it's like an exploded distributed database
0:26:55 with permissions built in.
0:26:56 And once you start thinking about it like that.
0:27:00 There's suddenly way more use cases where it can be a useful tool, including
0:27:04 stuff like the, being this like real time layer in a purely backend setting,
0:27:09 or you could imagine using Jazz as like a, distributing configuration for apps.
0:27:15 So like anything that's a distributed system where you might have network
0:27:19 failures, nodes going offline, but you want to have meaningfully shared state
0:27:25 with like History and auditability.
0:27:27 You can actually use Jazz for that.
0:27:28 And I think even though I'm trying really hard to envision all these different use
0:27:33 cases and build for it, there's probably a ton more that people will come up
0:27:37 with, just by having something that's so flexible without like a narrow minded
0:27:41 use case of like, this is for local-first apps or like, this is a database.
0:27:45 Does that make sense?
0:27:47 Totally.
0:27:47 yeah.
0:27:48 And I would love to dig in a little bit more into the social network aspect.
0:27:53 I think the exploded database analogy is, is very useful and maybe that also
0:27:59 addresses a little bit how, Jazz is able to stretch beyond that, but can you
0:28:04 make the, a little bit more specific?
0:28:06 when you.
0:28:07 Remember other people, me included, saying that, for local-first, anything
0:28:11 that's looks and smells like a social network or like a global, like basically
0:28:17 if you have a lot of strongly connected, a vast set of strongly connected data
0:28:21 points, this is where local-first has a harder time to sync all of that.
0:28:27 And it seems like that would mean you need to sync literally everything.
0:28:31 So you need to.
0:28:33 Chop off certain points in the everything is connected graph to not
0:28:38 let the user wait forever until all the graph data is there, but to only
0:28:43 show the user what they actually need.
0:28:46 So how do you work around
0:28:47 that?
0:28:48 Or do you need to sync everything?
0:28:50 That's kind of like, other than the like user identity and
0:28:53 permissions making Jazz special.
0:28:55 That's I think the only other big point that makes Jazz special
0:28:58 is that from the beginning I kind of knew that it had to be.
0:29:02 Super granular when it comes to which chunks of data are you loading?
0:29:07 And it's, it's much more, it's basically on demand by default.
0:29:11 And the underlying data model is like an infinitely big graph of
0:29:16 data that can reference each other.
0:29:17 And you like.
0:29:18 Load sub graphs of that as needed.
0:29:21 And for like a very local-first or classical app, that means, well, you
0:29:27 kind of end up everything that one user needs or like a small team of people
0:29:31 needs and there it's very obvious how that works well, I think the surprising
0:29:36 insight is maybe that even in something crazy like a social network, even where
0:29:40 you have single nodes, like people who might have a lot of followers, it's
0:29:44 actually still quite like manageable graphs that are quite independent.
0:29:50 And what doesn't work is in my design sense, you can't ask the app developer
0:29:57 to have to come up with the boundary of like, what is a chunk of data that
0:30:00 makes sense to be loaded at once.
0:30:02 I think maybe you could get away with it for an app like Notion where like
0:30:06 the document is an obvious boundary to do that for, but even there it's
0:30:10 kind of annoying and gets in the way, particularly with sharing and so on.
0:30:14 So I think you just have to adapt that like a hundred percent granular mindset.
0:30:18 And then it turns out, Even the very highly connected graphs, they're actually
0:30:22 manageable in size, and it is feasible to load them to display, for example, one
0:30:27 learning topic and Learn Anything, even if it has thousands of links and thousands
0:30:32 of people interacting with that topic.
0:30:34 That's actually, in the grand scheme of things, not that much data to sync.
0:30:39 And on my infrastructure, which is kind of inherently distributed.
0:30:42 It's like, obviously geographically distributed because that's like a nice
0:30:47 metric to kind of chunk data up against.
0:30:50 you can also start doing something very similar to sharding where you basically
0:30:55 co locate data that is often accessed together, again, on a very granular level.
0:31:00 And then suddenly even this like really hot data with lots of
0:31:04 people interacting easily fits.
0:31:06 into a single node, even a single core, and it's feasible to
0:31:09 sync it to clients who all want roughly the same stuff anyways.
0:31:13 and if you're being honest, like databases face exactly that problem and that the
0:31:18 way it's solved usually is just by scaling it,, like making your database node huge
0:31:24 so it can fit all of the data for all of the users and then distributing and
0:31:28 scaling databases is a hugely complicated topic and I think in many ways local-first
0:31:33 is actually an answer to that in the sense that in the most extreme case
0:31:37 you're like well we only need to worry about the data of one user and we'll
0:31:41 have a system that manages the data for one user, which is their machine.
0:31:47 but then the abstractions you build to make that possible, if you include
0:31:52 the granularity, actually also let you do everything in between where,
0:31:57 yeah, you, you can have a couple of nodes collaborating to sync and
0:32:04 persist and serve like, Subgraphs of that, like infinitely big data.
0:32:09 Does that make sense?
0:32:10 That makes total sense.
0:32:11 And before we're going even deeper here, and I think we're stretching a
0:32:14 little bit into some like implementation details here, et cetera, which are super
0:32:18 interesting, but maybe we take a little step back as a application developer
0:32:23 who wants to build something with Jazz.
0:32:25 Maybe you can walk us through, what does that look like?
0:32:28 So just to give a little bit of like a spectrum of options, we had Matt
0:32:33 Wonlaw on the show where we, for example, talked about CR SQLite,
0:32:37 where the idea was that, you replicate a SQLite database across devices.
0:32:43 So this is where you have already Something that developers are
0:32:46 very familiar with, which is a relational database that you can
0:32:50 just embed in the app and then query.
0:32:52 So that's one approach.
0:32:53 we heard from the folks working on AutoMerge, which is a CRDT based
0:32:59 system, so where you rather think less about a database that's replicated.
0:33:04 But more about individual documents, that are being replicated and state
0:33:10 based as you change the CRDT document, those state changes are being propagated.
0:33:16 and there could be also other options, for LiveStore, for example, I'm following more
0:33:20 of like a, what I consider a combination of both approaches where you distribute
0:33:26 a event log and you recompute a, in this case, a SQLite database from it.
0:33:32 So there's various flavors, various trade offs, which path have you've been
0:33:37 going down with Jazz and maybe also why.
0:33:41 How Jazz works
0:33:41 Yeah.
0:33:42 So the meta comment there is that like, after you think about it for a really
0:33:46 long time, a lot of these approaches end up actually being the same, but it
0:33:50 really matters, I think, in terms of contrasting different frameworks and
0:33:54 solutions and introducing people to the idea in the first place, from which
0:33:59 angle you approach it and like the.
0:34:01 It's like a replicated local database that's relational is a very obvious one.
0:34:06 And there's a lot of people doing that really well now.
0:34:08 the document one is an obvious one.
0:34:11 I think you'll be able to predict what, what my issue with
0:34:14 it is that it like makes you.
0:34:16 Put the boundaries, but I'm basically doing that.
0:34:18 I'm doing what AutoMerge is doing.
0:34:20 It looks like state, and I'll say that a bit more precisely in a second,
0:34:24 but again, it's a bit more granular.
0:34:26 And the way I describe it typically, like the audience that I have in mind
0:34:31 is actually not full stack developers or backend developers who are very
0:34:35 familiar with relational databases, but in my case, frontend developers who
0:34:41 are familiar with Local UI state on the one hand and kind of making requests
0:34:45 to APIs as like the only external system they ever need to worry about.
0:34:49 So the story I tell this Imagine Frontend developer is that imagine
0:34:55 if you could kind of mock up an app just based on local, like React use
0:35:01 state or like equivalent things, and you build your UI around that.
0:35:06 but then magically your app actually works and like all of the status persistent
0:35:12 and you can share it with other users and, you have permissions on there and
0:35:18 you still only wrote front end code.
0:35:21 That's kind of the Jazz story and that's what the API looks and feels like.
0:35:25 So if, if you build an app with Jazz, typically the first thing you do is.
0:35:30 You actually do something kind of database y, which is that you define a schema
0:35:33 just to describe kind of what is the shape of data, which kinds of objects
0:35:38 are the main abstractions in my app.
0:35:40 interestingly, you don't have to model users at all because that's just baked in.
0:35:44 So it's very nicely like, what are just the concepts that are
0:35:48 specific to your domain that you're, addressing with your app.
0:35:52 And once you have the schema, you can just start having state of objects in
0:35:58 that schema and build UI around it.
0:36:00 And you can create objects of different types out of your schema locally, and you
0:36:04 can create like, groups, which is kind of like the permission structure in Jazz
0:36:08 and put objects in groups and then like give users access rights to groups, all
0:36:15 like you can do these things literally in an on click handler of a button.
0:36:19 And it feels kind of illegal because of how simple it is, but that's it.
0:36:23 That's how you build apps with Jazz and you can get very far with just that.
0:36:28 As apps get more complicated, you can kind of.
0:36:31 abstract things all kind of similarly to how there are solutions for not
0:36:35 letting UI state get too complex.
0:36:38 and the other thing you might need to start, if you want to talk to external
0:36:41 systems like third party APIs, you can build the server workers that I
0:36:46 talked about a couple of times now.
0:36:48 But the nice thing is you can build.
0:36:49 If you also write them in TypeScript, for example, you just
0:36:51 share the same data schema that you're using for the front end.
0:36:55 And it really just feels like one, one small addition to your
0:36:59 otherwise purely front end code.
0:37:01 That's, that's kind of the Jazz experience, right?
0:37:04 That makes a lot of sense.
0:37:05 And I've just in parallel.
0:37:07 going through the Jazz landing page here, where you have, this
0:37:11 really cool chat app and 174 lines of code embedded here as well.
0:37:16 We can just see exactly that, like a little schema definition
0:37:20 of this case for this chat app.
0:37:21 There's just like a message.
0:37:23 Class, a message concept and a chat concept.
0:37:27 and that's it.
0:37:27 You can use it right away in your React code, in your other code, and fire away.
0:37:33 and you've also have here the user concept where you see like, okay,
0:37:38 something is owned by me and then the chat, for example, is owned by a group.
0:37:44 what if I want to go a little bit more specific here and enforce
0:37:48 certain Permission rules, that are more specific to my app.
0:37:54 what is the story in progression there?
0:37:57 So the way that that works is that it doesn't get more complicated than groups
0:38:03 and objects belonging to the group.
0:38:04 So like whenever you create an object in Jazz and like, I should say
0:38:08 the name for them, we call them co values, like collaborative values.
0:38:12 You have like co maps that are kind of like.
0:38:14 JavaScript objects, co lists that are like collaborative arrays, basically.
0:38:19 and just like you can represent a lot of different kinds of data with JSON, you
0:38:24 can represent a lot of different kinds of collaborative data with co values, right?
0:38:29 And each co value has to belong to a group.
0:38:32 The group is like the scope for permissions, and it simply has user
0:38:36 accounts in it with a certain role.
0:38:39 The three roles that exist are Reader, Writer, or Admin.
0:38:43 They do exactly what it says on the tin.
0:38:45 and they then influence what people can do on co values.
0:38:49 We can talk in detail later how that works under the hood, because
0:38:52 I think that's interesting as well.
0:38:53 But for now, that's all you need to know.
0:38:55 And that maps quite naturally on onto a lot of stuff that you want to do in apps.
0:39:00 But then the question is what about more complicated situations?
0:39:03 And the answer there again is the granularity.
0:39:06 Because if you wanted to every, each co value, like imagine like a kind
0:39:12 of tree of co values representing the state of a more complicated document
0:39:17 or even like a folder of documents.
0:39:19 The way that looks like in Jazz is that they're actually each
0:39:22 individual CRDTs that just have plain data as values in their fields.
0:39:28 Or they can have references to other co values.
0:39:30 And that's how you build this, like, potentially infinitely big graph,
0:39:33 and you, like, load whatever you need to, like, display right now,
0:39:36 or what you want to have offline.
0:39:37 But the nice thing is that the groups that these co values belong
0:39:41 to, and the permission structures, therefore, are kind of orthogonal
0:39:44 to the, like, data references.
0:39:46 So you can reference a co value, That belongs to a different group that
0:39:50 has different members or where the same members have different roles.
0:39:53 And that way you can build permission structures that are just as granular.
0:39:57 And you can even have like something like a notion document where like a small block
0:40:03 might only be editable by some people.
0:40:05 does that make sense?
0:40:07 totally.
0:40:07 you, you've been mentioning the reference concept that is giving you the kind of
0:40:13 like a relation for a key kind of concept between different kinds of documents,
0:40:19 and I think this is also describing the.
0:40:22 the boundary between one thing that needs to be synced and then another
0:40:27 thing that needs to be synced.
0:40:29 And if you model a thing like a network with that, how does,
0:40:34 Jazz, how does it know where to, uh, how much it needs to sync?
0:40:39 Where does it need to stop?
0:40:41 Is there, so one analogy, for example, in GraphQL . maybe not everyone is familiar
0:40:46 with that, but it's like a query language that is language agnostic and can be
0:40:51 implemented with any sort of backend.
0:40:53 And this is where you can also define a schema kind of similar to this here.
0:40:58 and aside from the schema, describes the potential graph of queries, or
0:41:04 set of queries in a specific query.
0:41:08 you need to very explicitly say, those are the things that I want to query.
0:41:12 So let's say we model a file system from this, where we have folders and files
0:41:18 and folders can have folders and folders can have folders in a GraphQL query.
0:41:23 You need to say, actually, I want to, you need to explicitly lay out.
0:41:27 I want to go like all the way to like level three.
0:41:30 So you need to say, I want to grab the folders and in that folders, I'm
0:41:34 going to grab again, the folders.
0:41:36 And I want to, there again, grab the folders, but you can't self
0:41:39 recursively, infinitely, traverse.
0:41:43 Is there a similar kind of explicit depth to how jazz should sync something.
0:41:50 Is that determined at runtime by a React component, for example, is
0:41:56 there some sort of middle ground?
0:41:58 How does that work?
0:41:59 So there are kind of, and it's a really good question because like, that's kind
0:42:03 of, you need a system that solves that.
0:42:06 If you don't have the explicit boundary of like, this is, we can
0:42:10 either sync all of that or nothing.
0:42:11 Right.
0:42:12 And the file system is a good example because it's.
0:42:14 It's kind of potentially infinitely deep, but you're probably only ever looking
0:42:17 at a subset, so how do you do that?
0:42:19 And the way, the quick and dirty way you do it in Jazz, which is actually
0:42:24 really fun to just, again, super quickly build your eyes that work, is that,
0:42:29 Jazz tries really hard to make covalues look like just plain JSON objects.
0:42:35 And if you have co values with references to each other, they look like JSON trees.
0:42:40 So what do you do then if like at some point you might
0:42:43 not have a co value loaded?
0:42:44 Well, then it just says that it's in a TypeScript sense that field is
0:42:48 either the reference thing or null.
0:42:51 And,, if you try and render a specific tree in a React component,
0:42:55 you can basically just use optional chaining to like render like this far.
0:43:00 And if it's not loaded, show like a little spinner or something.
0:43:03 But the funny thing then is that Jazz notices what you are trying to access.
0:43:09 And it's like, Oh, you're trying to render like three levels deep.
0:43:12 And you try to access this thing that we don't have yet in the background
0:43:16 triggers a sync of the needed co value.
0:43:19 And once that's available locally, it re renders your component.
0:43:22 And now that's not null anymore, but you actually have the JSON state
0:43:26 for that co value and you render it.
0:43:28 So very naturally by like building your UI and just deciding to render.
0:43:34 What do you want to render it will lazily load exactly what's needed.
0:43:38 And you can even manually do pagination like that by just having
0:43:41 a little stateful, like, oh, I want to render 10 items and then you only
0:43:45 drill down into the first 10 items.
0:43:47 And then like you hit a button or you reach the end of a scroll list or like.
0:43:51 Elements become visible on the screen and you just ask Jazz to
0:43:54 access more of them, even if they're right now, not, not available.
0:43:58 And in the background, it will load more.
0:44:00 That's the quick and dirty way.
0:44:01 Super nice for prototyping stuff.
0:44:03 It's a bit weird in terms of user experience, because you end up with a lot
0:44:08 of spinners and they like, they resolve really quickly because Jazz is fast,
0:44:12 but it still looks unfamiliar to people.
0:44:15 So if you want to give people a more polished experience of maybe one Loading
0:44:21 thing until a bunch of status available.
0:44:24 That makes sense as a unit.
0:44:26 There is a way of specifically specifying a loading depth and that's.
0:44:32 That kind of looks like GraphQL lite, but because you only need to specify
0:44:38 fields that are references, you don't need to say which plain data fields
0:44:41 you need because they're always loaded.
0:44:43 yeah, you, you, it's, it's actually very similar to Prisma.
0:44:46 You just say which references you want resolved and then the Jazz hooks.
0:44:51 Won't give you anything until all of that is loaded and then
0:44:54 they give it to you as a chunk.
0:44:56 That makes a lot of sense.
0:44:57 So you're basically just specifying sort of the graph of the references,
0:45:02 not the individual fields of a document, since you typically want a document
0:45:06 as a whole, that makes a lot of sense.
0:45:08 And that's also, as I'm thinking through how I would model something for Overtone.
0:45:13 when I have a music app and I want to listen to music, if I'm currently
0:45:17 ermbarking on a train journey or on a like traveling somewhere where
0:45:22 I don't have perfect connectivity.
0:45:25 I want to like that lazy loading just in time as I like click on a playlist.
0:45:32 if I don't have connectivity, then at that point, it kind of breaks a
0:45:36 bit of like that local-first promise.
0:45:38 but I also understand like, let's say, Spotify is thinking
0:45:42 about building it in that way.
0:45:44 Spotify can't just sync the entire catalog of like all of Spotify on a single device.
0:45:50 So there needs to be like some cutoff point.
0:45:53 And I think while prototyping doing the just in time lazy loading, that's great.
0:45:58 But then as an app developer, in this case, for example, me building
0:46:02 Overtone, as I better know, okay.
0:46:04 I want you to find some rules of like, that stuff should always
0:46:08 be there, like prepared for me going on a, on a train journey.
0:46:12 And that would probably in this case be.
0:46:14 For all of my playlists, make sure like all of like the tracks for the
0:46:18 individual playlists are at least the metadata is there and possibly
0:46:22 then have like also some rules for pre downloading some tracks.
0:46:25 If I have the rights to do so.
0:46:28 that makes a lot of sense.
0:46:29 And that seems like Jazz provides a really nice trade off of making, providing a
0:46:35 easy way right away to prototype and then, dial it in to match the user
0:46:41 experience that you want to provide.
0:46:43 And I guess I met the comment here with like, because you actually just
0:46:46 now asked a very precise, interesting question, which is like, well, what
0:46:50 if you ask it to load a chunk of data and not give it to you until all of
0:46:54 it is there, but then your connection drops, what should actually happen?
0:46:59 And like nothing being loaded, then it's actually a.
0:47:02 Like you said, an outcome that violates local-first a bit.
0:47:04 So there, then we need to be more refined and be like, well, maybe show
0:47:09 a spinner for everything for like two seconds and then give up and just show
0:47:13 me everything that was actually loaded.
0:47:15 and what we're getting to there is that I think like, look, I think
0:47:19 it's starting to become clear how local-first in general is this cool
0:47:25 new way of building app and how Jazz in particular things really deeply, how to
0:47:29 make that easy for you as a developer.
0:47:31 But most of the challenges with local-first and with multiplayer, by the
0:47:35 way, I think are UX challenges where we're like, well, what, what should happen?
0:47:40 And that's something that we figure out as we try to build
0:47:43 and dog food, our own apps.
0:47:45 As we see what, our first adopters build with it and what makes sense
0:47:51 to their particular developers and how you want to expose all of these
0:47:54 different, like, is it loading?
0:47:55 Is it locally available?
0:47:57 Is it locally available?
0:47:58 But it's like, not quite up to date with what we know the syncing server has, but
0:48:03 we didn't have a chance to get that yet.
0:48:05 And there's like so much complexity in there.
0:48:07 And in different situations, you need to expose like more or less of that.
0:48:11 So I think beyond just like.
0:48:14 Making the sync and making the data persistence and making the permissions
0:48:18 work, which like we're pretty good with now, there'll be a lot of like
0:48:22 API design and also like educating developers and just figuring out UX
0:48:27 together, like as a field, I think.
0:48:30 I definitely agree.
0:48:31 And like just the scenarios that we've now went through over the
0:48:34 last couple of minutes, I think already go surprisingly deep.
0:48:38 For example, like the partial, like if you want to load everything and then you say,
0:48:42 okay, I don't have everything, in some cases, it's fine to show a partial set.
0:48:47 In some other cases, it might be like really nerve wracking for a user where if
0:48:53 you don't signal like, Hey, we've just, we, we can't say this is everything.
0:48:57 We've just fetched so much since otherwise a user might assume, Oh my gosh.
0:49:00 Like this app has like lost some of my data.
0:49:03 and so this might, in some cases might be better to not show anything
0:49:07 and like explicitly let the user know, like, Hey, we're sorry.
0:49:12 when you come online again, we'll do our best to get everything in here.
0:49:15 sometimes you also like from the data you fetch, maybe you want to like,
0:49:19 let's say you, you shouldn't build a bank account this way, but let's say
0:49:22 you build a bank account and you've just fetched a bit of like your,
0:49:26 your like transactional history.
0:49:28 And it misses your latest, like, big check that you cashed in.
0:49:35 Basically you added money to your bank account and it's not in there.
0:49:38 And you think, Oh my gosh, like my bank account is like lost all of that money.
0:49:42 Obviously you won't build an app like that, but I think the analogy kind of
0:49:47 like translates where you derive data from other data and where it could be
0:49:52 like really bad, you missed something.
0:49:53 So this is really interesting to dig into the user experience aspects.
0:49:58 And that might also make for a really interesting future conversation,
0:50:02 but I want to, Dig a little bit more into, into another related topic,
0:50:07 which is the localfirst.fm podcast.
0:50:10 And what brings all of us together is that we think we can do better
0:50:14 how we build apps, at least in many app use cases, and Jazz shows for
0:50:18 how many app use cases that applies.
0:50:21 And so that means We, as a whole, as an ecosystem, we need to convince
0:50:26 the people who are not yet in that small but growing ecosystem.
0:50:30 We need to convince them that we have a very interesting way how to
0:50:34 build apps better, that are simpler to build, better for end users, etc.
0:50:39 And I think each technology has their own specific, benefits, how that's, is
0:50:45 a, is a good fit for, for certain app use cases and particular developer types.
0:50:50 Like you want to target more like the front end developers.
0:50:53 what is your approach to talking to developers?
0:50:57 How do you want to market Jazz to reach the right people and sort of the,
0:51:06 Marketing approach
0:51:06 Yeah, yeah, totally.
0:51:08 Because I think like, look, we're all facing the same challenge.
0:51:11 Like you said of like, we understand how this is better and how it can benefit
0:51:16 a lot of different kinds of apps.
0:51:19 but counterintuitively it's, I don't think it's really about selling the benefits.
0:51:23 I think the one big benefit that really does make sense.
0:51:26 And it's valuable to people as just saying, look, like you've got like
0:51:30 a 10 X better developer experience.
0:51:33 It's way faster to build apps.
0:51:34 It's way easier to reason about.
0:51:36 There's way fewer moving parts.
0:51:38 I think that's kind of universal across all the different solutions.
0:51:42 different solutions differ in terms of like what traditional
0:51:45 parts of the stack they replace.
0:51:47 I've put myself in the shoe of like replacing a lot of the pieces because I
0:51:53 do auth and permissions, and by the way, you can also store binary data in Jazz.
0:51:58 So suddenly you don't need blob storage anymore and binary data just becomes
0:52:02 part of the data you have locally and can be referenced just like JSON like data.
0:52:07 and it's so easy to just think about what are the obvious advantages of that
0:52:11 if you are totally bought into this and ready to build your app like that.
0:52:15 That's kind of the easy part, right, to make.
0:52:17 to explain that.
0:52:19 But the biggest question is like, why should you even bother?
0:52:23 And why should you give up this really proven, familiar way of building apps?
0:52:28 that means the biggest challenge is that it's so new and alien and different.
0:52:34 So I think the trick has to be How can we make it look familiar
0:52:39 and how can we make it look like something that already exists?
0:52:43 And that's, I think where exactly the different audiences or, ways of telling
0:52:47 that story for different products come in because, saying that you're replicating
0:52:53 a relational database into the client.
0:52:56 That's taking something very familiar to like backend developers and then
0:53:00 doing one little step away from that.
0:53:02 And then like, Oh, and then it has all these benefits.
0:53:04 Right.
0:53:05 I feel like, yeah, I've made it hard for myself because I'm basically
0:53:08 trying to replace the whole stack.
0:53:11 And that's a story that actually, again, it works really well for
0:53:15 frontend developers because the whole stack was never part of like
0:53:19 where they had agency to begin with.
0:53:22 So they're happy.
0:53:23 Full stack developers and especially backend developers aren't so
0:53:26 happy because you're like.
0:53:28 You don't have to do all of that stuff anymore.
0:53:30 It's replaced by this giant pile of magic.
0:53:33 I think like, I mean, what we identify as developers is being
0:53:38 clever and building stuff ourselves.
0:53:40 Right.
0:53:41 And I think a big part of what keeps really complicated stacks and ways
0:53:46 of doing things in life is honestly just the IKEA effect of like.
0:53:50 Well, but I built this myself and I like, I picked things that are individually
0:53:54 good at what they're doing, but I put them together in this really clever
0:53:58 way and local-first is like, it's just, it's so powerful that it takes away
0:54:04 so much of that doing stuff yourself.
0:54:07 That it's a real danger in terms of adoption and like not
0:54:09 bruising people's egos secretly.
0:54:12 so one attempt I had was like, well, can I kind of not make Jazz one giant
0:54:18 package, but more smaller ones so people can glue stuff together again.
0:54:22 And I think that's kind of counter to like what makes Jazz powerful, which is exactly
0:54:27 that it is a vertically integrated thing where even the different parts of like.
0:54:32 CRDT, stage sharing, and user identity and permissions.
0:54:36 They are actually very tightly knit together.
0:54:38 And that's why, yeah, that's what makes Jazz special, I think.
0:54:41 But, the other way out of that, I think, and this is something I just have to
0:54:45 do way more, is to have really good, like, under the hood documentation.
0:54:50 And the cool thing is, like, I think CRDTs kind of get thrown around
0:54:54 as this like mysterious new thing that magically solves everything,
0:54:58 but like, it's really complicated.
0:55:00 Don't worry about it.
0:55:00 Like, you can read about it in some research papers if you really wanted
0:55:04 to, but I think the way I've implemented CRDTs in Jazz is actually very.
0:55:09 Very straightforward, in the sense that it really follows a particular viewpoint of
0:55:14 CRDTs, which I think is best represented by a blog post called, like, Data Laced
0:55:20 with History, I think it's called.
0:55:22 And it's basically just this, the simple idea of like, look, you just keep all
0:55:26 of the edit history on an object around and that's what the object actually is.
0:55:30 And then the current state is just a view over that history.
0:55:33 And if everyone has all of the edit operations and the full histories
0:55:36 of different people collaborating on a document, then you eventually
0:55:40 get the same state and that's it.
0:55:41 and like, just as simply in like five or 10 more minutes, I could
0:55:45 describe to you how then Jazz adds cryptography to do the like.
0:55:49 Read and write access control, but it's actually not that hard.
0:55:52 And I think having really neat diagrams and kind of like a medium level
0:55:57 explanation that people can read through in like 15 minutes and feel like, okay,
0:56:01 these are the parts that are inside Jazz.
0:56:04 And now I know like, if I wanted to glue stuff myself together, what I could glue
0:56:09 together or which systems I would need.
0:56:11 But I won't bother.
0:56:13 It's enough for me to know.
0:56:14 What's going on and that in itself already makes me feel kind of clever.
0:56:18 And then just going like extra deep on all the details for the people
0:56:22 who want to be really, really clever.
0:56:23 I think that's going to be important.
0:56:25 and probably each framework has their own equivalent of doing that.
0:56:29 And like, it's not necessary to use it at all, right?
0:56:32 That the APIs that you use, if you build Jazz are much higher level
0:56:35 and are much more in terms of like abstractions that an app needs, but.
0:56:39 Yeah, I, I think DevTools, the biggest challenge is that you are
0:56:44 selling to developers, so you need to speak to developers egos, right?
0:56:48 Right.
0:56:48 And I love the way how you framed that in the Ikea effect and how you, yeah,
0:56:54 it's, it's like this delicate balance you want to, like, I think we can all get on
0:56:58 the same page that we want to collapse as much complexity as much as possible,
0:57:05 But developers still like love the abstractions, love putting things together
0:57:10 and, like figuring out the delicate balance of having something that's already
0:57:15 somewhat put together and does what they need, but then you can decompose it and
0:57:19 like compose it again in a different way.
0:57:22 I think that's sort of like where the, where you need to apply like
0:57:26 a little bit of like special sauce.
0:57:28 and I think this is what you've already, laid out very, very nicely with Jazz, with
0:57:32 like the APIs look amazing and the apps that are being built on top of it already.
0:57:38 I think a really, really good proof for that.
0:57:41 So slightly switching gears.
0:57:43 Jazz is no longer just a technology, but behind Garden Computing, you've
0:57:48 also, I think you've thought about that for a longer time and recently took the
0:57:53 step to actually, Turn Garden Computing into an actual company and build out a
0:57:59 commercial offering around Jazz as well.
0:58:02 and I think you've recently, took on a initial round of pre seed
0:58:07 funding, so congrats on that.
0:58:09 but I'd love to hear a little bit more about what that means for Jazz as a
0:58:13 technology, what your thoughts are on possibly offering a commercial product,
0:58:18 sustaining the company otherwise around that, and how you're thinking of like
0:58:23 Going beyond just working on this yourself, but possibly, scaling out the
0:58:28 company or like hiring other people.
0:58:33 Building the company
0:58:33 Yeah.
0:58:33 So I think again, going into it from like, how did it come to be?
0:58:37 I think it's important to say that, like, I'm not someone who's like trying to do a
0:58:42 startup for the sake of doing a startup.
0:58:45 I was very much like thinking of it as like an open source framework and
0:58:48 was building that as like a good tool.
0:58:51 And in a similar way where like the fact that it is a framework kind of became
0:58:54 apparent to me while I was building it.
0:58:57 it became apparent to me that like, okay, even if you have all of these
0:59:00 abstractions for distributed state and local-first, and that's all
0:59:05 like, it feels very peer to peer.
0:59:06 And I think in our legacy, we have a lot of peer to peer thinking.
0:59:10 and that obviously influenced me, but I had this moment where I'm
0:59:13 like, okay, if I really think about what I as a user want from the app,
0:59:16 for example, very pragmatically.
0:59:19 I want sync between devices that works even if the devices
0:59:23 aren't online at the same time.
0:59:25 So I need some kind of centralized syncing infrastructure that
0:59:28 also does persistence for me.
0:59:31 Right.
0:59:31 so that very obviously became a part of Jazz and then I'm like, it's actually
0:59:36 kind of hard to run that at scale and to run it well and have it have low
0:59:39 latency and so on, and that's something that a company could do as a service.
0:59:46 Right?, and it being open source, of course, you can also self host your
0:59:50 own version of that either on a single node for like a small app, or you can
0:59:53 be brave and try and scale it yourself.
0:59:56 That's totally doable, but there's just obvious value in
0:59:59 someone doing that for you.
1:00:01 And the interesting extra component there is that.
1:00:04 Because of the encryption, you actually don't have to trust that
1:00:07 infrastructure with your data.
1:00:09 You can just use it for syncing and persistence, but know that it will
1:00:12 never see your data, your user's data, whatever you care about.
1:00:16 so there's this kind of like really useful service or product.
1:00:21 presented itself to me and I'm like, okay, this doesn't just feel like it wants to
1:00:26 be a framework for people to really have that local-first development experience
1:00:31 where you only want to have to worry about the parts that actually make your
1:00:34 app, your app, and now you don't have to solve state syncing and permissions
1:00:40 yourself anymore, but you would still have to build syncing infrastructure.
1:00:44 That seems kind of weird.
1:00:45 Like.
1:00:45 I think what you want as an application developer is to use a
1:00:48 service for that, because then you're actually only left with your app.
1:00:51 That's what I would want anyways.
1:00:53 So like, okay, this is starting to feel like a company and I think I'm in a
1:00:57 good position to build that company.
1:01:00 and then it became a question of like, okay, I, for a long time,
1:01:04 my plan was to bootstrap it.
1:01:06 and I did try to go into YC and raise VC funding, but I think we, as if Field are
1:01:13 so early that it's, it's really hard for outsiders to see the potential in that.
1:01:19 and what it took for me to have any success with that was to get
1:01:23 Jazz to a state where it became obviously useful to developers.
1:01:27 And they could start telling these like first success stories of like,
1:01:31 wow, we actually built the SAP way quicker than we would have otherwise.
1:01:36 And then to do that in like a public setting, like the local-first conference
1:01:40 in Berlin, where then investors can see that and be like, Oh, this
1:01:44 actually really speaks to developers.
1:01:46 And that's like, That's like an early signal they understand, right?
1:01:49 So that's, that's what allowed me to raise that round.
1:01:53 And now I'm in the, in the very fortunate position to have investors
1:01:57 who understand how early we are and how much work it's going to take to
1:02:01 really bring this into the mainstream.
1:02:03 And starting to have the person power through like hiring my first couple
1:02:07 of employees who I'm really happy with and who, who really get it as well.
1:02:11 And they're building their own apps with it as well.
1:02:13 where I'm like, okay, we can actually speed run, the features that we
1:02:18 need to reach parity with what traditional stacks can offer you,
1:02:22 in the way that I think we need.
1:02:23 That's, that's kind of the switch that happened there for me.
1:02:27 And before I had all of these ideas in my head of what I kind of knew
1:02:31 Jazz needed to do, and believe me, I thought about everything.
1:02:35 It's all somewhere on the roadmap, but I didn't really know what
1:02:38 was most important, right?
1:02:39 But the nice thing about having early adopters is that just becomes super
1:02:43 obvious because they'll be like, They'll be blocked because Jazz doesn't have
1:02:47 like this and we just built that next.
1:02:49 And that's kind of the journey that, that I've been on actually, since before
1:02:52 the investment for about a year now.
1:02:54 and now I have the luxury of being able to like tackle a couple of these at a time.
1:03:00 that's kind of where I'm at with it.
1:03:02 And the goal is to really.
1:03:04 To build a service that makes sense both for individual developers, for
1:03:08 whom it will be the first point of contact with local-first or distributed
1:03:12 state, for small companies to build, successful apps super quickly and
1:03:17 kind of like being able to reach a much wider economy of small companies
1:03:22 and individual developers who can now meaningfully build real things that
1:03:26 are useful to people and maybe because.
1:03:29 It's so much easier to build things.
1:03:30 You can now build products that target smaller niches.
1:03:34 And that's really interesting.
1:03:35 And also to just give a tool for like bigger companies or even enterprises to
1:03:40 be like, Oh, it's actually really hard for us to build high fidelity apps.
1:03:46 Figma like notion.
1:03:47 We want these because we have lots of people and lots of teams that interact,
1:03:50 but we don't have the know how to build something like a sync engine.
1:03:54 That's just way too complex for a company to do itself.
1:03:57 But if that's now an off the shelf abstraction and there's kind of like an
1:04:01 obvious either third party service or something that you can deploy on premises.
1:04:06 That's really powerful and interesting and I think enables a lot more
1:04:09 bigger companies to build their own software as well and have it
1:04:12 immediately be as good as the best, like, SaaS apps we have right now.
1:04:17 That's, that's kind of the potential I see in it and what I'm trying to
1:04:20 address in the, in the medium term.
1:04:22 I like that a lot.
1:04:23 And that also makes me think about, like the, this concept called small giants.
1:04:29 I think it was also, I think I first learned about it on the Metamuse podcast
1:04:33 by, that Adam Wiggins did in the past.
1:04:36 Hopefully it comes back at some point.
1:04:38 but this is where they did one episode about the idea of small giants.
1:04:42 And this is basically that a very small team, possibly could be like just,
1:04:48 an individual small team, et cetera and they can build products, reach a
1:04:53 really wide audience without having to build up all of that load and to.
1:04:59 Like, for example, WhatsApp was when I think it was acquired before
1:05:04 billions of dollars by, by Facebook, was still a very, very small company.
1:05:09 I think, they've been, I don't get the numbers exactly right, right
1:05:13 now, but like, I think within 10 to 50 people where they've already.
1:05:18 Reach like billions of users.
1:05:21 I think similar for Telegram, well, Telegram is a little bit in the
1:05:24 news right now, but, I have a lot of admiration at least for like how they
1:05:28 built the product in terms of the craft, et cetera and it's also similar there.
1:05:33 There's a very small team that can still reach a very wide audience.
1:05:38 And I think this is what local-first can really empower, where you can empower
1:05:44 a lot more small giants to serve a much more richer, diverse set of use
1:05:50 cases, where a bunch of current existing products could be replaced by local-first
1:05:56 products, but not just by one local-first product, but a hundred different kinds
1:06:02 of people who have specific use cases.
1:06:04 There are a hundred different small giant.
1:06:07 Build products specifically for their use case, for their niches.
1:06:10 so instead of like having, 10 very, very large monopolies, like, dominating
1:06:16 a particular segment, let's rather have like a thousand individual
1:06:20 builders reach smaller slivers and have products that fit particular use cases.
1:06:28 And I think this is where you can empower them.
1:06:30 They can focus.
1:06:31 Similar to Invoice Radar, focus on specific use case and
1:06:36 then, use a syncing service.
1:06:38 So that makes a lot of sense.
1:06:39 And I'm looking forward to that future.
1:06:42 before we close out, I'm interested in hearing your perspective on the more,
1:06:48 the bigger web ecosystem as a whole, as you've been building apps within the
1:06:52 web space for a long time, now you're contributing a, better development suite
1:06:57 to that, but I'm curious whether you have any sort of strong opinions on the
1:07:04 The web is fine
1:07:04 I think my strong opinion on it is that I kind of don't have one, or like there's
1:07:09 a lot of critical voices that complain about all kinds of things about the web
1:07:15 and its state that are completely fair.
1:07:17 Right.
1:07:18 But I think what kind of gets lost within that is that the web is actually fine.
1:07:23 And it's not only fine.
1:07:24 It's, it's like, it's amazing.
1:07:26 It's like, I think first and foremost, it's this like
1:07:29 crazy distribution mechanism.
1:07:32 and, I think, you talked about this in a previous episode, that like, you can just
1:07:37 send your grandma a link and she'll know.
1:07:40 What to do with it.
1:07:40 Right.
1:07:41 and it will, she'll see what, what you see.
1:07:44 and that's crazy.
1:07:45 That's something that is just so at the core of the web.
1:07:48 And, sure.
1:07:48 It's kind of weird that like JavaScript got tacked onto like a
1:07:52 document representation and so on, but it is a really powerful VM.
1:07:59 That is super dynamic, would make anyone who likes Lisp or Smalltalk
1:08:05 proud if you really think about it.
1:08:07 But it's like, everyone has it.
1:08:09 The best minds of our generation optimized it to the death.
1:08:15 And you just get all like, CSS is crazy, but you can do a lot with it.
1:08:21 and you just get all of that.
1:08:22 And.
1:08:23 It's kind of not doing what it was originally meant to do.
1:08:26 It's kind of like an app distribution system now, but because it's so
1:08:32 flexible and so malleable, I think my big point is actually that we can
1:08:36 just make it do whatever we want.
1:08:38 for example, when I think about Jazz and what Jazz does, the way Jazz works is, is
1:08:43 it's actually like a high level framework and then like a protocol underneath it.
1:08:48 And it's a very minimal, simple core that does like, the implementation of
1:08:53 the CRDTs and like how to sync them, how to persist them and the cryptography,
1:08:57 like how do the permissions work?
1:08:59 That's all like defined.
1:09:00 And then like you get higher level features on top.
1:09:03 And if you look at that, it's kind of like a new networking protocol.
1:09:06 And in many ways, it's like what I think the web should have been like just taking
1:09:11 seriously that we're building like this.
1:09:13 Network of distributed nodes that have partial state and being able to represent
1:09:18 user identity and permissions across that.
1:09:20 so like one kind of pessimistic take would be that like, Oh yeah, that's
1:09:24 obviously better, but we'll never get there because we're stuck with the web and
1:09:28 this like centralized client server model.
1:09:31 And that's like at odds, but like, it's not at odds at all.
1:09:34 We've got web sockets and we can just build.
1:09:37 The protocol on top of client side JavaScript and server side JavaScript
1:09:42 and hopefully soon other server side programming languages and
1:09:45 native apps and, communicate over the web socket or maybe soon web
1:09:49 transport or like HTTP 3 or whatever.
1:09:52 It's like you can actually do a lot of crazy stuff with the web and, we
1:09:57 can just like, yeah, just embrace the fact that In the history of computing,
1:10:02 we almost never replace things.
1:10:04 We just add archeological layers of like, we're building the thing that we
1:10:08 really want, but we have to build it in terms of what's already there and like
1:10:11 widely available and it's actually fine.
1:10:15 And that's, that's.
1:10:16 How like you kind of have the psychological aspect that we talked
1:10:20 about earlier, where like this crazy new thing has to look and sound
1:10:24 familiar, but also very pragmatically it has to be implemented based on
1:10:29 things that already exist where you don't have to really replace anything.
1:10:33 That's, that's kind of my take on the web, right?
1:10:35 Right.
1:10:36 I love that.
1:10:36 I did this year, I did a three week journey through some of the
1:10:42 national parks of the United States.
1:10:45 And we also, spent a couple of days at the Grand Canyon where we just See like
1:10:50 those like massive, massive, like layers of layers on top of layers that just reach
1:10:56 back, I think like millions of years.
1:10:58 I don't recall the exact facts anymore, but I think it's a very good observation
1:11:03 that, we rarely replace something categorically, but we just build on top.
1:11:08 Maybe we phase one thing out, but that takes like, decades often.
1:11:13 And, it's kind of a miracle how capable the web has gotten, given how weird
1:11:21 it is and how many words it has.
1:11:23 So I think I like that observation a lot.
1:11:26 And, yeah, given the, given often the web for me is like a love hate relationship,
1:11:33 Outro
1:11:33 So, uh, Anselm, this has been a really great conversation.
1:11:37 I've learned a lot about Jazz.
1:11:38 I've been very inspired by the way, how you think about the entire space overall.
1:11:44 So maybe you want to have a, you have a last chance to plug anything,
1:11:48 give any shout outs, but other than that, I'll thank you for your time.
1:11:53 Yeah, I mean, thank you.
1:11:54 I really enjoyed this conversation as well.
1:11:56 Definitely shout outs to Ink and Switch because they are my biggest inspiration
1:12:01 and what kind of, what gave me a lot of the ideas in the first place.
1:12:04 In terms of plugging stuff, again, coming back to psychology, like I can tell
1:12:09 developers about all the advantages of Jazz and so on, but like, So far, what
1:12:14 has worked best in getting them to adopt it for even like a small experiment or
1:12:18 even getting them to start doing the guide and the official docs is just
1:12:22 being like, look, I've got these like shiny holographic stickers for Jazz.
1:12:27 And like, I've got boring stickers as well.
1:12:30 And like, everyone can get them at meetups.
1:12:32 I put them on tables and stuff, but like, if you want one of the special shiny ones,
1:12:36 you have to build something with Jazz.
1:12:37 And like, if you just do the official guide that counts as doing something with
1:12:41 Jazz Just show me like wherever you are in the world, either we meet in person
1:12:45 somewhere or I'll mail it to you, but you, you get the special shiny sticker.
1:12:49 Okay.
1:12:49 That's the deal.
1:12:51 All right.
1:12:51 There's, there's a first on the podcast.
1:12:53 There weren't any holographic stickers yet.
1:12:56 So I might just as well give this a try afterwards.
1:13:00 And the next time we see each other, I might steal one of those.
1:13:04 But thank you so much.
1:13:06 Thank you so much.
1:13:07 I really enjoy myself.
1:13:08 Thanks for having me, Johannes.
1:13:10 Thank you for listening to the Local First FM podcast.
1:13:13 If you've enjoyed this episode and haven't done so already, please
1:13:16 subscribe and leave a review.
1:13:18 Please also share this episode with your friends and colleagues.
1:13:21 Spreading the word about this podcast is a great way to support
1:13:24 it and help me keep it going.
1:13:26 A special thanks again to Rosicorp and PowerSync for supporting this podcast.