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