A podcast about local-first software development



#3 – Geoffrey Litt: Malleable software, local state management & Riffle

In this episode we talk about Geoffrey's background in malleable software and how relational databases can be leveraged to build better web apps and improve data ownership. A topic he extensively investigates through the Riffle research project.

Mentioned in podcast


Thank you to Expo and CrabNebula for supporting the podcast.


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:26It's great to be here.
Malleable software
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: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: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: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: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: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: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:21So you've been working on on Wildcard.
08:24Which are the results that come out of your your overall research in that field?
From Wildcard to Riffle
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: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: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?
Data ownership: SaaS vs Local-first software
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: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: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: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.
3 principles behind Riffle
17:04So, you know, the first principle I talked about is thinking of an
17:08application as a database query.
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: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.
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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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:52I think maybe to avoid overclaiming here, I'll say there are some trade offs.
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.
What is Riffle?
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: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: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: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: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: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: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: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
Riffle Challenges
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: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: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: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: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: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: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: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: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: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: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: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.
Where's Riffle now?
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: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: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:13But it's very exciting to me that these ideas are living on in your work.
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.
Geoffrey's new projects
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: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: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: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: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.