00:00isn't it really complicated
to build web apps?
00:02What if it was just way simpler to build
an awesome app that was fast, that was
00:06really responsive, that stored all the
data people care about, was easier for
00:10you to develop faster, simpler, less
ops maintenance stuff The data ownership
00:14stuff just falls out as a consequence.
00:16Could we leverage the power of
databases and the power of local-first
00:21architecture to cut through a
lot of the complexity of building
00:24modern web apps and make it simpler.
00:26Welcome to the localfirst.fm podcast.
00:29I'm your host, Johannes Schickling,
and I'm a web developer, a
00:32startup founder, And love the
craft of software engineering.
00:35For the past few years, I've been on a
journey to build a modern, high quality
00:39music app using web technologies.
00:41And in doing so, I've been falling down
the rabbit hole of local-first software.
00:46This podcast is your invitation
to join me on that journey.
00:50In this episode, I'm speaking to
Geoffrey Litt, who's currently
00:53a researcher at Ink and Switch.
00:55Geoffrey has worked on many
interesting research projects such
00:58as Riffle, Cambria, and Embark.
01:01In our conversation today, we're
talking about the ideas and goals
01:04that motivated Riffle, Which include
expressing an app as a query, fast
01:09synchronous reactivity, and unifying UI
state and app data in a single system.
01:15Before getting started, also a
big thank you to Expo and Crab
01:18Nebula for supporting this podcast.
01:21And now my interview with Geoffrey.
01:23Welcome, Geoffrey, to the show.
01:25So excited to have you.
01:26Thanks.
01:26It's great to be here.
01:28I mean, you and I have been working
together now for a few years, But let's
01:32rewind time a little bit and maybe start
where you and I have first crossed paths.
01:38This was, I think the end of 2020
and you've been just wrapping
01:42up your first project at Ink and
Switch, which was about Cambria.
01:46So would you mind, motivating
what the project was about?
01:51Yeah.
01:51Absolutely.
01:51So, I'm a researcher that works on a topic
called malleable software, where the idea
01:57is, can we let everybody customize their
software tools to meet their own personal
02:02needs rather than everybody changing
the way they work to match standardized
02:07software tools that other people develop.
02:09Right?
02:09turns out one of the core problems in
this space is wrangling data schemas.
02:15So imagine, you know, you're using
your favorite to do app, I'm using
02:18my favorite to do app, and we decide
we wanna work on a project together.
02:22What are the options?
02:23We either have to pick the same to do
app, or if we wanna each keep using
02:27our own favorite to do app, those apps
need to have some way of talking to one
02:30another and sharing a data representation.
02:33Right?
02:34it turns out that this is a pretty
gnarly problem because those data
02:38representations our 2 apps wanna use
might be different in subtle ways.
02:42You know?
02:43Perhaps your app has subtasks and
mine doesn't or something like that.
02:47And so the goal of Cambria was to
explore this problem and try to figure
02:51out, could we find a way to enable
collaboration across diverse tools,
02:55while also not requiring all of our
tools to share exactly the same data
02:59schema and all agree on everything.
03:00And It turns out that this is
actually sort of a pervasive problem
03:05across local-first software in
a bunch of different contexts.
03:08This problem pops up in
many shapes and forms.
03:11Even the simple case of, like, having
a centralized application written by
03:14one developer in a local-first context
schema migrations And upgrades often
03:19become a lot harder than they are in
sort of a server based environment.
03:23So, the Cambria project again was about
sort of First, just recognizing that
03:28this problem exists everywhere and
that it's really holds back progress
03:32in terms of interoperability and schema
management and local-first steps.
03:37And then we sort of prototyped a solution
to it, which was you can think of it
03:41sort of as a live data translation
system where as different tools are
03:45working on shared data, there's a layer
underneath the individual tools that
03:49helps translate data formats between
all the various tools in such a way that
03:53each app can feel like it's just working
with the data representation it wants.
03:57But, actually, under the hood where
we have some sort of translation layer
04:01that's, you know, sort of serving
as the glue that lets different
04:05versions of the same app collaborate
or lets even different apps entirely
04:08collaborate with one another.
04:10Yeah.
04:11I think that's a brilliant motivation.
04:13I remember, like, having read the
essay the first time was super well
04:18illustrated and super well motivated.
04:21It sort of almost provoked me
into reimplementing a version
04:26of Cambria myself back then.
04:28This is how much it's it kinda spoke
to me since I remember that the
04:31first version of Cambria was an sort
of like a DSL expressed in YAML.
04:36I am more someone who's working mostly in
TypeScript, so I remember reimplementing
04:41a small version in TypeScript.
04:43So, yeah, I love that problem statement.
04:46And so I think it's also interesting
how it fits into this broader
04:50umbrella of malleable software.
04:52and turns out, Looking back over
the last few years, this is not
04:56the only project you've done in
the realm of malleable software.
05:00So which other problem spaces
have you run into while pursuing
05:04this goal of malleable software.
05:07Yeah.
05:07I think it's a fascinating space.
05:09You know?
05:10The way I got into it was originally
it was actually I was working at a
05:13start up building normal SaaS software.
05:16And you know, we were doing what
SaaS companies do, which is that you
05:19have 30 people in a room somewhere,
designing interfaces that thousands
05:24and thousands of people, thousands
of miles away are supposed to use.
05:27Right?
05:28We were, in our case, designing
education software for schools.
05:31I just remember talking to all these
teachers and principals and all these
05:34different schools, and they had very
specific requests often as customers do.
05:39And, of course in SaaS,
typically, the answer is no.
05:42You have to be disciplined and
say, I can't change the wording
05:46of that button just for you.
05:48I'm not gonna add a setting for that.
05:50But I started to find this
very frustrating and wanted to
05:53explore what would it feel like
if software worked differently.
05:57And, you know, I think there's an
interesting connection to local-first
06:00because I remember coming across
the original Ink & Switch essay
06:04about local-first when I was
starting to think about this stuff.
06:07And I think they said briefly in
the essay something about how It
06:12seems like an intriguing foundation
if you have data locally and
06:15maybe even code locally available.
06:17That gives you a little bit more access
and control over your software than
06:21if You have a cloud SaaS architecture.
06:23And that sentence really sort of sparked
a bunch of thoughts in my brain that
06:28have led you know, I think a lot of my
work, the way I see it is sort of at
06:31the intersection of how do we use the
local-first architecture to enable more
06:36malleable software for end users is a
theme that I care a lot So Cambria was
06:39definitely one project in that line.
06:41I've worked on a couple
other projects in this space.
06:46one project I worked on early in my
grad school research career was a little
06:51browser extension called Wildcard.
06:53And the idea was what if you could
access the data underneath any web
06:58page in a spreadsheet uh, but it's
not only a read only spreadsheet.
07:01You could even write to the
spreadsheet and mod it yourself.
07:04So a very accessible way for normal
people to make their own browser
07:08extensions without programming.
07:10I love that.
07:11And I think as a fun fact, this might
have actually been the very first
07:16point where we've been put in touch.
07:18Because at that time, I was also
working on my little own Chrome
07:22extension, which was also kinda in
a direction of malleable software.
07:26This was before I was even aware of
the term and, like, that broader field.
07:31I was just motivated by my own frustration
that I could that the websites didn't
07:37quite work the way how I intended.
07:39So it just feels like we've been
on similar paths there, And what
07:43you've been building with Wildcard
was quite a step ahead of what I've
07:48been coming up with at that point.
07:50But yeah,
07:51Well, yeah, I, you know, I remember
one thing about that that I think
07:54maybe is a preview of the way we've
collaborated since then is that mine
07:57was a more speculative prototype of
a interface design, but it wasn't
08:02particularly solidly implemented.
08:04And I remember you had this really,
fancy developer experience around
08:08customizing your extensions and
stuff that I got inspired by.
08:11And so I think There's a fun
interplay there we can get into
08:15later about kind of more speculative
research versus engineering
08:18more solid versions of the idea.
08:21Yeah.
08:21So you've been working on on Wildcard.
08:24Which are the results that come out of
your your overall research in that field?
08:30Yeah.
08:30So, you know, throughout the years,
I've had the chance to work on
08:34A bunch of projects with mostly
with really awesome collaborators.
08:38one of the more recent projects which
I we actually worked on together, was
08:42the the last project I worked on in
grad school, which is called Riffle.
08:46And that was a project that you and I
worked on together with, Nicholas Schiefer
08:51and Daniel Jackson, my PhD advisor at MIT.
08:54And sort of the, I guess, the origin
story of Riffle, is that Nicholas and
08:59I were having a bunch of conversations
that revolved around sort of this
09:02idea of having a personal data store.
09:05So, one way I think about cloud
versus local-first is that in
09:10local-first software, one of the
ideals is that you own your data.
09:13these valuable thoughts that I'm having
and artifacts that I'm producing in the
09:16digital world, they should feel like mine,
just like a notebook I can carry around
09:21and, you know, have with me forever.
09:23Right?
09:23And There's this question of great.
09:26If you own your data sure, you
get longevity and control, but
09:30what about this ability to take
arbitrary tools that I wanna use and
09:35connect them to that personal data.
09:37This is something that's often really hard
in SaaS because the data's locked away.
09:40And maybe there's the APIs you
want and maybe there's not.
09:43And maybe there's the partnership
you want between the 2 tools
09:46you use, but maybe not.
09:47And we were talking about, you know, how
would it feel if you had a local-first
09:50data store with all your stuff in it
And you could connect whatever app
09:54or tool you wanted to that existing
data store that has all your stuff.
09:57Right?
09:58Um, what shape would that data store take?
10:00How would it work?
10:01How would you develop against it?
10:03And one hypothesis we wanted to explore,
particularly because of Nicholas's
10:07background, which is in databases, we
wanted to sort of ask this question of
10:11what if you had a really powerful database
that was designed for this purpose?
10:15Maybe it could be based
on relational databases.
10:19And maybe the experience of building
an app in that foundation could end up
10:24feeling really different from traditional
software development in a bunch of ways.
10:27So that's kind of how we
got into the Riffle work.
10:31That that's incredible.
10:32And if I remember correctly, This
was not the first time that Nicholas
10:37was also working on on this field.
10:39He didn't just work on on databases,
but I think he was at at Apple
10:43previously and was implementing
similar systems, I think, related to
10:48to iCloud and how syncing works there.
10:51So yeah.
10:52I mean, those are some pretty big ideals,
10:54That is not a very common thing
in the apps that that I'm using.
10:58It's, if, God forbid, something
like Notion would shut down.
11:01Like, what what would even
happen to to to my data?
11:05So I would love to see that flip of,
like, Everything that I'm creatively
11:10producing is by default mine
and turn around the relationship.
11:15But Uh, it's not even that you wanted
to, from a idealistic perspective,
11:20push for that, but I think you
took a step back and say, okay.
11:24What is even the technical
foundation for that?
11:27What would a prototype of that look like?
11:29How did the project get off the ground?
11:31Yeah.
11:32So one way that I think about
this is exactly the way you put
11:34it about the difference between
ideology and technical foundations.
11:37I think that data ownership, one of
the reasons we don't have it is because
11:41it's hard to build apps that way.
11:43It's not I think there are often
companies that don't really have a
11:47strong desire to build a SaaS data moat.
11:50It just is kind of the default
that is promoted by the way
11:53we naturally build stuff.
11:55And because it's so hard to
build apps with data ownership,
11:57we don't get that many of them.
11:59And one of the I think most interesting
potentials of local-first as an area that
12:04I don't think has been fully realized
yet is what if we could make it easier to
12:08build apps this way rather than harder?
12:10Right?
12:10I think a lot of people in this space
see that potential for this Radical
12:14simplification of how we build stuff.
12:16I think Peter, who was on the show
see, you know, has sort of, Inspired
12:21a lot of my thinking on that.
12:22I think Martin Kleppmann, who was one of
the coauthors of the local-first piece,
12:25has given talks about how you sort of have
this, uh, many layered cloud architecture.
12:30And in theory, it could be so
much simpler if you didn't have
12:33to deal with all that stuff.
12:35But, again, in practice, I think we're
still getting there as a community,
12:39and the reality is we're still maybe
in the zone where it's harder today.
12:42And so, You know, one of the ways that
I thought about the Riffle project and,
12:46you know, Nicholas and I and Daniel
thought about it was what if the pitch
12:49to an app developer for something like
Riffle didn't start from ideology.
12:53It didn't start from you care about
giving your users their data and providing
12:58interoperability, blah blah blah.
12:59The reality is for many people, these
are not the most pressing concerns.
13:03What if we started instead from, hey.
13:05Isn't it really complicated
to build web apps?
13:08What if it was just way simpler to build
an awesome app that was fast, that was
13:12really responsive, that stored all the
data people care about, was easier for
13:16you to develop faster, simpler, less
ops maintenance stuff The data ownership
13:20stuff just falls out as a consequence.
13:22Right?
13:22So a lot of our Riffle work was
focused on, could we leverage the
13:28power of databases and the power of the
local-first architecture to cut through
13:34a lot of the complexity of building
modern web apps and make it simpler.
13:37And in service of that mission, a
few of our starting principles were
13:41can you think of an application
as one giant database Query.
13:45What I mean by that is instead of writing
a ton of normal code that produces
13:49your UI, could you somehow push a lot
of the work into a optimized database
13:54that does a lot of heavy lifting and
let it produce UI states for you.
14:00Another thing that couples really well
with that is fast synchronous reactivity.
14:04So we have this idea that the
data's already there on your device.
14:08Throw away all the async crap that
comes with web apps typically.
14:12You know, React suspend network
requests and work with the data
14:16that's already there and simplify
just talking to it and querying it.
14:20And the last thing, our third principle
was Can we take all these different
14:25kinds of state that typically end up in
different systems and throw them in one?
14:29So your React UI state and your
persistent local device local state
14:33and your synchronized multi user state.
14:35Can you just store them in one system?
14:37And then You know, we like to think
of it as maybe there's some setting
14:40checkboxes on each bit of state
that tell you should you share it or
14:43whatever, but just have one system that's
capable of subsuming all those roles.
14:48And our hypothesis was that if you
pulled all this off, it could feel really
14:51awesome to build apps, and you would get
Both better apps for end users because
14:57they're fast and they work offline and
they have all the local-first goodness.
15:00But also you could get a better developer
experience because you've removed a lot
15:04of the layers of of traditional web apps.
15:06So this was a lot.
15:08And spoiler alert, that hypothesis
that you've motivated, at least
15:12in my very case paid off big time.
15:15So the developer experience for
me as a developer is better.
15:19I hope that the end user experience
will be better partially also
15:23because I care a lot about
performance and making things nice.
15:27But to crack the chicken egg problem
of, like, how do you even build better
15:33apps with this in the first place?
15:35What really was the the motivation
and the the catalyst for me was
15:40not all the ideals of local-first.
15:42Sure.
15:42I would love them, but that would
not really make the difference for
15:46me, like, start to work on an app and
build in one architecture or another.
15:50But the more Things I didn't have to
do in the first place, the better.
15:54The more I could really
focus on working on the app.
15:58And Just to simplify the entire stack
your motivation to say, like, hey.
16:04Actually, why do you even need a server?
16:06Why do you need a back end for the thing?
16:08Ultimately, the app is is
working on your client.
16:11How about that being the starting point?
16:13That really spoke to me, and this
drew me in as an app developer and
16:18where I believe in in that mission.
16:21So, yeah, I I couldn't agree more, and I
would love to dig more into the various
16:28principles that you've mentioned since
I think there's quite a bit of, like,
16:31interesting thinking behind each of those.
16:34If I recap it correctly, I think it
was simplifying the inner workings of
16:39an app into Uh, basically, database
queries, aka, like, complex SQL queries
16:44or however else you wanna express it
than the the synchronous uh, uh, graph
16:49of typically how React works, etcetera,
coupling that directly together.
16:55And the third part oh, you gotta
remind me about the third part again.
16:59But let's let's go through them, like, one
by one again and with a bit more detail.
17:04Absolutely.
17:04So, you know, the first principle
I talked about is thinking of an
17:08application as a database query.
17:10Right?
17:10And, actually, to throw a
little more detail in there,
17:13it's not one database query.
17:15It's actually a graph of database
queries with dependencies.
17:17Now that starts to sound kind of
fancy, but I think we all understand
17:21this model from using spreadsheets.
17:23The the metaphor, I think, to
think about is can You make coding
17:27a rich, complex application as
simple as using a spreadsheet.
17:32Spreadsheets dependency tracking
of formulas and automatic
17:36Dependency propagation is the
bread and butter of spreadsheets.
17:38It's one of the key features
that makes them useful.
17:41Right?
17:41When you're using a spreadsheet
and you update a cell, The contract
17:44that Excel gives you is typically
instantly or at least very quickly,
17:48unless you're in a huge spreadsheet,
everything will be up to date.
17:51You're never worried about staleness.
17:53You're never thinking about caching.
17:55That complexity of dependency propagation
is pushed down into the system.
17:59Right?
18:00And I would note, I think this
is a lesson that we've definitely
18:03learned in UI development.
18:05You could definitely say that reactive
UI frameworks like, React JS give
18:10you something like this guarantee.
18:12Right?
18:12They you declare the UI you want and
state and DOM are synced automatically.
18:18The problem that I see is that often
in our web stacks, this reactivity
18:22is partial to one part of the stack.
18:25So in in a common web application,
your React UI, what it's
18:29faithfully representing is not
all the state in your system.
18:33It's some view you currently have in
this tab of some larger state that is,
18:38you know, maybe primarily on a server.
18:41And that introduces a lot of complexity
because all of a sudden, you have
18:44your nice declarative spreadsheety
React thing, but then you have At
18:48some point in your stack, you're
gonna start hitting data fetching.
18:51You're gonna start hitting sending
rights back up to the server.
18:55And, that's just an enormous source
of mental model overhead, I think.
19:00On the flip side there have been some
interesting research projects which come
19:03out from the other side, And people,
for example, have literally tried to
19:06make UIs in things like Google Sheets.
19:09There's a really neat project by Ted
Benson and collaborators called Quiltstep.
19:13Literally, they use Google Sheets to power
your entire back end and all your your,
19:18you know, UI templating and essentially.
19:20And the problem there is normal
spreadsheets aren't really powerful
19:23enough to do that, and they're not
really architected the right way.
19:27one way to think about what we're
trying to do in Riffle is can you take
19:30the beautifully simple model of just
declarative dependency propagation, and
19:35apply that to your entire data stack.
19:38So your mental model as developer should
be, I just have all the data locally.
19:42I'm just writing a spreadsheet
that turns it into a UI, and the
19:47system will take care of the rest.
19:48Full stack reactivity.
19:50That's sort of principle number one.
19:52That makes that makes total sense.
19:54And I think you've Touched on also, like,
the the third principle, which I remember
19:58now is, like, the the unifying the UI
states and sort of the the other app data.
20:03And if you really think about it, where do
you even draw the line between something
20:07being UI state, something being app data?
20:10There is sort of like a arbitrary line.
20:12Maybe I think de facto in most today's
web apps is the app data is, like,
20:17what you fetch over something like
React Query as your as your website
20:22boots up or you have it pre hydrated.
20:25And the app state It's more of like
the in memory stuff that if you
20:29reload the pages, poof, it's gone.
20:32But, ideally, most of the things should
really be treated in a very similar
20:36way when I'm thinking of a native
Mac app, for example, like Finder.
20:41If I close a window and I come back,
The same items are still selected.
20:46I'm still, like, roughly in the the
same position with the the folders that
20:51I've selected and and the hierarchy.
20:53And most web apps, I would actually
suffer from that they they have, like
20:58basically, they're suffering from
dementia when you and insert something
21:02in a form, and maybe you really need to
look up every value and maybe the form
21:08expires, you reload, everything is gone.
21:10That's I think everyone has, like,
those terrible user experiences.
21:14And so treating everything as the
same data, I think is is a kind
21:19of a bold, but in my experience,
like, the the right step.
21:23And then if you can, Therefore, as a
conclusion, kind of, like, have all
21:28the data that you need to work with.
21:30Have that locally.
21:31It simplifies everything to such
a degree that's really liberating.
21:36So that that's sort of the the third the
principle, and I think that's that's a
21:40really bold one that is, I think the most
provocative compared to the traditional
21:45way of building web apps today.
21:48Yeah.
21:48Exactly.
21:48You know, just like you said I think it
can be a disrespectful user experience
21:52to lose people's valuable input.
21:55Even something like Scroll position
or, like you said, intermediate
21:59form state can be thing something
that I put a lot of work into and
22:03I don't wanna necessarily lose.
22:04Right?
22:05Now I think the deeper reason we
end up with software like this
22:10isn't that people don't care.
22:11It's really that we've made it hard to do.
22:14So, again, it's this technical
defaults ruling, the user experience
22:18situation that we talked about where,
You know, imagine you're a product
22:22manager and you get a request to
please persist to this user input or
22:26share this user input across users.
22:28And the engineer says, oh, man.
22:30That was previously React components
data, and now I need to, like, rearchitect
22:34where that data is stored and plummet
through a bunch of places and Add a
22:38database column for it, blah blah blah.
22:40It's all this work.
22:42And the goal of having a
unified system for your state.
22:44It's not that all states
should be treated the same.
22:47Definitely, some state, you know, should
be user local, device local, and so on.
22:51There, Yeah.
22:52Some state you want to reset
on new sessions by default.
22:56So you can think of that as ephemeral.
22:58But If you store it all in one system
and manage it all in one system,
23:02the goal is that it's becomes much
easier to move between, these states.
23:06Right?
23:07one example I love is that someone
who's working on a collaborative app
23:10told me the state of whether a context
menu is open in a spatial canvas app.
23:17They actually realized they needed
it to be shared because when I open a
23:21context menu, my cursor is moving around.
23:22If you can't see the context
you I'm using, you don't
23:25really know what I'm doing.
23:27And so, I think that's a perfect
example of blurring these boundaries
23:30where something that Seems like clearly
quote, unquote, local component state
23:35in a traditional framing might actually
need to be collaboratively synced
23:40or, you know, maybe even persisted.
23:42So that's what I see as the goal of having
this unified state management system.
23:47And in the Riffle work that's
basically the the maximalist
23:50view we took is no react state.
23:52Right?
23:53Every single bit of state in the system
flows through this one database, and your
23:58UI is just derived from that one place.
24:01And You can always reason about
essentially, the pixels on the screen
24:05are a function of the database.
24:07That's it.
24:07Nothing else.
24:08And we found a lot of neat qualities
that that design led to along with
24:13a bunch of interesting challenges.
24:15And and I have to say, I was I was not
on board with that when we got started.
24:20I was so attached to like, everything
is in React, and you have, like, things
24:26inside of React components, etcetera.
24:28And I remember Nicholas, he was, like,
on the on the opposite side there.
24:33And so, like, no.
24:34No.
24:34No.
24:34Like, React should do as little
as possible and, like, have your
24:37state outside, and that didn't
click quite back then for me.
24:42But step by step, I came around
to it, and I'm now also, like, on
24:46a maximalist side of, like, most
state should live outside of React.
24:50And for example, for Overtone,
there's a very simple case where
24:54you for example, for the app
for the playback of your player.
24:58Like, you want your playback
to happen to happen.
25:01You wanna hear something.
25:02Maybe you captured the the time code
of the the current playback progress.
25:07And even if the app is not open,
You wanna still hear things.
25:12If you reload the app you might
just still want to recover at the
25:16the correct playback position.
25:18So all of that state is kinda headless.
25:20So the state still lives on and,
therefore wouldn't quite make sense to
25:25have that be part of React, you say.
25:27Sure.
25:27You could say you have, like, a headless
React component, but that's already
25:32feels a bit backwards at that point.
25:34So Once I've started embracing that,
it was hugely liberating, and now I can
25:40start to reason about my state outside
of the context of React components in
25:46that outside of reactive view state.
25:49So That took me a bit to get
around to it, but I'm fully on board
25:53with that principle now as well.
25:55you know, I'll I'll mention, I
don't think we're the we're not
25:57the only ones who've of this right.
25:58I think um, the idea of having a
reactive state graph separate from
26:02your UI tree is something that other
web dev libraries have explored.
26:07MobX, Recoil, arguably, even something
like Redux, I think shows some of the
26:11power of having this sort of centralized,
outside of your UI tree state management.
26:16So, there's definitely, I think
some broad recognition that this
26:21can be a powerful pattern for for
some of the reasons you mentioned.
26:25You know, but I'll also mention,
like, there are some challenges.
26:27Right?
26:27And, I mean, You've
encountered some of these.
26:29I'd be curious to hear your take.
26:30Some of them that I think immediately
come to mind for people are, one,
26:35Performance is always an easy one.
26:37Like, typically, we expect button
hovers and, you know, selection
26:42changes to happen at 60 120 Hertz.
26:45And we don't expect things like
loading thousands of rows of
26:50data from our core data store to
necessarily happen at the same speed.
26:54And so that mismatch can be an an
an interesting thing to Manage.
27:00Our motto Nicholas's motto to some
extent is just make everything fast.
27:03If everything goes at 120 FPS,
then don't have a problem.
27:06Right?
27:07Easier said than done, but I
think a fun goal to shoot for.
27:11So far, most mostly what
we've been talking about is
27:13conceptually a simplification.
27:16Getting on board with that
different way of thinking about
27:19your your app on a conceptual basis.
27:21And I think for me, it took a little
bit of time to ease into that,
27:26and then, be confronted with the
new challenges that are raising.
27:29We we'll we'll go into the
challenges in a second since
27:32We've encountered quite a few.
27:34But I think we didn't quite touch too
much on the the second principle you've
27:38motivated before, which is, uh, the
synchronous reactivity, and, like,
27:43that should be as fast as possible.
27:45We'll we'll go into the performance
challenges there in a bit.
27:48But when you've said synchronous
reactivity as opposed to
27:54asynchronous reactivity, what what
are the why is this a principle.
27:58Like, what is so important?
27:59Can can you motivate the the
problem and the status quo and
28:02how Riffle is challenging that?
28:04. Yeah.
28:05Absolutely.
28:05This is a really
important principle to me.
28:08I think when we Build web
apps that have a server.
28:11We assume a lot of
asynchrony at many points.
28:15So, obviously, going on the network
to a server is a point of asynchrony.
28:19Even often loading data from
you know, like a local disk.
28:23Right?
28:23We think of as an asynchronous operation.
28:25And because of that, UI development
typically has a lot of reasoning
28:30about asynchrony, which is a really
hard thing to do as a programmer.
28:34For example, you might have a UI
where There are loading states.
28:38And everywhere throughout your app,
you need to think about, am I still
28:42loading, or do I have the data?
28:43And maybe you have a UI that's composed
of different sections, and some of them
28:47might be loaded already and others aren't.
28:49You might have intermediate
states to reason about.
28:51Like, After I select something
in a sidebar, there's some time
28:55where the main other pane of the
app hasn't reacted to that yet.
28:59So It might still be showing the old
thing that was there before I selected
29:02the new thing, or it might be showing a
loading state while I'm loading the data.
29:06And my experience at least personally
has been that We kind of accept
29:10this as just the way it is in UI
development, but it's terrible.
29:13It's it's a lot of
overhead to reason about.
29:16There are many, many more states your
system can be in when you have asynchrony.
29:21Right?
29:21And the the vision for synchronous
reactivity is let's make it again
29:25feel more like a spreadsheet.
29:26So the way I want my UI to feel is
that when I select something, on the
29:31next tick, on the next frame, every
pixel in the UI has fully updated
29:35to reflect that new user input.
29:38And that's obviously good for users
because they didn't have to wait
29:42But it's also good for developers
because you don't have to reason
29:43about the intermediate states.
29:46You can sort of think transactionally
where The state of the world changes,
29:50and, transactionally, we update a bunch
of derived views and queries of that state
29:56which end up in the pixels of the UI.
29:58And there was never any
intermediate state exposed.
30:01And it's It's sort of a subtle point to
get across, but my experience has been
30:06that when you work in a system like
this it just Cuts a lot of complexity.
30:11Yeah.
30:11It's not just a simplification in
terms of architecture that we collapse
30:16the stack from back end and API,
etcetera, and all into the client.
30:21But that's, like, one giant
dimension of complexity.
30:26But there is a second, much less
talked about vector of complexity,
30:31which is like, how is how are
things related to each other?
30:34Can they be synchronously
related or can or do they have
30:38to be asynchronously related?
30:41And this is where I think we're getting
into the area of distributed systems.
30:45I'm sure we'll talk a lot more in future
episodes about broader distributed
30:50systems where they're really needed,
where you have You're you have a device.
30:54You're in the US.
30:55I'm in Europe, and so we are distributed.
30:57However, if we are starting to
treat a local React app that's
31:01running in single thread And we're
coordinating the various React use
31:06states things with React useEffect.
31:08We've kinda accidentally created a
distributed system that's It's really hard
31:13to tame and where it is, there can be many
unintended bugs and just starts becoming
31:19a lot more complex to to think about.
31:22So this is the other part where I
think it really it con where Riffle,
31:27again, liberates so much and simplifies
and frees us of the the accidental
31:33distributed systems problem that
we have in most modern web apps.
31:37I, you know, I, think to 2 principles
that I think about one is don't
31:43make something a distributed system
if it really doesn't have to be.
31:47And 2 is if it has to be,
someone smarter than me should
31:51do the distributed systems part.
31:53Right.
31:53Really, we should be providing
abstractions that allow us to not think
31:58about the hard parts most of the time.
32:01Even, you know, I'm not a CRDT expert,
but I know quite a bit about CRDTs and
32:05have done some work on developing CRDTs.
32:07But and so I, you know, I Probably
know more about CRTs than a lot of
32:11app devs, but I don't wanna think
about distributed systems when
32:15I'm building some product feature.
32:17Right?
32:17And I think That is clearly one of the
core challenges in the local-first space
32:21that I think a number of projects and
companies are trying to address, which
32:25is what are the Good abstractions you
can expose to app developers that allow
32:29them to reason about tricky distributed
systems problems in a in a straightforward
32:36way without needing to turn on your sort
of distributed systems brain as much.
32:42Yeah.
32:42Exactly.
32:42And I I think the Being confronted with
distributed systems problems there is
32:48much more common than most app devs think.
32:52So most of the time when in React, you use
useEffect that that hook to, yeah, somehow
32:59tame your local state, Then you already
have a distributed systems problem.
33:04Things like React suspense and and so on.
33:07That that's kind of like a a solution
to address partially the the distributed
33:12systems nature that you have in React.
33:14So, I remember having when React suspense,
and all of those primitives came out.
33:19I was kinda wondering, how does
that fit into our Riffle world here?
33:24would Riffle at some point support
react suspense, and then at
33:28some point, it clicked for me.
33:30No.
33:30That's, like, addressing a problem
that we've already ruled out
33:34before, and we don't even have to
think about that complexity at all.
33:39And yeah, this is, like, entirely
different approach to addressing
33:44the problems that React, Suspense,
etcetera, is addressing in a, I would
33:49say, in a much simpler overall picture.
33:52Yeah.
33:52I think maybe to avoid overclaiming
here, I'll say there are some trade offs.
33:57Right?
33:57I think Often, these approaches that
involve concurrency are they're optimizing
34:02for either the reality of something
like a slow network request or for
34:05sort of worst case performance making
sure that you keep some things running
34:09fast even if other things are slow.
34:11And I think there's a different approach
you can think about, which is, In a
34:15nutshell, just make everything fast.
34:17And as long as everything's
fast, it'll be simple.
34:19If things get slow, you might end
up with a worse experience than you
34:22might have in a system that, you know
that is designed around concurrency.
34:26For example, maybe in a in a Riffle
style approach, if you're trying to
34:31synchronously paint frames and something
is slow, you might just end up with a ton
34:35of dropped frames and sort of a frozen UI.
34:38Whereas in a system designed to account
for that with better concurrency support,
34:42you might have, you know, a loading
spinner and some things remain responsive.
34:46And so I think Part of the
challenge is figuring out how to
34:49how to balance those 2 approaches.
34:52And as we've seen in our work, I think
sometimes you do need to account for
34:56the reality of sometimes you have to
make a network request because, you
34:59know, you're talking to an external
service or something, and you do
35:02need ways to model concurrency.
35:03It's just that I think We don't
need to, I guess, throw the
35:07baby out with the bathwater.
35:08Like, not everything needs to be
concurrent, and some things can be fast.
35:12I think I don't have much game dev
experience, but I my understanding is
35:15that a lot of video games, essentially,
you know, they paint frames, and
35:19they make sure every frame is fast.
35:20And they don't drop frames because
they make sure the frames are fast.
35:23Right?
35:23And I wonder how much of that ethos we can
apply to general UI development as well.
35:28So we've been referring to this thing,
Riffle, now throughout this conversation.
35:33And clearly, you and I are well aware
of what Riffle is, And you've motivated
35:38what Riffle is supposed to be through
the principles and sort of what you were
35:43hoping to achieve with it in theory.
35:45But in reality, what is Riffle?
35:49Riffle was a research project.
35:52And so our primary goal was to try to
get some of these ideas into people's
35:55heads, but we did need a way to test
them out and see, is this even possible?
35:58Is this really a good idea?
36:00And to do that, we built a
simple prototype reusing existing
36:04parts as much as possible.
36:06Namely, we we built on React JS as a
view templating layer, and we built on
36:10SQLite, which is a popular relational
database that can be embedded on
36:15devices and in the browser through Wasm.
36:18And what Riffle is, technically, is a
layer that sits between React and SQLite.
36:24And what it does is it lets you specify
a bunch of, SQL queries that turn a
36:29SQLite database into a React UI, and
it gives you some hooks in your React
36:33UI to do things like query data in a
component or make writes to your database.
36:38And you can think of it sort of as a
state management framework built on
36:42top of SQLite for React that tries
to realize some of these ideals we
36:46just talked about in a concrete way.
36:48Right?
36:49Now, again, this uh, was just sort
of a prototype to explore the ideas.
36:53And one challenge we faced early on was
how do we really test out if this works
36:59in the kinds of context we care about,
which are complex data intensive apps with
37:04pretty large amounts of data relatively
speaking and interesting schemas
37:08and strict performance requirements.
37:10To do apps are kinda boring and
don't really address any of those
37:13and that's actually how we ended
up collaborating with you on this.
37:16So, Maybe do you wanna tell the audience
a bit about how you got involved?
37:21Yeah.
37:21Totally.
37:22We've been in touch since You worked
on Cambria, and I think we've
37:26been catching up once in a while.
37:28And then at some point I learned about
you thinking about this this broader
37:32space and rethinking state management.
37:36With my background of Prisma,
I'm obviously no stranger to
37:40thinking about state management.
37:41I've been thinking about how
to make it simpler, typically
37:45more in a back end context.
37:47And for me, this was really
the the interesting foundation
37:51that you said, like, hey.
37:52Why why do you even want the back end?
37:54You wanna build an app.
37:55You didn't quite say it like this, but
this is the way how I how I had sort of
37:59picked it up and framed it in in my head.
38:02And that was a really stimulating idea
for me to say, like, actually, yeah,
38:06let's bring the database into the client.
38:09I was using a lot of MobX and
Redux and those sort of things in
38:13the past, and they they worked.
38:15They made me productive, but they didn't
have the properties that you mentioned
38:19before that state wasn't persistent.
38:22It fundamentally treated
state and data differently.
38:26I would fetch my data from from a back
end . It was a very Interesting idea for
38:32me to have the data all there locally.
38:35So and I was thinking about building my
own music app for for quite a while, and
38:41Riffle seemed like the perfect catalyst
for me to really take a stab at it.
38:46And the only way how I could could
really make progress on such a
38:51big effort, mostly by myself, was
to cut scope as much as possible.
38:58And that's that was a very
simple math to say, like, hey.
39:02We can cut the scope from the
back end categorically, and I can
39:07focus all of my energy and time on
building the best client possible.
39:10And a music client is no nobody talks
about, oh, that's the best music back end.
39:16People want the best music app.
39:18And that has led me to become the first
design customer, does it first design
39:24partner for Riffle, and that made
a a brilliant combination, I think.
39:28Yeah.
39:28I think one alignment and values that has
really helped here is that, you're trying
39:33to build a music app for power users.
39:35Right?
39:35And I think power users often care
about things like data density, latency.
39:40Um, you know, it's funny.
39:42When you look at apps like Spotify, for
example, and we've we've talked about
39:45this many times over the course of this
collaboration, Spotify, their desktop
39:50app is quite slow often and also quite
network reliant to a surprising degree.
39:56Many page transitions that we've
encountered even for data that is already
40:01locally cached, for some reason has a
lot of network access going on, and you
40:05often get multi second loading screens.
40:07And I think for serious Music
people like DJs you know, some of
40:12your target audience for Overtone.
40:14I think of it a bit the same way that,
serious email people like apps like
40:18Superhuman that respect their time
and make them really fast at email.
40:21A serious music fan wants an app that
feels good and not some, you know, loading
40:27screen filled consumer feeling app.
40:29Right?
40:30And I think that was really aligned
with some of the goals that we wanted
40:32to hit with the Riffle approach is,
Basically, can you just throw all the
40:36music metadata in a SQLite database use
relational queries, which are really
40:40good fit for things like joining together
albums and artists and tracks, things
40:44like that, and power, the kind of power
user experience that you wanted to build.
40:50Exactly.
40:50And I think this was literally also,
like, the starting point for our
40:54first prototypes to do a data model.
40:57I'm kinda employing similar ideas that
you use in back end development where
41:01you first lay out your different tables.
41:03In this case, I didn't
actually create a user table.
41:06I still don't have a user table
since the app just runs locally, but
41:10I did create a tracks table and a
albums table and a playlist table.
41:14And we threw that together.
41:16And within the shortest
period of time, we had a fully
41:20functional, very crude music app.
41:23And step by step yeah, we we I think we've
been looking for reasons why it doesn't
41:29work, and we never found that reason.
41:31And then the months passed, and the
collaboration now lasted, I think,
41:36for for almost, like, 2 years.
41:38And you've confirmed the hypothesis
that you had with your with your
41:42PhD thesis at MIT for for Riffle.
41:45this made for a brilliant partnership.
41:47Yeah.
41:47I think you know, one of our
goals with working with you
41:51was that first of all, yes.
41:52Like you said If it went well,
which I think it has gone better
41:55than we expected, then it's more
valuable confirmation, right, that,
41:59like, a real serious app works with
this than, like, a to do MVC demo.
42:04So I think that was one thing.
42:05But, also, the the
primary goal was not that.
42:07The primary goal was uncover what
the real challenges are of building
42:11real software in this model.
42:12And maybe you could talk a bit about
you know, throughout the project,
42:16you've been a a very useful critic
and sort of have pointed out a lot
42:22of the the problems and challenges
that come from working in this way.
42:26And I'm curious what your take has
been on what the biggest problems
42:30we've had to solve have been.
42:33Totally.
42:34So I as a person, I
like pioneering things.
42:39So I have probably a higher risk
appetite, and I can deal with, like, a
42:44couple of more paper cuts temporarily
than someone else who is just looking
42:50for the the best well trodden path.
42:53So, this this made me a viable partner
here as opposed to to someone who
43:00only touches the technology that is
already well proven over the years.
43:05And so I was rather looking for an
advances on a in a broader scale,
43:11like, on a architectural level and just
something that in the long run can help
43:16me reduce, and avoid complexity as much
as possible even though temporarily
43:23possibly dealing with enduring a
few more paper cuts here and there.
43:28And given that I am both comfortable
in the shoes of an app builder as well
43:33as in the shoes of a tools builder.
43:36I think I was uniquely positioned to
switch between those those 2 modes
43:41to unblock me etcetera, and to have
enough imagination to understand,
43:47oh, this is not a categorical flaw
in the way how things are right now.
43:51We can fix that through better
tooling or refactoring of the API.
43:56So this I think it was kinda in in
waves where there was some waves of
44:02immense productivity, and things have
been working much better than expected.
44:07And at times, we've hit some walls
of doubting, is this ever gonna work?
44:12Are those principles, the the ones that
we've picked Are those the right ones?
44:18Is it a good idea to keep our
entire state graph synchronous,
44:23can we make it fast enough?
44:24So we've been hitting those challenges,
And the ones that are most memorable
44:29to me was really around performance I
can motivate it from my perspective.
44:35I've set it for myself as a challenge.
44:38I want to build a music app
That's fundamentally built with
44:42web technology that should still
feel as fast as a native app.
44:47So that means If you're now looking
at a 60 hertz display or a 120
44:52hertz display, if you scroll, if you
interact with the app in some way,
44:57It should work without frame drops.
45:00And given that all state management,
everything everything that changes
45:05on your screen, is fundamentally a
result an implication of state change.
45:11And that this happens smoothly,
it needs to happen in a 120 hertz.
45:17So, that basically gives you
per frame, yep, less than 4
45:21milliseconds to do everything, state
change, render, react, etcetera.
45:26So performance was always top of mind,
and I think that where we've been going
45:31back and forth is it ever gonna work?
45:33Oh, yes.
45:33We can make it work.
45:35And that has kept us busy for for quite
a while, and I think we can go more
45:39into depth what that's what that meant.
45:42But that's that's the top challenge that
comes to mind besides a few, like, paper
45:47cuts and also figuring out, like, how do
we the the starting point, even though
45:52this is a local-first podcast, Riffle Up
to this point, it was mostly local only.
45:58And just in a later point, we're making
we're introducing the the collaboration
46:04aspect to make it truly local-first.
46:07But yeah, I think performance been the the
major challenge that we've been facing.
46:11You know, the way I think about
performance in this stack is that the role
46:15of the database is to make things fast.
46:18What a database does is you give it
nice declarative queries, And it figures
46:22out how to make them fast because
some smart people worked very hard,
46:25and you didn't have to do that work.
46:26Right?
46:27And I think a lot of the challenges
we've hit basically boil down to, um,
46:31we don't quite have the right database
for this use case or a shape yet.
46:36A lot of UI stuff, I think, boils down to
the problem of incremental computation.
46:42Incremental computation is a is a pretty
broad, you know, computer science term.
46:45That basically means I have a function
and the input changes a little bit.
46:50Can we figure out how the output
changed without starting over
46:54from scratch on the fresh input.
46:56Right?
46:57And this is a problem that people have
approached from a number of sides.
47:00The sort of programming languages
community has approached this problem.
47:04You know, incremental computation
is the keyword that can highlight
47:07a lot of the work there.
47:08But the databases community has also
thought a lot about this problem.
47:11They Often call it
incremental view maintenance.
47:14You know, an example might be I
have a big join on thousands of
47:18rows and I add one row to the table.
47:20How does the result change.
47:22Right?
47:23And I think a lot of the reasons we've
had performance challenges is that our
47:27technical stack has mostly been based on
SQLlite which is a database that is sort
47:32of built for UI, but is not incremental.
47:34We did some explorations with a database
called SKDB which is actually a SQL
47:40database designed to be incremental,
And that yielded some pretty
47:44interesting and promising results.
47:45We actually published a paper at
the UIST conference, which talked
47:49about some of our positive results
from working with that technology.
47:52I think, ultimately, you ended up
deciding to stick with SQLite for the
47:56production Overtone app because you
wanted a sort of a more, you know, mature
48:00database to work with as your foundation.
48:02But the way I see the problem is really
that we sort of need the right database
48:07that has the right primitives to make
UI development of this sort fast.
48:11And maybe the perfect database
for that doesn't quite exist yet.
48:15But I think that's that that's the
missing piece and the ultimate, you
48:19know, decade ahead if this really
panned out, version of the stack, I
48:24think, would include that database.
48:26Yeah.
48:27Totally.
48:27And I I think it's a matter
of, like, now it's early 20 24.
48:31Who knows?
48:32Maybe next year, the the world
has already moved closer into the
48:36direction that is a good foundation
for for something like Riffle.
48:40The the audience shouldn't have
the takeaways like SQLite is slow.
48:44Quite the opposite.
48:45I think this was the insight that
SQLite is incredibly fast and remarkably
48:51capable was the foundation to embark
on this project in the first place.
48:55Nicholas has been through his
prior work at Apple, Done a lot
48:59of work related to SQLite and I
think related to to FoundationDB.
49:04And that was one of the key insights
that we say, like, Actually, SQLite is
49:08so fast and now can be embedded into
web applications through Wasm that it
49:13can be a replacement technology for
some for, like, MobX and and Redux.
49:18So before WASM, etcetera, and all of the
optimizations that have gone into that.
49:23This wouldn't have been possible.
49:25But now that's possible this allowed
for a better foundation for to deal
49:31with complexity since if you build
something with MOBX, etcetera, you
49:36still need to wrangle all of your
JavaScript objects by yourself.
49:40Like, if you want to have, like, a
filter or map or group by, you gotta
49:44implement all of that yourself.
49:45And the app user experience that
I want to enable with Overtone
49:52is this will be very common.
49:54Think about it, like, in Notion
when you have the tables feature and
49:58you have You configure a few sorts.
50:01You configure some group buys.
50:03You have different views.
50:04Those are all things that get
very boilerplatey to implement
50:08with JavaScript, and those are all
things databases are super good at.
50:13And this is what got me over the
fence to say, like, actually, let's
50:18embrace what the database is good
at, and build a bit of, like, the
50:22React nice to have things around it.
50:25And I think the the core of what Riffle
is is really like that combination
50:32of a underlying SQLite database and
put a reactivity system on top of it.
50:37And reactivity system in that regard
is, like, how React Components compose,
50:42and if one thing changes, then the other
thing updates to the minimal degree.
50:47That's what Riffle is doing.
50:48And A very simple idea with many
implications and remarkably powerful.
50:54Yeah.
50:55You know, I I think you're you're right,
and it extends beyond performance too.
50:59I think when you think about the
requirements of what a UI needs, I
51:03think that when you remove all the
layers that typically sit between a
51:08back end relational database and a UI.
51:10Those layers were there for a reason.
51:13They were solving some problem,
and you end up needing to find
51:15ways to solve those problems.
51:16So, often, UIs need tree shaped
data to hydrate a tree of a UI.
51:23Right?
51:23Often front end developers
don't already know SQL.
51:28And often, actually, SQL, we found
can be a mediocre language for
51:32certain parts of UI development.
51:33It often just feels a little
bit too low level or something.
51:37Obviously, you know, having worked on
Prisma, you, I think, have experience with
51:40some of those problems in the back-end
context, but I think some of them become
51:44even more apparent in a front-end context.
51:47Some of the you know, I I don't wanna
necessarily necessarily say the ORM
51:52word because I think that's a touchy
topic, but I think some of the roles of
51:56associating different kinds of models
with each other and things like that,
51:59there's sort of, sometimes feels like
there's a need for for that kind of layer.
52:03Right?
52:04I think you know, in our technical
prototype stack, what we ended up doing
52:08was stuffing a GraphQL layer in there
between SQLite and the UI you know,
52:13because you're a GraphQL expert and that
helped alleviate some of these problems.
52:17But, again, I think I see and I think
we we see that more as a as a shim.
52:22Right?
52:22Like, sort of, a layer that
shouldn't need to be there, but
52:25it's there because the database
didn't quite have the right shape.
52:28And I think some of that reflects that
maybe no one has ever designed a database
52:34specifically for this role of being
embedded so closely to a user interface.
52:39Yeah.
52:40Totally.
52:40I mean, I I think about it this way.
52:43We wanna take one or 2 steps forward,
But in order to do that, we also
52:48had to take a step backwards.
52:50And the the step forward that we took
is that we get the power of a database,
52:54that we get all of those semantics that
a database give us, whether it's group by
52:59and sorting and nested selects, etcetera.
53:03All all of those great things that
would really um, freeze up our work
53:07and make some things that we would
need to imperatively implement in
53:12JavaScript makes that declarative.
53:14However, the steps that we're taking back
is that, In SQLite, it's quite limited.
53:20It doesn't have many data types.
53:22It doesn't even have a
Boolean type, etcetera.
53:24So you need to do a lot of translation
between the way how SQLite understands
53:29the world and how someone who's,
like, a a more sophisticated
53:35TypeScript developer as me.
53:37I'm used to having all of
my fancy TypeScript types.
53:40And to create a good translation layer
between that embedded SQLite database
53:45and what I want in my JavaScript
now we gotta reinvest in that.
53:51And so you've mentioned GraphQL.
53:53That was sort of a technology that
I was quite familiar with from prior
53:58work, and I think that's sort of a
temporary usage until we we teach SQLite
54:04some of the tricks that TypeScript
already knows and until we create a
54:10a better mapping in in between that.
54:13But that's certainly been another, For me,
less of a challenge, but it still requires
54:18quite a bit of work to make SQLite feel
and a native in a TypeScript setting.
54:24Some people, I think, believe that
one of the sort of original sins
54:28of computing, so to speak, is that
programming languages and databases
54:32really split into separate fields.
54:34And the idea of, like, the system
that you use to wrangle your runtime
54:38in memory state And the system that
you use to persist and query your
54:41persisted state are so separate
in the way you think about them.
54:45You historically, you have
systems like small talk, for which
54:49have much less of a separation.
54:50They're closer to you have objects in
your language and you're just saving
54:55those objects and reloading them,
And there's much less of a gap there.
54:59Right?
54:59And something I found interesting about
some of the more recent work you've
55:02been doing in this space is you know,
you've been working on tools that make
55:06it easier to close that gap and let
you think about the kinds of in memory
55:11objects that you wanna be thinking about
in your program, and turn those into the
55:16things that you wanna be storing in your
database and querying and vice versa.
55:20And I think that's again one of the
really interesting challenges in
55:23this space is handling that impedance
mismatch between a relational database
55:29and, your TypeScript code or whatever.
55:31Do you wanna talk a bit about
that area you've been working on?
55:35Yeah.
55:35Totally.
55:36I think this is also, like, a for
for you, like, a broader umbrella
55:40of of your work that contextualizes
everything you've been doing over the
55:44past few years and will probably still
be the foundation for for the the
55:48years to come as Malleable software.
55:51For me a common theme seems to be
all around schema management and
55:56kind of fighting that impedance
mismatch from different contexts.
56:02And so I've been trying uh, to make
that simpler in the context of of Riffle.
56:07And in a way that nicely brings us back
to the initial topic that we talked about
56:12with Cambria since it's not just Already
hard to deal with that appease mismatch
56:18between your application, types that
are expressed, for example, in TypeScript
56:23and the way how a database thinks
about it how it stores the the data.
56:28But both can also change over time.
56:31You wanna implement
new features, etcetera.
56:33So your database schema might change,
Your app types change, so you also get a
56:39deal with with schema change management
here, which hopefully, we'll we'll
56:44get to bring some of the goodness of
Cambria in into the fold here as well.
56:49Schema migrations is still Sort of
a untamed problem, but we're we're
56:55getting ahead of ourselves here.
56:56So, if Someone in the
audience thinks about, okay.
57:01Riffle sounds great.
57:02Can I use it?
57:04You've been mentioning that you've been
doing this as part of your PhD at MIT.
57:09What is the current state of Riffle?
57:12Yeah.
57:12I get asked this question from
time to time, so it's probably
57:15good to provide an update.
57:17So Riffle was a research
project fundamentally.
57:19The goal was to explore this idea and
see if it was possible or a good idea.
57:24It ended up being part of my PhD
thesis, and I wrapped up grad school.
57:29And at this point, sort of the the
core Riffle project itself is is,
57:34I would say, it's basically over.
57:36We published a paper at the UIST
HCI conference this year that
57:40summarizes some of what we learned.
57:42However the ideas are not, dead.
57:44So, actually, you, Johannes, have been
sort of carrying the torch forward
57:48to some of these ideas and building
them into a new library that you're
57:51building, that has sort of replaced
Riffle as the foundation for your work
57:56on Overtone and so maybe you could talk
a bit about your ongoing work there.
58:01Yeah.
58:01Totally.
58:02So for me, what's been the most
valuable thing over the course of
58:07the past few years in terms of our
collaboration is, a, that collaboration,
58:12that partnership, and really doing a
lot of research and exploratory work
58:17together and then, yeah, b, having sort
of, like, a prototype implementation
58:23of what that could look like.
58:24But it was really a prototype
implementation that could prove
58:29out those different ideas.
58:31But to make actual progress with
Overtone, I was running into a lot of
58:37the limitations of the those prototypes
where it was working on the happy path.
58:42The not so happy path was
unexplored and started causing
58:47a bunch of problems for me.
58:49So this caused me not to throw out the
baby with the bathwater and reach back
58:53for something like MobX or or Redux.
58:57But it has led me to yeah, where put
on my dev tool builder hat again.
59:04And I started productionizing the
ideas of Rifflemore, and I did
59:11that under a new umbrella, which
is a library called LiveStore.
59:15It is not yet open source.
59:17I'm hoping to get it open
source sometime this year.
59:22Right now.
59:23If someone is curious to give it
a try it is possible right now if
59:28you are sponsoring the the project.
59:30That's a topic for another day.
59:32I'm hoping to make development
of LiveStore sustainable.
59:36And through GitHub sponsorship is one
way how I'm currently planning to do so.
59:41But, yeah, the ideas of Riffle live on
and possibly multiple projects in the
59:46future, LiveStore being one of them.
59:49I'm sure your work on Riffle has
inspired more folks to implement
59:53similar ideas in the future.
59:55So that's that's what I
can contribute right now.
59:59Yeah.
59:59I'm really excited to see where
your work with Livestore goes.
1:00:02You know, I think You have some some cool
stuff cooking and places you're trying
1:00:06live store, and I'm sure you're gonna
keep learning a ton more about where
1:00:11this approach works and new challenges.
1:00:13Right?
1:00:13But it's very exciting to me that
these ideas are living on in your work.
1:00:17Yeah.
1:00:18And so Geoffrey and I are still touching
base every so often, and I share my
1:00:26updates and progress on LiveStore.
1:00:28And Now step by step I get to make
progress on some parts that we haven't
1:00:34quite got to yet while working on
the Riffle research project and
1:00:40where I get to unlock some progress
where Geoffrey thinks, oh, yes.
1:00:46Finally, we're getting to that
point that we haven't gotten
1:00:50to while working on Riffle.
1:00:52And I now I'm I have to face all
of those bigger, implications that
1:00:59we've been well aware of, but we just
haven't gotten to them yet, whether
1:01:02it's schema migrations or making
the technology actually local-first.
1:01:07So introducing syncing and collaboration
capabilities, and I wanna do so
1:01:12in a way that is compatible with
different kinds of syncing approaches,
1:01:16whether it might be something like
electric SQL or possibly something
1:01:20like Auto Merge or Yjs in the future.
1:01:23So there in a way, we've come really far,
and in a way, we are just getting started.
1:01:28So I'm I'm super excited about that.
1:01:31So we've been talking a lot about
SQLite, Riffle, LiveStore, But you've
1:01:37since moved on to to new projects.
1:01:40So and I think you're still at Ink
and Switch even more so than for I
1:01:44think you're now full time at Ink and
Switch and are already in new projects.
1:01:49So which sort of problems
are you currently looking at?
1:01:53Yeah.
1:01:54So since finishing my PhD earlier I
guess last year over the summer, I've now
1:02:00for a few months been full time at the
Ink and Switch Research Lab where Peter
1:02:03Van Hardenberg again is the director.
1:02:06You know, they're where a lot of the look
they they coined the term local-first.
1:02:10Right?
1:02:10And so they're what got me into
this space in in some sense, and I'm
1:02:14Really excited to be full time there.
1:02:16I'm leading our malleable
software research track now.
1:02:19And so that's basically a research
track where we explore these ideas
1:02:22around customizable software.
1:02:24And we really are interested
particularly in the intersection
1:02:28of the local-first architecture
and the malleable software agenda.
1:02:32And we have a lot of ideas for how those
2 things can be kind of complementary
1:02:36to each other as I described earlier.
1:02:39We have some fun experiments brewing.
1:02:41one thing is that we're increasingly
trying to use our own local-first tools.
1:02:46So one Little project I worked
on in my past few months there is
1:02:50spinning up a writing tool that
we use internally at the lab.
1:02:54We used it to write our last essay that
we published and that's based on the auto
1:02:59merge stack that the lab has developed.
1:03:01And it's a really nice way to sort
of, Again, just get some authentic
1:03:05experience using the stack and
understanding the challenges and
1:03:08the and the and the good stuff.
1:03:10Right?
1:03:11We're then kind of using that stack
as a foundation to explore a lot
1:03:16more speculative stuff going forward.
1:03:18You Yeah.
1:03:18Some of the ideas we're excited to
explore are the potential for version
1:03:22control in a local-first environment.
1:03:25If you have, a layer like auto merge
in your stack, which is really designed
1:03:29around not just local-first data,
but also storing, past history of
1:03:34documents, what can you do with that
potential to unlock for end users.
1:03:38And another theme we're gonna explore,
and have started exploring a bit already
1:03:43is not just data in a local-first
way, but code in a local-first way.
1:03:48So if you put code on people's
devices in a way that they can mod
1:03:53themselves what does that unlock in
terms of customizing our software?
1:03:58This is sort of a fully maximalist
local-first approach and it's something
1:04:03that Peter and the lab have explored in
the past but it's, you know, there's a
1:04:07project called Pushpin, which I encourage
people to look at if they haven't
1:04:11heard of it, which is basically, an
exploration of what happens if you have
1:04:15local-first data plus flexible tools that
can op that can operate on that data.
1:04:20And I'm excited to keep pushing in those
directions and see if we can basically
1:04:25give people more control and empowerment
over their computing experience on
1:04:29top of this local-first data stack.
1:04:31That is incredible.
1:04:33I'm very tempted to also somehow
contribute more in those various
1:04:38topics that you've been mentioning.
1:04:40But
1:04:41My day has just so many hours, and I
think I have still a lot of work ahead
1:04:46of me with LiveStore and and Overtone.
1:04:49However, I think there will be many
problems that will have positive overlap.
1:04:53I think we're still not done
with the Cambria problem.
1:04:56Maybe we get to collaborate
there in the future.
1:04:58We've been doing also some really
interesting exploratory work around
1:05:03what does it mean for an app to
have version control for for users.
1:05:07That is something I'm really
interested in so I'm I'm sure
1:05:11we'll we'll get another stab at
collaborating on some project together.
1:05:16But, yeah, Geoffrey, I've been
looking forward to this for a long
1:05:19time and really excited to share what
we've been working on over the past
1:05:23few years with a broader audience.
1:05:26And thank you so much for for taking
the time and sharing all of those
1:05:30stories and and insights with us.
1:05:32Thank you.
1:05:32you
1:05:33Thanks so much.
1:05:33It's been fun.
1:05:35Thank you for listening to
the localfirst.fm podcast.
1:05:38If you've enjoyed this episode and haven't
done so already, please subscribe and
1:05:42leave a review wherever you're listening.
1:05:44Please also consider telling your
friends about it, if you think they
1:05:47could be interested in local-first.
1:05:50Thank you again to Expo and Crab
Nebula for supporting this podcast.
1:05:54See you next time.