00:00What do you mean replicate the
whole data to the end client?
00:03Like, It's too big.
00:03Like, that can't work.
00:04So I understand the hesitation.
00:06But any like half step in that
direction, it just a gateway to
00:10replicating more and more and more.
00:11Cause you just want more and
more and more to be instant.
00:13So I had a very traditional mindset
around it, which is, okay, we have an
00:17API, the API serves data and we're going
to like cache some of that locally.
00:22And I think a lot of people are already
doing this stuff, like react-query
00:24put you in that direction where just
caching stuff and then refetching.
00:28It kind of gives you some of this like
real time local-first feel, but then
00:32you start to hit the limits with that,
if you're looking for stuff that's not
00:34literally in the exact view, you're then
round tripping with the server again.
00:39The key thing to understand is if
you're building an app that people
00:42are actually using every day, the
initial load time is really not
00:46something you need to care about.
00:48Welcome to the Local First FM podcast.
00:50I'm your host, Johannes Schickling,
and I'm a web developer, a
00:53startup founder, and love the
craft of software engineering.
00:57For the past few years, I've been on a
journey to build a modern, high quality
01:01music app using web technologies.
01:03And in doing so, I've been falling down
the rabbit hole of local first software.
01:07This podcast is your invitation
to join me on that journey.
01:11In this episode, I'm speaking to
Dax Rad, who is using local first
01:15in multiple projects, including the
serverless deployment tool, sst.
01:19dev, a healthcare app, and an
upcoming personal finance app.
01:23In this conversation, we explore how local
first simplifies app development, the UX
01:29and data patterns he's using, and how self
hosting could empower local first apps.
01:34Before getting started, also a
big thank you to Expo and Crab
01:38Nebula for supporting this podcast.
01:40And now my interview with Dax.
01:42Hey Dax, welcome to the show.
01:44How are you doing?
01:45Good.
01:45How are you doing?
01:47I'm doing great.
01:48Super excited to have you on the show.
01:50You're certainly also one of the
more, well known voices on Twitter
01:54sharing the local-first gospel.
01:56So, seems like you're not just working
on one project with local-first,
02:00but almost quite a portfolio of
local-first inspired projects.
02:04So super curious to hear more
about those, but maybe you want to
02:08share a bit of your story of like,
what has led you to local-first?
02:12yeah, so my name is Dax.
02:13My primary project that I work
on is a project called SST.
02:18Uh, we're a, we're a dev tool.
02:19Like, we help people ship applications.
02:21We help people deploy all kinds of
infrastructure to all kinds of places.
02:25And we have an adjacent project to it.
02:29Uh, so SST users get access to
this thing called the SST console.
02:33And that is a local-first application.
02:36I mean, I'm gonna say local-first.
02:38There's obviously, like, a spectrum.
02:39I would say it's a local-first.
02:41The least local-first thing with that
you could possibly have while still,
02:45I would say, embodying some of the
characteristics, but my history with it,
02:49like most people or like a lot of people,
I guess, uh, it started with, with Linear.
02:54I came across.
02:56The product probably like 2018 or 2019
somewhere, somewhere around there,
03:00probably 2019, something like that.
03:02And I found them fascinating
in a few dimensions.
03:07One, their attention to detail
was just kind of outrageous.
03:10Like there's all these little details.
03:12Outside of local-first stuff, just these
details that are in there that, you know,
03:16they're, they're like real craftsmen.
03:17They care about, uh, every
little aspect of their product.
03:20I found them really interesting from
a business perspective because they
03:24entered the most crowded and most
cliche space you can possibly think of.
03:28Everyone has had the idea of, I
hate my project management tool.
03:32Like I should build my own,
uh, the most boring, cliche,
03:36non innovative idea possible.
03:38They enter that space and
they absolutely crush it.
03:40Like no one really could
have predicted that.
03:42I think you would have, if you
just heard that idea, you're just
03:45been like, whatever, and they did
that purely from this aspect of.
03:49Really excellent quality and performance.
03:52And these are things that people will love
to say, like, oh, the user doesn't care.
03:56People, performance doesn't matter.
03:57Like, you know, they'll try to say that
it's something that you can do later.
04:00And this is a great example of a company
that's kind of violating that narrative.
04:05So I find them really fascinating.
04:07And I got obsessed with just digging
into how They built their stuff
04:11initially from like a UI perspective.
04:13But then I was like kind of looking
into how all this, how everything
04:16is super responsive and instant.
04:18And I started them so hard to the
point where I think I was really
04:21convinced at some point that I
knew more about their system than
04:23anybody that didn't work there.
04:25Like I understood like their
exact protocol, like how
04:27they sort stuff locally.
04:29Uh, I kind of just kept going
back to it to refer to it.
04:32And around the same time, my
wife and I were starting a new
04:34project in the healthcare space,
and this was a productivity tool.
04:39So it's the type of tool that people log
into the beginning of the day, use it
04:43all day until they finish their work.
04:45So these are the places where
I feel like the performance
04:49aspect is really understated.
04:52When you're using an app every single
second of the day to do your work,
04:57There's all those little paper cuts
where something takes a little bit longer
05:01to load, or there's like a spinner.
05:03These do weigh on you.
05:04If you talk to the user, they
probably won't articulate it.
05:07But if you ask them the question, does
it feel like a joy to do your work?
05:11Or does it feel draining to do your work?
05:13And they're going to say draining
unless you push things to this degree.
05:17and this never shows up in like
typical user research or like user
05:20feedback or any of that stuff.
05:22So because we were working on
something in this category, I
05:24was like, okay, we have to do it.
05:26We have to like set the, meet
the same bar that Linear met.
05:29And that's kind of when I started
digging into what are all the
05:31different ways that we can enable this.
05:34And we started from like a JSON
API using Orbit to like replicate
05:39the data locally, to GraphQL and
Urql to do something similar.
05:44Um, and then we eventually
ended up on Replicache after,
05:47like, trying a few of those.
05:48Uh, we also tried, I
think, RxDB at some point.
05:52Because we knew that, yeah, we
want to have almost every operation
05:55happen locally, if possible, so
that the feedback is instant.
05:59You know, searching, and this is in
the healthcare space, so searching
06:02through patients should be instant.
06:03Loading up their information
should be instant.
06:06Even if we had a really large data
set on the server, In terms of like,
06:10a single business might have, you
know, tens of thousands of patients.
06:14An individual doctor is
only seeing a small subset.
06:16So having the ability to like,
partially sync the data that
06:19we know the user cares about.
06:21So we spent like, through the
course of building this product,
06:24we tried so many different setups.
06:25And we've probably spent two years of
learning and trying how to do these
06:31patterns before we landed on something
where, one, like the tools, like
06:35I said, we ended up on Replicache.
06:36Replicache is a tool that we liked, and
two, like, As people building products,
06:40like we understood how to like, really
take advantage of it, how to structure
06:43things and where to pay attention.
06:45So that product is called Bumi.
06:48Uh, we actually ended up
deciding to pivot away from it.
06:50Uh, like we have, we have some customers,
but it just ended up not being a
06:54market that was particularly large.
06:56And so we wanted to switch to
something that was a lot more,
06:59like, wide, like anyone can use.
07:02And something that we personally
would use, I found that any product
07:05I build where I personally use it, it
just comes out like 10 times better.
07:09It's just way easier to understand the
problems and be motivated to fix them.
07:13So we're working on a new
product called Radiant now.
07:15And that is a personal finance
application, which again,
07:18there's thousands of, very
similar to the Linear story.
07:21But we really believe building,
like, a very power user
07:25productivity focused version of it.
07:27There's like interesting
room in the market for that.
07:30So the one other thing just to kind of
cap off the story is, uh, so between
07:33those two things, uh, working on SST, we
also kicked off a new project there, the
07:38SST console, which I mentioned earlier.
07:40Kind of a similar story where this
is a tool that you use alongside
07:43your day to day development.
07:44You're using all the time.
07:46Having every single thing be fast
really makes a difference in the end
07:51feeling that users have of the product,
so we decided to go with the same kind
07:56of local-first ish model for that.
07:58And that one is completely open source.
08:00We were really public about building it.
08:02I think a lot of people were exposed to
the idea of This pattern, and we've seen
08:07people like, kind of take that project
and like, use a basis, use it as a
08:12basis for things that they're building.
08:13So yeah, I think for me it's
always been about delivering
08:17a much higher user experience.
08:19I really feel like at some point
the web was really focused on how
08:25can we make the web feel native,
and that was like the obsession.
08:28And for some reason that like, kind of
went out of popularity, but I personally
08:33still care about that as an end user when
I use products and they're slow and laggy.
08:37I want everything to be my browser.
08:39I like that and I want people
building those things to care
08:41about those things because I'm
just going to be happier as a user.
08:44And it's kind of been my.
08:45My reasoning to really like, you know,
spread the word about this stuff.
08:49Yeah.
08:49Everything you've just said
deeply, deeply resonates with me.
08:52I'm similarly also very inspired
by, by the folks at Linear, how
08:56much value they put into the craft.
08:59I was actually just, uh, as a
little anecdote, I was just having
09:03drinks last night, uh, with Julian
from the, the, the Linear team.
09:08And we were also chatting about
this and similar to what you've
09:11described as that it's so tricky.
09:13It never shows up in your user interviews,
et cetera, that people say like, Oh,
09:18like I'm really annoyed that this
button takes like 300 milliseconds.
09:22But if it was instant, then I think
people will really, uh, share that.
09:26And it's basically like a, more of like
a death by a thousand paper cuts, and
09:30it's too hard to enumerate the thousand
paper cuts, but it's still kind of clear
09:35that the product is not very smooth.
09:37But once you really, once you're using
Linear, then there is no going back.
09:42And this seems to be also
still like a challenge in terms
09:44of communication for them.
09:46How do they articulate to someone
who has not tried it out yet?
09:49What the difference is?
09:51It's that overall quality and, but
I think they're doing a great job of
09:55just being sort of like the lighthouse
example now of like what that next
09:59generation category defining product
feels like and should be like.
10:04So I think they're, they've like
bootstrapped their way out of that, that
10:07problem and it's very inspiring for me
where I'm like my JIRA is kind of music
10:13apps where I am annoyed by the thousand
paper cuts that you have in when you're
10:18using Spotify or SoundCloud, et cetera.
10:22So many of those supposed apps feel
more like websites that really like
10:27Winamp was a, or iTunes back in the
golden days, that was a much superior
10:32user experience to what we have today.
10:34We have maybe a richer ecosystem in terms
of available music, but the actual user
10:39experience that has really suffered and
I similarly also care a lot about how
10:46native can you make a web app feel like.
10:48And not just, end up with your
ambitions on like a website level.
10:54So, uh, that deeply resonates.
10:56I think there is, it's both, uh, equally
exciting to explore that from a user
11:00experience, what really drove you.
11:02But I think there's also a lot
of potential from a developer
11:06experience point of view, where I
think there's also so much stuff
11:11we just put up with as a developer.
11:12So I'm also curious to hear more on that,
but yeah, you, you mentioned that you
11:18had a one to two years of explorations
early on that, where you figured out
11:24how not to do it, I'd love to hear a
bit more about those failed attempts.
11:28Yeah, so I think, the spectrum
really was just us dipping a toe to
11:33then going further and further and
further with how much is done locally.
11:36So, I think initially, it's, that
sounds weird to everyone, right?
11:40Like, what do you mean replicate
the whole data to the end client?
11:45Like, it's too big.
11:46Like, that can't work.
11:46Or like, what about this?
11:47What about that?
11:48What about that?
11:49Uh, so I understand the hesitation.
11:51But any like half step in that direction,
it just kind of a gateway to like, just
11:55replicating more and more and more.
11:57Cause you just want more and
more and more to be instant.
11:59So I had a very traditional mindset
around it, which is, okay, we have an
12:03API, the API serves data and like, we're
going to like cache some of that locally.
12:07And I think a lot of people
are already doing this.
12:09Like a lot of stuff, like react-query
like gives you this starts to like put
12:13you in that direction where just caching
stuff and then like refetching, you know,
12:17when the window becomes active again,
it kind of gives you some of this like
12:20real time local-first feel, but then you
start to hit the limits with that, where.
12:25If you're like, if you're looking
for stuff that's not literally in
12:28the exact view, you're then kind of
round tripping with the server again.
12:32And I think the key thing to understand
is, is if you're building an app that
12:37people are actually using every day,
the initial load time is really not
12:42something you need to care about.
12:44The first time they load the
app, like let's say they like
12:47log out or it's a new computer or
whatever, they're setting it up.
12:49Okay, like maybe they're downloading
a couple megabytes of stuff.
12:53That's going to be slower than You
visiting some public website that's
12:57like optimized around like the initial
load time, of course, but once that
13:02initial cost is paid, every single
interaction that they have going
13:06forward from there is insanely fast.
13:09And that trade off is so worth it for
apps that people actually use as a joke.
13:13I like to make out is that the
web has become so obsessed with
13:17optimizing for websites where people
visit and leave as fast as possible.
13:22I'm like, If you're working on
something like that, totally get it.
13:25Like totally get all the, the SSR stuff.
13:27Everyone's obsessed with all the, like
the infinite levels of like CDN caching
13:31and the little optimizations there.
13:32I totally understand that, like
minimizing bundle size, all that stuff.
13:36But a lot of people work on SaaS products.
13:38Most of the products that I use every
day are not, don't fit in that category.
13:42I'm using them every day, like
just preload stuff for me.
13:45And I feel this way about some
of the biggest products, right?
13:48Like think about GitHub.
13:49I'm an open source developer,
like, my day to day job is
13:52maintaining open source projects.
13:53I'm in GitHub all day, clicking
through issues, looking through
13:57commits, looking at PRs.
13:59It is so frustratingly slow how
almost every single interaction
14:04results in like a page load.
14:05GitHub knows, okay, you're not going
to send me all of GitHub to me locally.
14:10But you know there's these three
repos I work on every single day.
14:13Sync that locally, sync
that optimistically.
14:15Like that would save me so much
time and frustration and energy.
14:19And actually scratch that.
14:20It's not really about the time.
14:21It's really about the energy for me.
14:22You can spend four hours doing
work that saps your energy and four
14:27hours where you feel empowered.
14:28And to me, like good apps like this.
14:31I like feel super empowered
and it's not sapping my energy.
14:33I'm not drained after the four hours.
14:35I'm like ready to go on to my next thing.
14:37Right.
14:37And yeah, some of these biggest apps
that are productivity apps are so
14:40built like traditional websites.
14:43Definitely.
14:44Yeah.
14:44I mean, the, the use case that
you've mentioned in regards to
14:47GitHub is, is an excellent example.
14:49Like for, like you have those.
14:52units that are really self contained,
most repos don't have hundred of thousand
14:58of issues it's really easy, like takes
roughly the same amount of data that
15:03like your initial JavaScript bundles took
to just download the entire, thing as a
15:08SQLite database or like in another format,
and then just have it there available.
15:13Since you're navigating so much within
the scope of a GitHub repo, whether
15:17it's Between GitHub issues or going
to like a pull request or something
15:22and whatever paper cuts you experience
there, it really lowers your effort
15:27of like wanting to go the extra mile.
15:29Whether you want to respond to
someone's like, in a GitHub comment.
15:33I think, uh, Jamie Kyle, actually, I
think he ran a couple of experiments
15:37there that's literally faster on GitHub
to open a new tab for a link and have,
15:43get the server side rendered stuff than
dealing with like the, The, the rail
15:46style in navigation on the existing site.
15:50And that speaks exactly to,
to the symptoms that you've,
15:53that you've described.
15:54I will also call out a project.
15:57I don't fully remember the name
anymore, but someone on Twitter, I
16:00think was working on, on exactly that,
like a little GitHub client that is
16:05local-first inspired, that pulls down
your data that you're dealing with to
16:10make exactly these interactions fast.
16:12Maybe you know the name.
16:13Yeah, so I actually
tweeted asking about this.
16:15I remember seeing it and
I couldn't remember it.
16:17And I think it was, uh,
by Devin, the Parcel JS.
16:20Yeah, so I saw him
messing around with that.
16:22I don't know if he ever, like, finished
it or released it or anything, but
16:26yeah, this is so desperately needed.
16:29GitHub isn't going to do it, I don't
think, because it's so outside the
16:32scope of how their system works.
16:33But just someone, please, just
build a thing that syncs the
16:36issues and PRs optimistically.
16:39And you're going to save me so much.
16:40I'll pay for this product easily.
16:42I don't know how big the market is
for people that care this much, but it
16:45doesn't seem like that much work because
it's just a single repository view
16:48and some of the stuff that's in there.
16:51And you could totally do this.
16:52Yeah.
16:53This is kind of what I was saying before.
16:54I'm mostly speaking as a developer,
like building these things.
16:57But the end thing I
care about is as a user.
17:01I just want more of this
stuff out there in the world.
17:03So I'm not as frustrated.
17:04I definitely agree.
17:06And like, I applaud you for like going
that adventurous path and that extra
17:10mile with SST console, since I think you
had the right intuition there and it is
17:16paying off in terms of just how fast that
feels to use and how much, like you say,
17:21like it no longer drains your energy.
17:23Yeah.
17:24It gives you energy using that.
17:26And once you had that experience,
you'd really like every loading spinner
17:30that you see is so much more painful
afterwards when you're like using,
17:35for example, the, Cloudflare console,
it's like the same thing there.
17:38Like you're within a project , you
have that many deployed workers and
17:41you just want to navigate between that.
17:43It's fine that my logs stream in.
17:46But all the metadata around
that should just be instant.
17:49It's a tiny amount of data.
17:52And like the majority of apps, if you
really look at what data people are
17:55constantly going between, it is so small.
17:58So yeah, you figured out like the, the
patterns early on or rather that you've
18:02realized, okay, you started with a bit
of caching, a bit of more caching, a
18:06bit of more caching, and you didn't
quite find the right line to draw.
18:10So you just, okay.
18:11We're going to just
bring over all the data.
18:14Did you have other sort of learnings
where you had to rewire your brain?
18:19Yeah.
18:19So I think, uh, one other middle step
we had was we tried it through GraphQL.
18:24We weren't particularly
interested in the GraphQL part.
18:28It was, it just happened to be
that, uh, Urql, the GraphQL client.
18:32It implemented a lot of, uh, the
local-first stuff like you could
18:37replicate the whole database
locally and because GraphQL has a
18:40nice, idea of like relationships
between objects, the data format
18:44locally could be pretty intelligent.
18:45like, downloaded 1 thing, it knows
how it's related to another thing.
18:48So if you query it from a different
path, it can, like, resolve it locally.
18:52So there's just some
clever things that it did.
18:54And we thought that was really cool.
18:55But what ended up sucking was
we didn't really like GraphQL.
19:01And everything you did, even local
operations, required GraphQL as input.
19:06which again is fine.
19:07It's just, it just wasn't
really clicking for us.
19:10And again, it still had this, uh,
There was a limitation of like, it
19:15wasn't really meant or initially
designed to have all data locally,
19:19so it's all like, there's always like
some stealing or some performance
19:22issue or something you run into.
19:24So when we went all in on having,
okay, like we, the system is primarily
19:28designed around syncing the data locally.
19:30What we found actually, and I think the
Linear people talk about this too, is.
19:34The developer experience around
this became a lot more simple.
19:38So my wife, who I work on this
stuff with, she is not an engineer.
19:43She does everything else outside of it.
19:44But in the past couple of months, we're
like, why are we drawing that boundary?
19:48Just learn how to be more hands on.
19:50And so she's been learning like
how to actually like write the code
19:53and build these things and she's
making like fantastic progress.
19:56One of the things that's
been crazy helpful is.
20:00All the data's just there locally.
20:02So for her, even though she's a
beginner, it's such a simple model.
20:05She's not like figuring out the round trip
with the server, like syncing all that.
20:10Like, I handle all that, and I make sure,
like I figure out how the data looks like
20:14on the back end, and I make sure it's
all synced correctly to the front end.
20:17From there, there's not all this weird
like, loading states, or like fetching it,
20:21or like just a whole bunch of complexity
around getting data back and forth.
20:25It's solved in one part of your
app, and then you never have to
20:28think about it anywhere else.
20:29So just from like a team productivity
point of view, like she can build
20:33any feature she wants, even if I
didn't like explicitly think about
20:37it from the backend point of view,
because she has all the data locally.
20:41She's like, I want to create a view
that searches through this set of data.
20:43She can just go do that.
20:44All the data is there.
20:45Very, very straightforward.
20:47And it's actually wild how much of
a productivity boost that has on
20:51your team, because you're not like
constantly building these like back
20:54and forth with every new feature
you're not rebuilding another way to
20:57like sync that data back and forth.
20:59and it's been amazing.
21:01That's so liberating.
21:02Uh, we talked about this also in the
recent episode with Kyle, who drew the
21:06comparison of like going from jQuery to
React where React freed you up of like
21:11that manual view maintenance and now
going from like the, the manual state
21:15transfer across different environments
that frees you up of like that data
21:20management and you can now actually.
21:22Focus on what matters most, like
building a great user experience
21:25and putting the effort into the
pieces that do really matter.
21:29And that simplification that is just so,
so hard to overstate how nice that is.
21:35And I think that also unlocks
a whole bunch of like new.
21:38tooling.
21:39So for Overtone that I co developed
with the project Rffle, or now called
21:45LiveStore, it's always been a first
class citizen to have great dev tools.
21:49And one of the parts of the dev tools
is to have a data browser in there.
21:52So it basically feels like a
Google spreadsheet and really it
21:56also acts as a Google spreadsheet.
21:57You have, you have like visual view.
22:00on all of your data, if you change
something such as like a playlist
22:04title in that data browser, it like
automatically updates in your app.
22:09And there's no question of
like, Oh, do I not need to like
22:12send this to this REST request?
22:14But do I need to also like,
Invalidate this in Redis.
22:18No, you just like set
the data and there it is.
22:21Yeah, that's great.
22:21I mean, a local data route is actually
something that we're definitely
22:24missing, but that's a, yeah, it's like
it enables so many things like that.
22:29Just the debug ability and observability
of what's going on and just being
22:32able to change something in one place
and have it update everywhere, like
22:35in your view and in the backend,
it's just so, it's so much simpler.
22:38And it's weird because I feel like
apps used to kind of work this way.
22:42Like when I got started, I was
building desktop applications.
22:46And I guess there wasn't really
a cloud component in some of
22:49the initial things that I built.
22:51And they were this simple because
the data was just local and like
22:53you'd hit a button and you like
mutate the data and it's it's there.
22:56So yeah, to me it feels like
returning to a simplicity with like
23:00much more power and capabilities
that we didn't have back then.
23:03Exactly.
23:04Plus we now also get the power of
the cloud for collaboration and
23:07like a lot of the, the nice pieces.
23:10But I think there's just been an over
investment over the last 10 years
23:14into having everything be so cloud
centric that like you built like
23:19even a local calculator probably as
like a remote rendered server app.
23:24And, I think now also bringing more
investment into kind of back to the roots,
23:30uh, in, in this way of building, building
apps, I think this will also help more
23:35people who are not quite as adventurous as
you are to, to really explore this before
23:40others do, that this becomes a more viable
standard path that people build apps with.
23:45Yeah, and like there are, like
a lot of stuff becomes simpler.
23:48There's some new stuff you have
to learn, of course, like with
23:50any new paradigm, there's, things
that are a little bit different.
23:52I think some of those involve things
like, so in our case, in the Bumi example,
23:57we unfortunately had customers that
had too much data, where it wasn't as
24:01simple as just syncing it all locally.
24:03So we have to think of like some new
kind of like UX related patterns where
24:08we kind of optimistically sync stuff
that we think the user will care about.
24:12So like the first time you visit
a patient, it might take a little
24:15bit to load because we didn't
sync all the patients locally.
24:18We do sync like a shallow version of the
patient locally for everyone, so they can
24:23search through all of them really quickly.
24:25But to get into the full
details, like you might not.
24:27That's too much data to send to everyone.
24:29So the first time you go
there, it'll be a slow load.
24:31But from that point, we kind
of flag them as, Oh, this
24:33user cares about this patient.
24:35And from then on, we'll
constantly send them updates.
24:37If they haven't visited the patient's
profile for like two weeks or
24:40whatever, then we'll kind of unflag
it as something that they care about.
24:43These are like new patterns
that, you know, they don't really
24:46exist in a traditional app.
24:47But this mixture of local and cloud, you
can get pretty far with tricks like that.
24:52And we kind of have to learn some of
those tricks and some of those ideas.
24:55Because we have a whole like We
have, I forgot what we called it, but
24:58it's like, uh, We have like a system
where you can easily flag stuff as
25:02a user is interested in this thing.
25:03And if you flag it, it starts getting
synced and then it'll get unsynced
25:06after some window that you specify.
25:08So we kind of have to like, you
know, think about that and, and
25:10create a framework around it.
25:11But that's one.
25:12The second thing is like,
obviously handling, And this
25:15isn't unique to local-first.
25:17Anywhere you're doing optimistic
things, obviously there can be
25:21errors that happen on a delay.
25:23Again, it depends on
the type of application.
25:24Like a music player, probably, the
syncing is probably like pretty
25:27straightforward, but for something that's
Looks more like a traditional SaaS app.
25:32There might be sources of truth that
can't be validated entirely locally.
25:37So you'll end up with situations where
the user does something, then goes
25:40away, then the error shows up later.
25:42And like, you need like a whole different
UX pattern when you can't block the user.
25:47It's worth doing because 99 percent
of the time they don't hit that error.
25:51So it's good to let them move on.
25:52But you have to handle a
case where, where they do.
25:54So there's different problems that show
up, but again, it's all in the name
25:57of a better experience to the user.
26:00So totally worth it.
26:01So, let's say you have some kind of.
26:03You can create a new field that needs
to be globally unique in your system.
26:06So let's say, uh, I mean, we can
just use Linear as an example.
26:10Like, you can create a new project
in Linear, but the name of the
26:12project needs to be unique.
26:14there's an impossibly small chance that
you create it and you move on, but someone
26:19had created it at the same time, because
they thought it was their job to do it.
26:23And there's like an issue, because
your write maybe got rejected.
26:26in a typical UI, when you create the
project, you would see a spinner.
26:31Spinning.
26:32Okay, created.
26:33Because you have a spinner there, you
can, like, make sure stuff gets written
26:36correctly and then you don't let the
spinner come back till you know for sure.
26:40It's good.
26:41Um, so anywhere with this like
unique feel type of situation,
26:43we run into this problem.
26:45Our fix is actually pretty simple.
26:47We just have like some kind of
like context thing of like pending
26:50stuff that hasn't been confirmed.
26:52And if it comes back with an
error, we just pop up a toast that
26:55brings them back to the original.
26:57We, like, reload that original content.
26:58If they want, they can click back
and go back to where they were.
27:01And, like, you know, change
the issue that they had.
27:05So I think we found that
pattern to work pretty well.
27:08Obviously, it's like, the
example I gave is really stupid.
27:11Like, no one is ever
going to run into that.
27:14There's some examples that are a little
less stupid, where it is reasonably
27:17possible that it could happen.
27:18But we found this idea of, like,
preserving the context of the
27:22UI and bringing them back to it.
27:24If the error happens,
they can opt to go back.
27:27We found that to work pretty well.
27:28Yeah, I think that's a very
elegant solution for this.
27:31I mean, another possibly even
more aggressive solution to this
27:35would be to say to gate this
feature behind being online.
27:39And to actually like establish some
notion of like a global transaction for
27:44that and, only let the user pass through
this intentional bottleneck if that
27:49has happened, but the way how you've
designed this in a asynchronous way.
27:54I think it's also very elegant.
27:56but I think this is the nice thing that
like local-first affords you or forces
28:01you to do is like, it frees you up from
a whole bunch of stuff you no longer
28:05need to do, but it really forces you
to think about carefully, what are the
28:09domain requirements of your specific app?
28:13And if your domain expert from
the app says like, Hey, this is
28:16what's really important here.
28:18There cannot be two project
names with the same exact name.
28:23Then like you can actually put in
the extra efforts to enforcing that.
28:27And this is what makes
the app worth it later.
28:29Yeah.
28:30Yeah.
28:30And it's, yeah, it's not all or nothing.
28:31You can opt in.
28:32So the thing that you said,
we are in the SC console.
28:34We do that when you're creating a
new workspace, we actually do have a
28:37spinner there because it's like weird
to like, Create a new workspace and get
28:41kicked back 'cause the name was taken.
28:43So yeah, we, we hold you there
And that's like, you know, a more
28:45traditional experience and that's
fine 'cause that's like a very small
28:49percentage of the app where you're
like creating a new workspace.
28:53You do that once when you sign
up and you never do that again.
28:55So yeah, you can kind of granularly
pick where you want a more traditional
28:59blocking approach and where you
want an optimistic approach.
29:02And I think a lot of the people that
are maybe skeptical of the local-first
29:05thing, I think they tend to imagine
it in these extremes of like.
29:09You have to sync all of your data
and obviously that won't work.
29:12Or like you have to have everything
be optimistic and obviously
29:14everything can't be optimistic,
but you can really pick and choose.
29:18It's more about what you default to.
29:20And then you opt out of It's good
to default to optimistic first.
29:23Cause that's, what's great for the user.
29:24Right.
29:25I think in the, in your context of
building SaaS apps, I think there's
29:29kind of layers to this entire thing.
29:31There's like the global system.
29:33That you're still in control of.
29:34That global system is probably not
local-first by all the ideals, but once
29:40you create an account or once you've
created a project, and now you enter like
29:44a smaller scope of that overall system,
and that now is very much local-first
29:50because this is where it actually matters.
29:51It's okay if your users sign up.
29:54takes half a second to load.
29:56But once you're in your productivity
environment, this is where you
29:59want to really have unlock the
benefits that local-first gives you.
30:03Yeah, exactly.
30:04The data, what is the
day to day workflow like?
30:06And that should be, that should be,
you know, an excellent experience.
30:09I think the other area, and we talked
about this a little, is there's also the
30:15desire for apps that don't die because
a company went out of business or like,
30:20you know, They were forced to find a
business model that didn't make sense
30:23for the idea that they were working on.
30:25And I think this does make
a lot of sense, I think.
30:27If you think about something
like a, like a video game.
30:30I mean, video games are different now,
but like, you know, there was a time
30:33where you would buy the video game.
30:35It was a finished product, and it
was on, like, a physical thing, and
30:39you could just run it and play it.
30:41And.
30:42You had that forever.
30:43So, but I mean, now you have like some
games that require you to be online
30:47or it's a, it's a hybrid of both.
30:48And like, you can imagine how at some
point this game won't be playable anymore.
30:53And that's happened to a few things.
30:55I think people feel that way
about applications as well.
30:57And I totally get that.
30:58I personally don't work on anything
where that's like the critical
31:02burning desire where like, you
want it to like really run locally.
31:06You want, you care about the
privacy, you care about whatever.
31:08I like totally get all of that.
31:10It just hasn't intersected with
like the areas that I focus on.
31:13So for me, it's been more about,
uh, just the experience side of it.
31:18And I think the reason is a little bit
tricky to go to that extreme in SaaS.
31:22is a lot of like a portion of your
value is in the end experience.
31:27And like we talked about, I think
people are under delivering there,
31:30but usually it's also tapping into
some kind of bigger data set or bigger
31:35capability that can't really run locally.
31:38So it's usually a mix of the two things.
31:40So I typically will have to
mutate the data outside of
31:43the user interacting with it.
31:44So if you look at something like,
uh, like Radiance, so this is
31:47going to be a personal finance app.
31:49You can totally build a fully
local-first version of this
31:51that runs entirely locally.
31:53That whoever's building the app, it can
be totally encrypted where they don't even
31:55have access to seeing any of this stuff.
31:57And there's like value in
building something like that.
31:59But, you know, with all these advancements
in AI and LLMs, those can actually impact
32:05Personal finance apps a lot in terms of
like making sure that data is cleaned
32:08up correctly, auto categorizing, like
all the things that sucked historically
32:11about these applications, LMS have
a lot of potential to fix that, but
32:17there's not really a good way to do that
in a local-first way, at least today.
32:20So that's why for us, you
know, for building this thing,
32:23it's not going to be this.
32:25thing that runs entirely locally
because we still want the ability to
32:27like process your data using tools
and technologies that, you know,
32:32unfortunately can't run locally today.
32:34Yeah, I think you've touched on a couple
of really interesting points there.
32:38So the, I think right now, the canonical
definition of like, what is local-first
32:43software is as according to the Ink and
Switch essay that lays out the seven
32:48ideals of local-first and I think you're,
You're, nicely sticking to the first four,
32:53which is like about the loading spinners
and that it works offline and so on.
32:57And I think what you've just hinted
at, what you don't do yet is what
33:01local-first calls like the long now
that your app like lives on, even if the
33:07creators are no longer working on it.
33:09And that's very understandable.
33:11That takes a lot of time
to, and effort to put into.
33:14And given that you just have so
much time to work on the app,
33:18that is not your highest priority.
33:19However, what I think is still nice and
a glimmer of hope there for the entire
33:25category of local-first inspired software
is that if at some point you say like,
33:30okay, I'm winding down development on
this app, then you could still much more
33:36easily to put in a bit of extra effort.
33:38to now round up the project
in a local-first way.
33:42I think we've seen a really nice example
of that with another personal finance
33:46app called Actual Budget by James Long.
33:49And so as he no longer had time to work
on that project, it was so much easier now
33:56to transition the app from something that
he hosted as a cloud service to something
34:00that people can just run by themselves.
34:02If you build like those monstrosities
of like giant Kubernetes cloud things,
34:08it's really, really hard to like, tell
someone how to easily just download a DMG
34:13and run this on your MacBook, whereas if
your app is local-first to begin with.
34:18Then, I think it's much easier to
repackage the app that you've built.
34:23And you can trim away a lot of
like the multi tenant stuff that
34:26you need about SaaS and just
package the, the productivity
34:30aspect of the core of your app.
34:33And then I think it's actually quite nice
and easy to achieve lasting software.
34:39Yeah, I agree.
34:40I think so.
34:41And with Radiant, we're
actually, so because we can't.
34:44Do this thing where it's like end
to end encrypted and because of
34:46what, what our goals are, instead,
we're making it dead simple to
34:51fully run the whole system yourself.
34:54If you care about hosting yourself and you
want all the data and a big part, and to
34:58be honest, that's a lot of what SST does.
35:00SST helps you ship very complex software
multiple times in multiple environments.
35:05and so, because Radiant is an SST
app, it is very easy to point it
35:09at your own private infrastructure
and say, I'm just going to have
35:12a self hosted version of this.
35:14And it's, and we're making sure it's
like, As simple as it can be to do
35:18that, and get as close to, like, using
the hosted version because there's
35:23like some weird benefits of that.
35:24Like, so this version that we're building
is going to be mostly built on Cloudflare.
35:28If a lot of people end up self
hosting it, that's great because
35:31Cloudflare is paying for the usage.
35:33Like, The free tier is coming out
of each individual's deployment.
35:37They're like self deploying
it into CloudFlare.
35:39And that's like an interesting model
for, I don't think for radiant, it's
35:42like particularly interesting, but
if you look at, um, there's another
35:45project by, uh, Ben Vinegar, he
works at Sentry, called CounterScale.
35:50So this is a classic, like Google
analytics type product, right?
35:54It does like this web analytics,
the basics, and it's very early on.
35:57But it's not a hosted project.
35:59It's just something that deploys
into your own CloudFlare account.
36:01So he can have a million users
using it for free without ever
36:05really, you know, paying for that
because, you know, CloudFlare is
36:08much more set up to offer that.
36:11I'm very interested in that model.
36:12Uh, cause I think for a lot
of infrastructure pieces
36:14like that, it is a nice.
36:16To have it alongside the
rest of your infrastructure.
36:18I worked a lot in healthcare
environment, which has a lot
36:21of compliance requirements.
36:23And oftentimes I couldn't use the
tool I wanted to use because it
36:26wasn't hostable in my own environment.
36:29So, um, we're pretty excited about
like letting people do more of that.
36:33I love that.
36:34And I think this is like intuitively.
36:37It should be easy to self host your
own software, like whether it's like
36:42some company running it or whether
I just like take the software, put
36:46it on my Raspberry Pi, put it on, on
Cloudflare or AWS, but in reality,
36:52that's very much the exception.
36:54I'd be curious whether you can share
a bit more of like the reasons that
36:57you see why that's so hard and how
you're trying to make that easier.
37:01Yeah, I think, uh, it's funny
because there's a weird alignment
37:05if you think about this.
37:07We are a small team.
37:08If our system is really complicated
to run, that sucks for us.
37:12If we can make our system really easy to
run and really low overhead and we care
37:15about that more than everything, it kind
of starts to look like something that's
37:18easy to self host by anyone, right?
37:21So I think for us, like, a lot of times
we'll choose architectures that look
37:24weird because they're like, Oh, that
looks like the fourth option on the list
37:28of the ways they could have built it.
37:30But it's because we really, really care
about, low operation overhead long term.
37:38So even if it's like, you know, 20
percent harder to build up front, if
37:41it results in like less babysitting on
our end, we'll like choose that option.
37:46And it's because we're very committed
to continuing to be a really small team.
37:49And so we'll, we'll end up picking
those options and those options happen
37:52to align with like, what's, what's
simplest for, for the end end user,
37:57if they're self hosting, I will say
like there is a version of doing
38:00this, which we don't do, which is.
38:03Building your stuff in the most,
like, neutral way possible, so it
38:06can run in literally any environment.
38:09I definitely get that, but you
do end up having to run a lot of
38:14infrastructure on your own to, like,
get any complicated application working.
38:18If you do it in a totally neutral way.
38:20We kind of picked a middle ground where
it's like, we do rely a lot on, like,
38:24in this example, like, we're going to be
using CloudFlare, we're going to be using
38:28workers, we're going to be using their
queues, we're going to be using their
38:29PubSub, all the CloudFlare native things.
38:32So, yeah, if you want to go take
that and run it inside, like, just
38:37a standard server you have, it's
going to be a little bit challenging.
38:40And like, there are adapters and
stuff, and you can figure that out.
38:43But we're starting with just making it
runnable in your own cloud environment.
38:49So you can sign up for a
Cloudflare account and run it.
38:51I know that doesn't like hit the
exact extreme of like being able
38:54to fully run it yourself, but we
think it's like a nice middle ground
38:57for a lot of companies, right?
38:58Companies typically are already
using some form of this.
39:01Getting this stuff deployed
into their own account.
39:03I think it works well.
39:05What's weird is you ask, like,
why isn't this more common?
39:08I think it's actually common in this
weird way that people don't expect.
39:13A lot of companies build
SaaS software, right?
39:16They'll build like, I don't know, let's
say, let's take some random common
39:20thing, like Auth as a service, right?
39:21Like, I'm going to build Auth as
a service that people can use.
39:25And they initially launched
that as like a hosted product.
39:28And nobody uses it except for
people that have no money.
39:32So they have like a lot of users, but
you know, these users don't pay a lot.
39:35They start to try to move up, up market.
39:38They end up with bigger
companies, you know, medium sized
39:40companies, enterprise companies.
39:42They'll all love the product, but
refuse to use a hosted service.
39:46So then they're forced to figure
out how to make their stuff run
39:49inside the customer's AWS accounts.
39:52So if you do look at a lot of
these companies, they kind of
39:54do have this hidden, like thing
that they eventually figured out.
39:57I think companies should realize they're
going to end up in this place anyway.
40:00Like it's very hard to build a big
business purely off of a hosted thing.
40:04Like some people do it when you
really have like a large market,
40:08but oftentimes you're forced to.
40:09Bring yourself inside
someone else's environment.
40:11So I think one way or another,
you're likely to hit that.
40:14So it's good to plan for that upfront and
assume that you're going to run into that.
40:17And we, because we're like, We're
more in the infrastructure space.
40:20We kind of expected that from the
beginning, which is why we care a little
40:23bit more about making all that possible.
40:26So let's imagine I want to follow
this paradigm for Overtone.
40:32And I do think that Cloudflare could
be a very interesting fit for that in
40:35terms of the modern primitives that it
provides, so what would I need to do as
40:41the application developer of Overtone
who buys into that vision and says
40:45like, Hey, I don't want to operate like
the cloud thing for that, but I want
40:49to empower every user to deploy their
own for the benefits that it provides.
40:54What would I as the application
developer need to do to make that happen?
40:58And then also follow up question.
41:00What does someone who wants to deploy
that Which sort of additional stuff
41:04do they need to deal with as opposed
to just using something like Spotify?
41:08Yeah.
41:09Yeah.
41:09Cool.
41:09So I think, I think the simplest way
to think about it is how hard is it you
41:13for you to spin up a staging environment
for your own application, right?
41:17You want to create an exact copy
of your environment, but you
41:20know, just the staging version.
41:22So this requires bringing up
all the same infrastructure.
41:24It requires like, you know,
running your database migrations
41:27to get the schemas running.
41:28Um, requires a bunch of things.
41:29And, you know, the obvious thing is
you should be using infrastructure
41:32as code to help you do this.
41:33You define all your infrastructure as
code so you can point it at different
41:36environments and run entire copies of it.
41:39That's like the bare minimum.
41:41If you yourself can quickly create
another environment for yourself,
41:45you've kind of solved the problem.
41:46Now someone else can
follow those same steps.
41:49Where they're just cloning
your project and running.
41:52You might be using Terraform, you
might be using SST, whatever it is.
41:55Uh, you can do a thing,
deploy with your credentials.
41:58And the same thing ends
up in your account.
42:00Where this is a little bit
challenging is updates.
42:03So obviously, you know,
you have new versions.
42:05People can clone and redeploy, whatever.
42:07But there's sometimes
operationally challenging updates.
42:11Like you might have like a schema change.
42:13You might have, uh, like
data needs to be migrated.
42:16So, ultimately, the thing to always
go back to is how do you make it
42:21easy for your own team to do that?
42:23Are there programmatic
ways of doing all this?
42:25Or, like, if you need to do ad hoc
random stuff and that's part of your
42:29workflow, it's going to be annoying
for your end user to self host because
42:32then you need to, like, send them
the instructions, they need to do it,
42:34they might, like, do it incorrectly.
42:36So, if everything is tracked
in code and is automated and is
42:39programmatic, It's good for your team.
42:41That's good for the end user.
42:43and for an end user, in terms of
what they should expect, if you are
42:46using some version of the cloud, you
should hope that the thing you're self
42:51hosting is taking advantage of as many
managed services as possible, right?
42:55So I had this issue with PostHog.
42:57So PostHog is an open
source analytics tool.
43:00And when I was exploring it for
my healthcare thing, I was like,
43:02okay, we'd have to self host it.
43:04Let me go look at the
first self hosting steps.
43:07Step one, set up Kubernetes.
43:09Right, immediately there, I'm like, I
like, found a way to finally free myself
43:14of Kubernetes for my main application.
43:16I don't want to like go, have to
go manage a Kubernetes cluster
43:19again, just for this thing.
43:21So you should hope that, you
should pick tools that use
43:25managed, versions of these things.
43:27That's why, like, we typically focus
a little bit more on some of the
43:31serverless stuff, because it's very easy.
43:33If our app just runs as a Lambda
function inside of someone's
43:37AWS account, or as a Cloudflare
worker, there's almost no overhead.
43:41You're not like, you don't have
to like set up like Datadog
43:44to like monitor the memory and
like scale this up, up and down.
43:47It sucks to do that for like a small
tool that you're adding to your project.
43:52So we try to make use of managed servers
as much as possible so that the end user
43:56doesn't have as much operational overhead.
43:59and again, some people
are willing to do that.
44:01It's just, uh, it's obviously a
spectrum with all of these things.
44:04I do think it's a double edged sword while
it like really takes away that operational
44:09burden and operational overhead.
44:11It's not just about, uh, deployment cycles
and like the update cycles of the app
44:17that you're deploying, you potentially
also need to update a, like from database
44:22version A to database version B of like
just a database server that's running or
44:26like your analytics server or whatever.
44:28So that certainly takes a lot more effort.
44:31However, on a longer time horizon,
if you do rely on managed services,
44:36they might just at some point send
out a notice and say like, Hey, next
44:40quarter We're shutting down like
that plan that you're relying on.
44:44So you're also in some regards
might be building on quicksand.
44:48I think the, the larger a services
such as Cloudflare, I think the
44:53chances that the rug is being pulled
underneath you are probably lower.
44:57But it's always a double edged sword.
44:59And so my preference typically is in
terms of the architecture that I'm using
45:05is like to go as simple as possible.
45:07This, for example, why I'm also very
drawn to SQLite and I love the, all
45:11of the, the new tooling being built
around SQLite since SQLite that's, no
45:16one's going to take that away from me.
45:17It's just like a little file.
45:19That I can put on a SD card or whatever.
45:22And, uh, that's still gonna like similar
to that computer game from like the 1980s.
45:28that's still gonna
work, in, in the future.
45:30And I think that's a great way
to preserve data and you can
45:33still do so much with that.
45:35So I think that's sort of like
a third option, uh, instead of
45:39going with like hosted or, Very
scary self hosted infrastructure.
45:44If you make the self hosted
infrastructure just that simple to
45:48rely on something like, like something
that's almost serverless by default,
45:53like SQLite, I think that's a,
that's a very attractive idea for me.
45:57Yeah, no, I agree.
45:58And with everything I'm saying,
it's always like you have
46:01to exercise your judgment.
46:02I'm speaking from the things that
I typically have worked on and
46:05I think this is where we landed.
46:06but yeah, if I was working on something
that had different requirements,
46:09like, yeah, having like the
simplest approach, uh, makes sense.
46:13The only reason that we have to do
this is because we work on stuff
46:17that is like one of our tools is.
46:20Like, uh, like issues, like,
kind of like how Sentry offers,
46:23like, issues that extracts.
46:24So we need to process, like, a
large amount of logs, uh, because
46:28some people have, like, you know,
like, billions of invocations a day.
46:31So it's not the type of thing that we
can really simplify, like, we can't
46:34just give you, like, a single container.
46:36And this, because that's going
to get overloaded very quickly.
46:38So the options for us are some
crazy Kubernetes thing, or we
46:42just take advantage of AWS Kinesis
and all these things that are
46:45built in that are lower overhead.
46:47Um, but, you know, if those
weren't my requirements, I would
46:49probably opt for something similar.
46:51And yeah, at the day, it always just
comes down to like, have good judgment.
46:55With whatever you're doing.
46:57Yeah.
46:57I think it's just as web developers, we're
just so like in, in our like dependency
47:04fury in a way where like, we just like
npm install this, npm install that, and
47:09we also not just package dependencies,
but we also like add infrastructure
47:14dependencies left and right to something,
I think is a big contributor, contributor.
47:19Why the long now aspect of local-first
software is so hard to achieve.
47:24So I'm always, uh, trying as hard
as possible to avoid dependencies,
47:29whether it's package dependencies
or whether it's like infrastructure
47:33dependencies as much as possible.
47:35But it's always a trade off
since they do sometimes can
47:38really save you a lot of time.
47:39Yeah.
47:40Yeah.
47:40I think for us, we kind of land
in this middle ground where
47:42we'll commit to one thing.
47:44But then we'll reject a
bunch of other things.
47:46So, there's this phenomena happening
right now, where, uh, you have these large
47:51cloud providers that offer these services.
47:53The services aren't like, The
best, most wonderful things to use.
47:58There's a bunch of companies that'll
like, make a copy of just that one
48:01service, but do it like 10 times better.
48:04It's often really compelling, and like
you, I can see why people are tempted
48:08to adopt every single one of these, and
people end up with a stack where it's
48:11like, It's my application and sitting on
top of like 10 different other vendors.
48:17And these 10 vendors are also startups,
you know, like it's unclear if they're
48:21going to be around for a while.
48:22So for us, we like as tempting as it is.
48:25And some of it has nice as some of these
offerings are like, we never use those.
48:28We just stick to the most lowest level
primitives that we can be sure are
48:32going to be around for a long time.
48:34And we'll commit to those.
48:35Like, we're going to accept
the fact that if something
48:37happens to them, we're screwed.
48:39More likely we're going
to die before they do.
48:40So that makes sense, but like, you know,
we won't, we won't apply that everywhere.
48:44So again, it just comes down to
like having the right judgment
48:46and picking things and low
dependency is very important.
48:50That makes a lot of sense.
48:52So you mentioned in terms of the
deployment cycle, also the update cycle
48:56of your application, and now in the.
48:59local-first way, there is, uh, primarily
you need to think about how do I
49:03update the local-first app itself?
49:06So some certain things are easy
to deploy, like a, a new component
49:10version of your UI that's, that's easy.
49:13But now that also all of your data
lives in the client, the schema of your
49:18data or like the shape of your data is
possibly also going to evolve over time.
49:22And there's different
ways to deal with that.
49:24So I'm curious how you've handled that.
49:26as well as possibly also the same
problem applied to your cloud component.
49:31Yeah.
49:31So in terms of the data locally, we've
never done anything sophisticated here.
49:35We've always just blown it all away.
49:36If we have to do some kind of severe
breaking change, we will just update like
49:41the big version number and the app will
erase everything locally and re sync.
49:46It's not a huge deal.
49:47It's never like massive amount of data.
49:49I think I can see a world where this
is, and already it's actually not
49:53too different than changing your
back end database schema because
49:56you have similar issues, right?
49:57Like you want to make backwards compatible
changes as much as you can because
50:01you don't want to have to like force
changes in your application code and
50:03force deployments of those together.
50:05So similarly, most of the time you
can do something backwards compatible.
50:09If you totally mess something up,
which obviously happens sometimes,
50:11yeah, we just blow it away.
50:13We haven't really found the need
to do anything more sophisticated
50:15in what we have, like.
50:17Migration scripts that
run locally or anything.
50:19I can see how that's a case for if you're
like running, I guess, if it's like end
50:23to end encrypted or something where you
can't really do that and the true state of
50:27the data is what's on the person's device.
50:30I can see how you have to like
think about that a little bit more.
50:32I think it kind of reminds me of
WhatsApp a little bit because like with
50:34WhatsApp, it feels like you're like
shuffling your data across your devices.
50:37You get a new device, you like
Move the data from one to another.
50:41So I imagine they deal with things
like this, but yeah, personally don't
50:44have a ton of experience with that.
50:46Yeah, I mean WhatsApp is also one
of the OG local-first apps that
50:51really like followed this pattern
out of necessity that defined
50:55why WhatsApp is so attractive.
50:57But I think the, the trade off that you've
landed on, I think makes a lot of sense.
51:01It's very pragmatic and given that you're
in this hybrid mode of like some parts of
51:06your app are cloud oriented, some parts
of your app are local-first, now you can
51:11also reap the benefits of the best of both
worlds that allows you to move quickly.
51:16I think if at some point you want to
move further on the local-first side.
51:19Spectrum, then I think maybe
you can't quite afford just
51:23blowing all the local data away.
51:24I'm kind of exploring some patterns in
that regard where I'm kind of keeping
51:29two versions of the data around locally.
51:32One version that is more
of like an event log.
51:35And one that is more of
like a typical app database.
51:39And the app database is just a projection
on aggregate from the event log.
51:44So I also get the benefits and luxury
of, in the case of a schema migration,
51:49I can just blow away the app DB.
51:51But instead of talking to the
server, I can just replay it locally.
51:55Sometimes takes a little bit of time,
but, uh, you get a lot of different
51:58options here that you can choose depending
on your requirements and how much time
52:03you can afford to put some effort into.
52:06Yeah, yeah, that makes sense.
52:07And what's interesting is this feels
very different, but it just kind of
52:11echoes the same things you do with
like a database in the back end.
52:15It's ultimately the same thing.
52:16It just happens to be that the
node of the database is running.
52:20In someone's machine, so you
end up with like almost all
52:22the same scenarios and options.
52:25Did you run into any situation where
you feel like, okay, this was really
52:30easier in the way how you've built
software in the past that's now
52:34like either currently harder with
local-first or like just categorically
52:39inherently harder with local-first?
52:42Well, it's really that one scenario
I talked about before where
52:45you do want to block the user.
52:46Since the default is inverted, whenever,
like you never, you never think like
52:51holding the user up until the backend
verifies something has happened.
52:5699 percent of developers would never
think about that as complicated.
52:58It's like, obviously, that's
like how everything works.
53:01But when you invert the default, that
becomes a little bit more challenging
53:04and Yeah, we just have to come up with,
like, certain patterns around, like, if
53:08you do an action, and a server rejects the
action, the natural s thing that'll happen
53:13is your state locally will revert to the
state it was at before you did the action.
53:18But that state has no record of
you trying to do the action, so
53:21the UI won't have like any error
or like information about this.
53:25So, doing an action where there was
an error on the backend and preserving
53:28that error, it just ends up being
more steps than it would be otherwise.
53:34But again, like we talked about, like this
is a minority of cases, so it doesn't come
53:37up, but it's just a funny thing where.
53:39Something so straightforward in
the traditional situation is like
53:43so weirdly complicated in this.
53:46So that's one thing that comes up.
53:47I think the second thing that comes up
is Kind of going back to this thing about
53:50like the doing migrations of data locally
or the schema changes, there's always
53:55a chance, and it's happened more when
I was earlier on in doing this stuff.
53:59So I think it was just me, like, not
doing stuff well, or like not having
54:03the right approach to certain things.
54:04But, um, Sometimes you would just end
up with, like, data that was bad and
54:09messing up the user's state locally.
54:12And with any other app, hitting refresh
means, start over, you're, like, rebooting
54:17your computer, you're, like, back to,
back to ground, like, back to zero.
54:21But with local-first, you might hit
refresh and the local data is still there.
54:24That's causing the bug, preventing, like,
you know, the fix from being applied.
54:28So, just like the, you lose the
ease of, like, wiping everything
54:32and there's no, like, built in user.
54:34Habits around like, oh, like,
let me try clearing my index
54:38DB and my browser, right?
54:39That's like not a thing
that anyone thinks about.
54:41So just like guarding those
things so you never end up in a
54:43state where it's unrecoverable.
54:46I think that's, that's for good.
54:47Again, it's usually handled on
a lower level, so you're not
54:49dealing with this constantly, but.
54:51It is a technical possibility.
54:53Yeah, I like that, uh,
that observation a lot.
54:56This is also something I'm
currently thinking a lot about.
54:59How can I make that
easier through LiveStore?
55:01Since I also, as working both on
LiveStore and Overtone, I do discover
55:07those behaviors, whether it's like
still me as a developer driving the
55:11user experience where it didn't pop open
the console and like throw away, like
55:16all the, the locally persisted data.
55:19But I can't expect an app
user to do the same thing.
55:22So I need to build like some sort of,
um, guards or some sort of detection
55:26of like, Hey, it seems like the app is
in sort of like a really tough spot.
55:31What should we do about this?
55:33Should we try to just like
delete a little bit of stuff
55:36that might cause the blockage?
55:39Or what should we do about that?
55:40And so where, where I'm currently at
is I think a mixture of user experience
55:45affordances, as well as technical
detections, whether something is
55:48wrong, I think transactions can help
with that in regards to the technical
55:53abilities, but then in terms of the
user experience, similar to like a
55:58React error boundary that you have to
detect whether something has gone wrong.
56:02I want to have a similar pattern that
allows you to, you know, Click a button
56:07that wipe everything, but it before
it does wipe everything, download
56:12a snapshot of your full database
that in case something catastrophic
56:16happens, you can, you still have that.
56:18You can hand that to an app developer
and you can also later re import
56:22your app state from there so
that you can go back where you've
56:26left off in case you wiped it.
56:28So those are like some, some primitives
and some, some patterns I'm exploring
56:32right now, but I'm, I'm excited
to see what other figures out.
56:36Yeah, that makes sense.
56:37It's also great that you're like,
building an actual thing with the tool.
56:43There's just like, no better
way to like, really understand
56:46what problems you need to solve.
56:48With SST, like, our
console is built with SST.
56:52So, any change we make comes
from problems we discover.
56:56The actual product that we're building.
56:57That's why it's so fun to work on like,
developer tools, because you are the user.
57:02So you're never like, how do
I get in the mind of a user?
57:05Like, that's, that problem isn't there.
57:07Like, you are the user.
57:08It's very easy to figure out what
problems there are, um, and discover that.
57:11You kind of skip that whole,
like, discovery process that
57:14usually needs to happen.
57:16So if you have someone who's
currently like, by default, building
57:20a new app with something like Next.
57:22js or Ruby on Rails, and they, they hear
about your story and now they're like
57:27curious about local-first, but they're
not quite sure where to get started.
57:31Do you have some tactical
suggestions for them?
57:34And also in terms of mindset,
what do they need to.
57:39switch in their brain, uh, that they're
successful and can hit the ground
57:43running in a local-first mindset.
57:46Yeah.
57:47You know, it's, I don't think I've
really thought about like, what's
57:50the right onboarding path for
people doing this type of thing.
57:54I'm like, I know the tools that I
use, like I said, we're, we're, we've
57:57centered around Replicache at this
point, but you know, local-first website
58:00obviously has a ton of other options.
58:03And there's a spectrum of like
what you care about and like how
58:05easy it is and how incremental you
can add it and things like that.
58:08But the mindset I think really is, it
really has nothing to do with local-first.
58:12And I think it's a good
mindset for everyone.
58:14I feel like there has been this shift
away from like caring about UX and
58:19almost, I feel like there's like a weird
proudness to like not caring about UX,
58:22which I think is fundamentally wrong.
58:24And what I mean by that is.
58:26There's a whole meme of like, Oh, if
you did this, you shipped too late.
58:29Or like people are proud
of like shipping bad stuff.
58:32Cause they're signaling that
like, I'm just someone that
58:35like tries to get stuff done.
58:37I'm not like wasting time on stupid stuff,
which the Linear people had a great write
58:43up about this and it's this whole concept
around the idea of an MVP is stupid and
58:48it's been stupid for a while, but for
some reason, people haven't realized this.
58:52I definitely will acknowledge maybe
back when I was starting out, like
58:55in the startup world, like, I guess
it's been like 10 or 11 years, things
58:59were definitely different back then
where there wasn't a lot of software.
59:02So anything was better than nothing.
59:05So you could really ship something pretty
quick and like get validation and move on.
59:09It's like that whole like mindset
kind of made sense back then.
59:12But it hasn't been that
way in a long time.
59:14So many people ship like something
they built in a week and they're
59:17like, Oh, it didn't work.
59:18Let me move on to the next thing.
59:19To be honest, nothing good can
really be shipped that fast.
59:23It's just not possible.
59:25Uh, and you really need to have a strong
sense of here's a problem I'm solving.
59:30I have good taste around it.
59:31I'm going to put in a lot of effort
and make a really great experience.
59:36And.
59:37Whether or not my idea is going
to work, you can't know that
59:41until you've hit that bar.
59:43And as a Linear people wrote up a whole
thing about this on like, we're so
59:47obsessed with these like little tiny MVPs.
59:50And that's like the weird default
that we're all like kind of
59:52proud to say that we follow that.
59:54Um, and the mindset shift is with
local-first, it's getting easier all
59:59the time, but it's going to be a lot
harder than a lot of things that you've
1:00:03done before because you have so much
time to focus on these little details.
1:00:08And you really have to focus on details.
1:00:09You have to enjoy Letting them and
caring about them and making that
1:00:14feel good because that's what that's
where the bar is now, whether people
1:00:17realize it or not, the fact is Linear,
Linear exists now that it exists.
1:00:23How can you possibly ship
anything not at that level?
1:00:26Right?
1:00:26How, like, sure, in the short term,
I'm sure you can, but the long term,
1:00:29obviously that becomes a new bar.
1:00:32So, for me, the mindset shift is like,
there is a new bar go use products that
1:00:36are like this, like, Linear is one, like,
superhuman is like a smaller example.
1:00:40of stuff that's kind of gotten bigger.
1:00:42That is the bar, and you have
to accept that that is a bar.
1:00:45And if you really accept that,
then you'll be motivated to like
1:00:48go and figure out all this stuff.
1:00:50Yeah, it's quite different from where
I think the mindset is currently.
1:00:54I think you've very succinctly
Summarized my last two and a
1:00:58half years working on Overtone.
1:01:00I'm exactly inspired by that high bar.
1:01:03Sometimes I might even raise it a bit
higher just for, for the challenge, but
1:01:08it's so fun to see like all of those
details just compounding and, and I
1:01:13like much smoother product experience.
1:01:15And, uh, yeah, I love the the
blog posts that you've pointed
1:01:19out from the, the Linear blog.
1:01:21And I think the only exception really
to where the bar needs to be higher is
1:01:25like for just categorically new things.
1:01:28Maybe an exception here is like
AI products, uh, like AI products.
1:01:32There is no, no prior version to that.
1:01:34So maybe it is really speed that,
that matters most, but I think
1:01:38for every software that replaces
something that was there before.
1:01:43I think it's, you have to
really, really care about craft.
1:01:46Um, Arc is another example as like
to really innovate on a browser.
1:01:52Like the browser is still the same,
what it is before, but now it's
1:01:55like all the compound effect of all
of like getting the details right.
1:02:00And that really, that really excites me.
1:02:02So thank you so much for
that wonderful summary.
1:02:05Yeah.
1:02:05And there's so much
opportunity to do this.
1:02:07Like I'm unhappy with so much of
the things that I use every day.
1:02:10So yeah, I just want more people to get
excited about doing this type of thing.
1:02:14Thank you so much.
1:02:15This has been really, really fun.
1:02:17Thank you so much for coming on.
1:02:19Yeah, appreciate having me.
1:02:20I, I, it was good.
1:02:21I actually don't get to get
into some of these details.
1:02:24I don't, I've actually never gotten
a lot of these details before.
1:02:26So yeah, it was great.
1:02:27Thank you for listening to
the localfirst.fm podcast.
1:02:30If you've enjoyed this episode and haven't
done so already, please subscribe and
1:02:34leave a review wherever you're listening.
1:02:36Please also tell your friends about it.
1:02:37If you think they could be interested
in local-first, if you have feedback,
1:02:41questions or ideas for the podcast,
please get in touch via hello at
1:02:45localfirst.fm or use the feedback form on
our website, special thanks to Expo and
1:02:50Crab Nebula for supporting this podcast.
1:02:53See you next time.