739

March 6th, 2024 × #local-first#offline#pwa

The LoFi Movement: Building Local First Apps

This episode covers the concept of local first web development, where apps work offline first and then sync data in the background. The ideals, principles, tools, and sample projects around this concept are explored.

or
Topic 0 00:00

Transcript

Wes Bos

Welcome to Syntax. Today, we've got a episode for you on local first development, lofi, which is super cool. Scott's like, we're gonna do an episode on lofi. I was like, what the hell is that? That sounds cool. Some sort of, like, sick library for, like, making tunes or something like that, but, it means local first. And, it's approaching your applications so that they work offline first. Scott how, like, sometimes people think, like like, mobile first. Right? You think about your applications as a mobile app first, and then you scale up rather than the opposite. So local first is thinking about your applications of, like, what happens when the Internet cuts out and then what happens when we we reconnect. So Scott has dove deep into this topic, so excited to talk to him all about that. How are you doing today, Scott?

Scott Tolinski

Hey. I'm doing good. You know what? About 10 minutes ago, it Wes, clear sky. And right now, there's, like, already half,

Wes Bos

so

Scott Tolinski

right now. Oh, no.

Wes Bos

Oh, okay.

Scott Tolinski

Oh, it it is a certified winter wonderland.

Wes Bos

It is, like, coming out. Wild. That is wild that Denver JS just, like, warm and snowing in, like, the same week. 60 and sunny yesterday. Yeah.

Wes Bos

Hold on. Sanity. What is that in the for the rest of the world? Oh, warm.

Scott Tolinski

15.5.

Wes Bos

Thank you for for converting for the rest of the world. That makes a lot of sense.

Wes Bos

Let's talk about my T shirt.

Wes Bos

I will tell you right now, I will do anything for a T shirt.

Wes Bos

You can you can ask you can ask me to pay me money. You can ask me to to take me out for lunch on talk about your company.

Wes Bos

Sometimes, maybe. Whatever.

Wes Bos

Send me, like, a a T shirt. I'll do literally anything for a T shirt, which is a weird part of tech where that we will do this. So, this company, Dress Node, sent me this, and, they're sometimes people will reach out and be like, hey. We have this, like, crappy print on demand coding T shirts where they just, like, have these crappy T shirts. And and I got this one. I was like, oh, this is another one of those. Right? But I was like I checked it out. I was like, this is actually sick. So check this out. Dress Node is makes these teas for Oh, yeah.

Wes Bos

Super good Sanity, like, super high quality, kind of, like, more of a boxy, modern fit.

Wes Bos

And he hit me up. It's, the guy behind it is a a product manager at Microsoft, and he said, hey. I'm I'm making, like, a black owned tech inspired clothing brand called Dress Node.

Wes Bos

And, also, the dude knows a little bit about making sweet shirts, and that's something I'm really into. So he sent 1. He's gonna send 1 to Scott as well. So Scott will probably wear his on a future app as Wes, but certainly check out Wes code if you are interested in cool shirts. Look at the even like this. There's like a cool

Scott Tolinski

Oh, yeah.

Wes Bos

QR code. Great logo. Apparently, there's like a whole bunch of fun experiences if you scan that. I haven't done that yet. But, they have a really cool mission behind STEM and and furthering it. So check it on out. Thanks, Dress Node.

Wes Bos

Not for sponsoring, but thanks for this free shirt. And, again, I'll do anything for a free shirt.

Scott Tolinski

Yeah. If you got shirts out there, just just send them along.

Scott Tolinski

And this podcast is presented by Century. So if you need air tracking in your software, and this stuff that I'm about to get into in this episode is complex. Let me tell you. I have, you know, really spent some time in here, And it's and, unfortunately, it's not super easy. And with anything like that, you're bound to make some mistakes.

Scott Tolinski

Now when we have all these systems that we're about to talk about, you know, there's a ton of potential for things in syncing process, in saving process, anything to go awry or to not behave like you're expecting it, and your visibility on that's going to be super low. So if you wanna have high visibility into your applications, head on over to century.ioforward/ syntax. Sign up and get 2 months for free. And, it's just an awesome tool.

Scott Tolinski

So let's get into local first. Now local first or lo fi, which honestly, even if you Google lo fi local first, man, that lo fi beats to to code 2 or to study 2 has, like, really dominated Google. So if you're trying to research this stuff, I've included a massive amount of ESLint, including this, this really good one, which is local first web dot dev, which that in itself has a massive amount of links. So if you're if you're looking for further information on this, it's gonna be tough to Google, and I've tried to include everything as as you, you know, would need so in this episode.

Scott Tolinski

So I think the the big thing here is that the local first movement as as it so put or local first development is more than maybe what you're thinking in terms of, hey. It works offline.

Scott Tolinski

The way that they've defined this lo fi movement of coding is through several things.

Scott Tolinski

And these are these are the kind of principles in which they're call them the 7 ideals of local first. And and I've pulled this directly from this Inc. And Switch blog post.

Scott Tolinski

So this these are not my own words, but I'll I'll do my best to try to explain some of these. And you'll see different projects in this space representing all or maybe some of these ideals.

Topic 1 05:19

7 ideals of local first

Scott Tolinski

So number 1, no spinners.

Scott Tolinski

They want instant loading.

Scott Tolinski

And you can really get instant loading, like, in terms of from your database calls or your your data. If you're loading from an IndexedDB locally, I mean, cut like, for very minimal data, you could get as low as, like, 20 milliseconds. And it's for complex data, you know, you're only getting up to a couple 100 milliseconds, which is a far cry from a network call. Right? Yeah. I'm I'm sure you're gonna get into this, but IndexedDB is the Wes API. It's a database in the browser.

Wes Bos

It's a set of APIs to interact with a database that actually lives inside of your browser. It's similar to local storage, but way more powerful and a little bit more complex to get into, whereas local storage is just key value strings. Right?

Scott Tolinski

Yeah. Yeah. If you were saving data in this kind of context, like a full application, you're you're not gonna put it into local storage. You could think if you're trying to sync your database, you're gonna put it into IndexedDB.

Scott Tolinski

There's some other options there too. People are doing some crazy stuff with WASM and SQLite.

Scott Tolinski

But for the most part, number 1 ideal, no spinners. They want that data to load quickly. It's on your device already. It shouldn't take any time to load. 2, your work should not be trapped on 1 device.

Scott Tolinski

As in if you go to your phone, your computer, whatever, that information should be able to sync from Node device to another. Okay? And it should happen preferably in real time. So that way, if I do something on my phone, it goes to my computer.

Scott Tolinski

Now

Wes Bos

Really? Without a sir there's gotta be a server, though. Right?

Scott Tolinski

There is a server, and this is part of the that we're going to get into.

Scott Tolinski

Okay. Because that local first does not necessarily mean offline

Wes Bos

first. Server offline. Vercel Wes less? Correct. Yes. And then JS no serverless?

Scott Tolinski

Dude, it JS very funny because one of the the one of the things I watched when they they were describing they came up with the lo fi name.

Scott Tolinski

They were like, at first, I wanted to call this serverless, but then the serverless folks took that. So I couldn't call it serverless, which is great.

Scott Tolinski

Okay. So those are the 222 additional or 2 initial ideals. 3rd 1 is the network is optional. Notice how it says optional and not required.

Scott Tolinski

So the network will be used for initial loading of the app. It will be used for syncing your data. It will be used for bringing in new data from the sync to database, those types of things. But the network should not be a requirement to use your app generally.

Scott Tolinski

And this is for a number of reasons beyond just working offline.

Scott Tolinski

It's so that if your network conditions are changing, the app experience doesn't change. If you're loading everything locally again, it's going to be fast. It's going to be on device.

Scott Tolinski

Okay? The the most, like, reasonable thing I could say is, like, it's a it's an app on your phone that functions very much like a native app.

Scott Tolinski

Obsidian comes to mind. Right? You can work in Obsidian whether there's a network or not. And when the network connects, it syncs. So seamless collaboration with your colleagues AKA multiplayer stuff. This is you know, you see this a lot where, you know, Wes and I are editing the same Notion document. That is seamless collaboration with your colleagues. So that is a tenant of, or an ideal of local first, which is funny because when I was researching, multiplayer stuff we did this for my Hack Week project at Century. I did a kind of a document editor, a multiplayer document editor. You see so many of the same folks, so many of the same projects, so many of the same connections with a different goal in mind. Right? The multi player specifically is a goal for collaboration, but it also plays an important part in offline first software, local first software.

Scott Tolinski

Next up is security and privacy by default. Everything should be encrypted. Right? Stored on your device. It's yours. It should be encrypted. That's part of their ideals.

Scott Tolinski

Next step is that you retain ownership and control. Hey. The app is on your device, but also you can export that data. Yeah. If you ever see the actual budget project from James Long, that's a good example of this because, again, these these files are local. You can export them. You can import files. You can move them around.

Scott Tolinski

One of the things they often talk about is like, hey. If the service goes down and you have the app on your phone, the app should just not stop working.

Scott Tolinski

Maybe they take the app down. It's yours. You should be able to use it. Yeah. You wanna wanna hear a crazy story about that?

Wes Bos

Wes. So this this company, I I won't name them because I'm I'm sure they're actually trying to fix the fix it. But they emailed me and say, hey. Check out our new note taking application. It's kind of like a mix between mind mapping and, and note taking, which is something I've wanted forever. Like, I I always do mind mapping, and then I always do Node. But, like, connecting them together, I've never found something that has been been perfect for me, and they came out with that. And I was like, sweet. Like, I'm gonna try this. So I I started, like, making a course in that, and and then I came back to it, like, 2 months later.

Wes Bos

And they had given me, like, a 3 month trial. And that trial had run out, and I was not able to access my Node.

Wes Bos

Like, it was gone.

Wes Bos

And, like, Node.

Wes Bos

I logged in, and it just Wes like like, here's the credit card form if you wanna whatever. And I don't I don't think that was out of malice, but it was it showed me that, like, man, that's not Local First at all. That's somebody else's app. And if you stop paying, you lose absolutely everything.

Wes Bos

Pretty dicey.

Scott Tolinski

Yeah. And I think about this a lot with Obsidian, Right? Which is one of the reasons why I like it so much. The only thing that Obsidian doesn't do well is multiplayer stuff. Right? Like, you and I Sanity edit an Obsidian doc reliably at the same time, at least not in the same way we can in Notion.

Scott Tolinski

But I like about Obsidian is that it is a folder of markdown files. I could go and publish them to my website. I could go and, open them up in Versus Node, and it doesn't have any impact on whether or not I'm able to use those files. So if if Obsidian goes away for some reason, I still have every single method that I have. That's we've said that so many times on this this show is if whether considering whether to buy into a proprietary

Wes Bos

thing or Scott, like, do you go MySQL, or do you go Firebase? You know? And you get a lot more with Firebase. Right? But then, if when when Google shuts them down, you are screwed.

Scott Tolinski

Yeah. And we'll talk a little bit about some of those things even in projects right now within this episode.

Scott Tolinski

Good reading on these ideals and their general thoughts on them, this ink and switch, blog post I have linked directly below these in the show notes is like the best place to get a great handle on just the the big picture of local first if you like in-depth reading. Because this is it's a big read, but it's a really good read. They they talk about, like, all these different softwares and compare them and say, alright. Are they fast, multi device, offline collaboration, longevity, privacy? Do they have user control? And then, you know, there there's a lot of great information here. So, you're probably thinking like I was after, getting a nice little intro to this stuff. Holy cow. It all sounds amazing. Let's go.

Scott Tolinski

Let's just do this. Let's do local first. Yeah.

Scott Tolinski

And then, that's where the the fun part comes in because nobody has really I mean, there are people who are, like, attempting to nail the local first complete solution.

Scott Tolinski

The problem with a local first complete solution is the stuff is hard. The stuff is complex.

Scott Tolinski

And typically, most people aren't starting a new project.

Scott Tolinski

You're working on a project and you might say, oh, man. Maybe local first would be a good opportunity here. Well, that's not really you didn't have the opportunity to do a local first, so now I have this whole tech stack. What do I do with my tech stack? Right? Yeah.

Scott Tolinski

But if you are looking to to start a new project, there are some new services that we'll talk about later on that do get you more things out of the box with less effort, but they do require some buy in. They do require subscription costs. They do require things like that. So there's a whole dimension of how much do you want to do yourself and how much pain would you like to have in your life? Because,

Wes Bos

we'll talk about how complex this stuff is because it's pretty I I am just I I I know it's coming up, but I cannot wait to find out the answer to what happens when 2 people edit the same thing and both come online after.

Scott Tolinski

The answer is, in this very first thing under I have here, the next heading JS the tech. And a big thing that you'll see over and over in the space is the, acronym CR DT, conflict free replicated data types.

Scott Tolinski

And a conflict free replicated data type is basically how you do just that. How you take 2 bits of changes and know which one took place and how to conflict free merge those changes, merge that data.

Scott Tolinski

CRDTs are the thing that kind of powers the whole syncing engine. Right? You have a change in your local database.

Topic 2 15:06

Conflict resolution with CRDTs

Scott Tolinski

You have a change in your remote database.

Scott Tolinski

How do I know which of those is the most updated one? But not only that, you have a change on Node device. You have a change on another Yeah. Do you know which of those changes the most? Run Node that other time. On Wes computer and a change on my computer. How do you know which one of those goods in in what the order they they get updated into the document? Because it's not happening simultaneously.

Wes Bos

It's it's happened on Notion a few times.

Wes Bos

Like, I've gone offline before, and then you've edited something. And I've edited it. And then I come back online, and it it can't resolve that because what I had changed is no longer there. So how how do you do it? Scott, I'm tight in the know. Well, you use a CRDT

Scott Tolinski

of which there is a lot of these things and many of which are not a ton of fun to use. The the big boy in this space is Yjs.

Scott Tolinski

Now Yjs has a learning curve. I'm gonna tell you that right now. Now I have a repo that I'll post into the show notes that shows the same app in both Yjs and Replicash. But Yjs is really the high performance CRDT that has a big community, that has a lot of people using it, and is more of a lower level tool to build these conflict resolution things. Okay? So you can hook up a CRDT to a WebSocket server, and you could hook it up to an pnpm DB.

Scott Tolinski

And in those 2 steps of hooking those 2 things up, you can keep 2 browser windows in sync.

Scott Tolinski

Next thing you do, you hook that Yjs up to your server, your API server, then you get it syncing to your database server. Now those aspects are much more tough, and we'll talk about some services there. So the tech is you need CRDTs, the con the conflict free res merger data. Yeah. There are others of these, but, again, JS is the biggest one. There are easier ones of these, but many of them do cost money to use. There's licensing fees involved.

Scott Tolinski

Yjs is free and open source, but it is probably the most difficult.

Wes Bos

Can I can I just say it's a total missed opportunity to call it crudite.js? Oh, yeah. Broke. Come on. It's not even it's it's on npm. It's open. The whole the how rare is it that a single word npm package is available? And CRDTs are called crudites.

Scott Tolinski

That's I don't know how to spell it, I'm gonna be honest with you. What? I don't know how to spell crudites.

Wes Bos

Crudites. Oh, you're not French.

Scott Tolinski

I'm not. Yeah. We don't. Yeah. Yeah. We call marmots, marmots.

Wes Bos

Momo?

Scott Tolinski

Yes.

Wes Bos

Anyway so but, like, at at some point, you're gonna have a a conflict where that you cannot resolve. Right? Like, at some I've had this with with my Versus Node settings. You've had it with Git as well. Is is there some solution to when you do have a merge conflict at some point? Like, I is JS probably covers most of them, but if both people are both offline and we both change the same word to different word, what's the what happens then? You just tell the user, hey. Something happened, or or you can you could say which Node you wanna keep?

Scott Tolinski

Yeah. I think the answer is that it does its best. What you're not you're not gonna get from this is you're not getting, like, a Like a ESLint interface or Yes. My understanding is that because this stuff is deep, the algorithms are there's different types of CRDT algorithms.

Scott Tolinski

My understanding is that this uses, like, timing involved in, like, a an actual, a specific clock that has, like, a central clock, not these 2 users' laptops' clocks, essentially, that are able to save, you know, the last one out JS the the winner.

Wes Bos

The NPT.

Wes Bos

And Yeah. It's probably smart enough that, like, like, you know how Git sometimes Wes, like, alright. You both change the same sentence, but I'll I can figure it out. You know? Like, you didn't change both the same words of a sentence, so I can I can merge those 2 things into each other? That's cool. I didn't even realize that this was a thing other than Git. Yes. It's a thing, and it's a thing that powers a lot of these multiplayer

Scott Tolinski

apps that you see. Yjs specifically is a very widely used, project for for doing that type of thing. There's a really good, talk from JS from James Long called CRDTs for mortals, which, does its best to explain these things for normal people, and I think it does a great job. Alright. More more on the tech here. WebSockets.

Scott Tolinski

Definitely used WebSockets. Typically, you know, there there is ways to do it with WebRTC, but the way that people are doing typically syncing data is with WebSockets.

Scott Tolinski

You use a WebSocket to connect to other machines or other windows that are opening the same app in the same room necessarily, or you use WebSockets to talk to your server so that when you make a change locally, that server also gets that change so it can save in the database.

Scott Tolinski

Right? Or perhaps the database needs to sync with the client, and therefore, you're getting that information through a WebSocket.

Scott Tolinski

More tech here. IndexedDB, we went over. It's the local database. Again, some people are storing things in SQLite, but most people are doing indexed DB for this. The SQLite stuff is some proprietary interesting stuff going on, maybe, some different projects doing interesting things there. 99% of the time, IndexedDB.

Scott Tolinski

Last piece of

Wes Bos

Sorry. I had one more thing I wanna say is, you know how I can tell that this local first thing is going to be big? After doing a little bit of research on it, there's 2 people that popped up JS is Nick Graff and Johannes Schickling, and they're both Yeah. They're both working on projects in the space, and they're they were both early Prisma GraphQL folks as well. You know? Like, they they saw that and and sort of jumped on it. And now they're they're both working in this space.

Scott Tolinski

Yes. It's gonna be great. Some really, really smart, talented folks. We're bringing all kinds of different interesting projects here, and we'll talk a little bit about some of those and what they can do. But most of those projects that you might wanna check out are on local first web Scott dev. So The last bit of interesting talk here is service workers.

Scott Tolinski

A service worker is basically caching the code that you need to run your site to run it offline.

Scott Tolinski

If so if you think about it and I have I have a a repo that I'll share with everybody that just bare bones examples for this. But if you have a service worker that's loading the code and you have an IndexedDB that is fetching the data client side, you don't have to go outside and you can have your whole application load locally.

Scott Tolinski

Because, again, it's getting that data local on your device. It's getting the saved website essentially from the service worker. All that hopefully just works just fine. In my repo that I'll share, it has a very basic implementation of you click a button, it updates your IndexedDB, and it works offline. You click that button a whole bunch offline, still updates the DB. You come back online. It works the exact same.

Scott Tolinski

So let's get into some software options here. I have 3 different projects that are I think are the most interesting in this space. RepliCache is the one that I think is getting a lot of hype right now. RepliCache is interesting because it is closed source and you sign up with a license.

Scott Tolinski

But the license is pretty reasonable as far as pricing goes. You can get it's funny. It's like monthly active profiles.

Scott Tolinski

If you're less than 1,000 monthly active profiles, it costs nothing. And this is only if your project is commercial.

Scott Tolinski

If your project is noncommercial, RepliCash is free. So if you're just trying this out and you're not making money on it, you can just use this thing.

Scott Tolinski

So that's great.

Scott Tolinski

Replicash handles a lot of things for you. It handles the syncing to an IndexedDB.

Topic 3 23:00

Replicache handles syncing

Scott Tolinski

It handles, syncing in general, syncing over WebSocket. You don't have to worry about the WebSocket code. And it handles the conflict resolution stuff.

Scott Tolinski

So what you end up getting out of it is you get something that works with anything because you just point it to a URL for your push and pull for your API layer.

Scott Tolinski

You connect it to your application. You could connect it to a database, And you are essentially able to with 1 step well, not 1 step. It still takes a little bit. I have a I have a a folder that shows you how to do this in the SvelteKit app. But what it's cool about this, again, it handles a lot of the kind of pickier stuff that Yjs will do.

Scott Tolinski

And that's great. As a friendlier project, I'd say this one is definitely friendlier.

Scott Tolinski

Okay. So it's Yeah.

Wes Bos

It it's essentially a state management library. Like, you would do all of your getters and setters via RepliCache if this is something you use?

Scott Tolinski

Yeah. Pretty much. Yeah. Or you could either way, I did it as I synced it to a, a Sveltekit rune, like a state rune, which is just just keeping it in sync. So I was using the Svelte rune as my local data source, but then it would keep it inside. And you could probably also use, like, a, like, a proxy,

Wes Bos

which is an object which you intercept the get and sets on. Mhmm. And you could just, like like, that's how some of these nice state management libraries, which is like you're like, person Node age equals a100. And behind the scenes, it's not just putting a a number on the object. It's actually intercepting that and running a method, and you can put your own logic in that via a proxy.

Scott Tolinski

Yeah. Okay. So Replicache is a more simple version of Yjs.

Scott Tolinski

Yjs, you gotta do a little bit more yourself. That's okay. In fact, when I lined up the code by code with Replication in Yjs, Yjs, in my basic example, wasn't that much more complex. That said, I think over time it would be. And lastly is Electric SQL, which aims to be Electric SQL aims to do even more for you than Replicash.

Topic 4 25:15

Electric SQL aims to be complete sync layer

Scott Tolinski

And, again, I think this one is a little bit more of a buy in. Again, they they say it's the missing sync layer. So this one, again, is trying to be a nice sync layer. But in reality, you kind of end up using it like an ORM in many ways. You do connect it to your own database.

Scott Tolinski

It does work with Postgres.

Scott Tolinski

It's specifically for Postgres, which is, you know, people using SQLite or or MySQL are out on this one, but it does more. If you're looking for a more and more friendly option, Electric SQL is the one. And there are, by all accounts, more even more expensive and more simple ones. That's kinda how it goes. Right? Yeah. So let's talk about the very most basic offline or local first app. Okay? The very most basic one.

Scott Tolinski

You initially load the app the very first time you load the app.

Scott Tolinski

Your app gets cached via service worker. The data gets stored into an IndexedDB.

Scott Tolinski

You go offline or anytime you load the site, even online, it should load the site from the IndexedDB.

Scott Tolinski

It should be instant. It shouldn't have to go to the network. So at its very most basic, that's it. Right? Where it gets more complex is when you need to go beyond just a local data store. Right? Which most websites probably do. Right? You probably need a remote data store somewhere at some point at some time.

Scott Tolinski

So that this is where things get get tricky because, you do need this syncing between a local database and an external database, and that's where it really gets more complex.

Scott Tolinski

Either way, the benefit of having a simple local first app in this way is that you get near instant writes.

Scott Tolinski

Like, near instant writes, near instant reads. And if you're doing something that requires that or that would feel nice, maybe a here's a basic example that everyone's made a ton of, a to do app. Right? Yep. If your to do app is taking, you know, 200 milliseconds to return from the network just to check a to do, then that's probably a good situation where Local First could come in handy. In fact, I first got into this stuff because I was working on my habit tracker app.

Scott Tolinski

And the way that I solved my habit tracker feeling slow is just by adding optimistic UI. Right? It it the UI thinks that it's a success even if it doesn't know that it's success. And then it, you you know, collects whether that was a success later. However, a local first is kind of better than that because, again, it's saving everything to your database and then just syncing in the background. Either way, you don't your application will feel native fast.

Wes Bos

So that syncing, if I'm understanding what you've told me so Yarn, is that you're you're in the browser. You make changes to your data type. It syncs it to to IndexedDB.

Wes Bos

And then when there is network available, it will then send it to the server.

Wes Bos

The server part, does Yjs do that part as well? Like, does it connect to a database? Am I writing my own resolvers that then save to the database and pull the data out, or or does it also do everything, soup to nuts, with the database?

Scott Tolinski

So Yjs will not touch your database.

Scott Tolinski

Okay. I think there's extensions for it that that do, like, community based extensions that do more there. Yeah. But in in reality, you're using Yjs to understand where like, which piece of data. Is it this data or is it this data? Which one is the most up to date one? And it kind of puts them in a, like, a do this, then this, then this, then this scenario.

Wes Bos

Okay. So who sends the data from the browser to your server? Then The Wes that what the Wes socket. Okay. And then, okay, okay, and then you have a server or WebSocket running that just listens for data coming in, and then you save that data. By the time it hits your server, you're not concerned about it being possibly conflicted? Crudite?

Scott Tolinski

Well, it depends on what. You know? If you have an if you have an app that Yep. Is multiplayer like Notion you have something like Notion, that gets more tough. Right? Because you have data coming in from different sources. You have data in the database, and you have to understand. Data here. Data here. Data here.

Wes Bos

Portland didn't reference anyone yet. Okay. I don't know that reference. No. Okay. Someone will get it.

Scott Tolinski

If you have, like, a a to do app, that's way more simple. Right? It's like, I am a user. I've checked this to do. It goes up. Alright. Check the data in the database. Is it is it more recent or not? And the Fireflies will handle that stuff, but it's not easy. That's why a lot of these tools that you'll see around here are like, oh, we take care of the syncing. We take care of the local database, and we take care of the remote database. Okay. There are services out there that do that and do it well. I see. You're you're you're signing up for something. Right? You're you're buying all in. Whereas, like you said earlier, you might already have a database, and you might have a tech stack where you need to to work with that.

Scott Tolinski

Yeah. You will see projects in all phases of this this, like, I do everything for you to Yeah. I just handle the conflict part to I handle the sinking part to I handle you Node, there there's all sorts of different projects in the space. Okay.

Scott Tolinski

So in a much more complex app, like we've been saying, yeah, you have your your online app loads. It caches it to a service worker. It saves the data to a database, a local database, an IndexedDB database. In the background, it syncs to your remote.

Scott Tolinski

The remote syncs back to your local.

Scott Tolinski

The service worker is for offline. The data, once it saves local, it syncs to remote. If a data JS changed remote, it comes into a WebSocket and syncs to local.

Scott Tolinski

It I was telling my wife. I'm like, I'm trying to learn this stuff, but I feel like that GIF of Charlie from It's Always Sunny where everything's, like, connected. I'm like, this is this is literally the technology I'm trying to work with right now. It's just lines connecting everywhere.

Wes Bos

Oh, that's great.

Scott Tolinski

Yeah. So okay. Let's talk about some big concepts here. State lives in the database. They often talk about like, hey. When you use an app, and you leave the app Wes you come back to the app, usually, the state's like the same in all accounts, really. Right? You have Safari. You close Safari. The tabs that you had open are are still open. Those types of things.

Scott Tolinski

So one of the ideas here is that a lot of people are putting all kinds of app state directly into the IndexedDB, and they're even putting it into the DB no matter what. Because that way, if I set something on my phone, it's the same way in my desktop, it's the same way elsewhere. Right? So a lot of the state lives in in IndexedDB or in your database in general, just just to keep state everywhere.

Scott Tolinski

So that's like a really interesting, way that people tend to work in these things. Right? Just that that alone is a big shift from the way you typically think. And because of that, you'll see a lot of these apps, they do kind of take that space of a state management library like you mentioned. Right? Like, this electric DB has its own hooks, React hooks, if you wanted to have it be your React Native library. Yeah.

Scott Tolinski

So let's talk about some questions that people have. What about SSR here? Like, what JS server side rendering look like in this world? Well, the initial load necessarily isn't as important as long as the data gets into the IndexedDB. And as long as the service worker works, that initial server side could be a client side render only. It could be a server side render. It could be anything. That's not necessarily a concern. But I think that one thing you'll notice when you look into which application specifically benefit from local first architecture, SEO is not typically a concern for them. Yeah. Right? Maybe it's your landing page. Your landing page doesn't need to be local first. I mean, it that that could be simple. That's just a service worker. Right? But, like, does your to do list need to be server side rendered? Probably not. And because of that, you end up getting into spaces where you're only doing client side rendering and it makes things way easy. I know we we just had episodes on HD max. It's like throw everything back to the server. Yeah. And largely in this world, it's like, no. No. No. No. Throw everything onto the client so much to the point where everything runs on the client, even the database. You know? Man. Wes, eventually,

Wes Bos

it's kind of already a thing with the, whole web container spec is eventually, it'll be running the back end in the browser as well. You know? Like, that that's not a joke. That's what, who's behind web containers? I always mix up these Gitpod, Stackblitz.

Wes Bos

Stackblitz is behind them. Stack all these, like, coding in the browser things, Stackblitz is behind it. So Stackblitz has something that will run Node. Js in the browser, which is wild to me. But, yeah, it's it's it's I think this is the perfect example of, like, sometimes the tech depends on what you want. It's not 1 or the other. Right? It's not HTMX for absolutely everything, and client side rendering is garbage.

Wes Bos

Obviously, there's there's 2 sides to this type of stuff. And if you are going offline, you don't have a server.

Wes Bos

So you're you're going to need it. And and maybe that's that's even another question JS, like Wes talk a lot about, like, oh, it's super fast and whatnot. And I think a lot of people forget because they're they're dev ing locally on a gigabit hardwired Ethernet connection, and they don't realize, like, oh, yeah. There's there's possibility that these things could be slow or, like, somebody is ducking into the subway or you have spotty like, up at our cottage, I dry when I drive to town, I don't have Internet for probably 80% of the drive. You know? And Yeah. I have to, like, make sure that I have Spotify songs downloaded before I I take that drive. Otherwise, it's like, I gotta listen to the radio like some like

Scott Tolinski

cowboy. And it happens more than you think. And it's Scott, like, not necessarily offline conditions, but just slow conditions. I go to dance practice every Thursday.

Scott Tolinski

My Wi Fi signal, for whatever reason, a dance practice sucks, and I I need an app to help me practice. And I'm sitting at practice with my app to help me practice, and I click a button on it. And I gotta wait 10 seconds for a database response, and I Wes like, screw it. I I can't use this, and I made it. You know? I'm like, I'm responsible for this, and I can't even use it. Yeah. That well, that's another good example is,

Wes Bos

like, Riverside.

Wes Bos

What we're recording on right now will saves your thing locally and uploads as it can rather than assuming a fast Internet connection. And, obviously, Riverside is not a local first application because we're talking to each other over the Internet. It won't work without the Internet, but parts of your application can be local first. And you might wanna think about like, oh, yeah. Maybe there are pieces of the application that need to be local first with this tech.

Scott Tolinski

Yeah. There's tons of applications where this makes a lot of sense, and there's tons of applications where it doesn't make a lot of sense. Would your does your blog need to be local first? No.

Wes Bos

I mean, you could load it via a service worker, and it could be Service workers would be enough so that Yeah. Somebody who's coming back to the coming back to it can get it immediate. Or if if, like, you're taking a flight on a plane and you wanna download my entire blog so you can read it, you could do that. I you can't do that right now. I don't I don't have that on my website, but you could. Yeah. I should. But, you know, the there's apps that have done that. You know? Wes it, like, was it Dash or one of these apps that was, like, docs offline? The docs offline?

Scott Tolinski

That's the same concept. Right? You're saving these things for offline or even you think about, like, you know, I I go on a flight with Netflix, and I wanna save some movies offline for my kids. Right? I mean, there are a lot of instances where this stuff makes a lot of sense. Yeah. MB has that, and MB JS built on Wes tech. Right? So, what about this Apple PWA nonsense? Because I know it's inevitable that people are gonna be like, I wanna do local first, but Apple killed PWAs.

Scott Tolinski

And you're not wrong. Apple sucks for that, but it doesn't really affect many of the things that we need here. Right? IndexedDB still works.

Scott Tolinski

Service workers still work. WebSockets still work. So regardless of what Apple does here, many of these these technologies that you need to do this stuff won't be affected by that. Did you see?

Wes Bos

Just talking about the Apple thing.

Wes Bos

It's funny because, we'll talk about this, and it'll probably change by the time this is out. But, did you see that the EU is looking into Apple's removal of of PWAs or their their treatment of it? People freaked out, man. Yeah.

Scott Tolinski

So hopefully that that changes. They look at it so hard that, they they feel Apple feels really bad and changes their decision. You Node? Yeah.

Scott Tolinski

You just look in your life. I'm disappointed. I hope so too.

Scott Tolinski

Yep.

Scott Tolinski

Okay. You might be thinking I recognize a lot of these things from real time in multiplayer. We talked a little bit about this, but, yes, the same technology is frequently used in multiplayer stuff. You'll often see CRDTs talked about just as much in multiplayer application as you do in WebSockets.

Scott Tolinski

Figma has a ton of articles on CRDTs and and technology that they've developed there or how they do syncing.

Scott Tolinski

That stuff is extremely fascinating even if you're not building Figma.

Scott Tolinski

You might be thinking, hey. This all sounds like too much work. Well, triple it Scott dev is just one of many services that I found that handles everything for you. If you want, like, the supabase of this stuff, Triplett.

Scott Tolinski

Triplett is an open source database. You can host it yourself that syncs with data between the server and the browser in real time. It gives you TypeScript, real time sync, offline support, relational queries, works everywhere.

Scott Tolinski

Doesn't doesn't matter which, frame front end framework you wanna use it with, even React Native. Right? So if you want the easiest possible solution, there's stuff like that.

Scott Tolinski

Again, you're paying for it, or you're hosting Vercel, even better. Right? That sounds neat.

Scott Tolinski

Electric SQL is like the next step down. If you don't mind a little bit of work, Replicache is the way to go.

Scott Tolinski

There's more like evolu.evolu.

Scott Tolinski

Oh, I don't know. Play on the word evolution or something Scott dev, which is also really interesting because it use Keasly, which is an ORM that people are liking.

Scott Tolinski

It has a CRDT. It uses SQLite in the browser.

Scott Tolinski

Yeah. A lot of cool stuff. If you wanna go as deep as possible and you wanna become, you know, a Jedi master at this stuff, go to Yjs.

Scott Tolinski

It's it is intimidating.

Scott Tolinski

It will kind of make you, a little frustrated at points and just a little bit frustrated at points, but it's, definitely worth it to if you're interested, like, seriously interested in this tech, it's worth it to spend the time learning Yjs even if you're not going to use it simply as a means of getting a better handle on this stuff overall. Sometimes I think that, like, people always reach for the service. Right? Why reinvent the wheel? The wheel's already been fixed. But sometimes, reinventing the wheel exists to help you understand concepts and help you learn, even if maybe that's not what you're shipping. But there's no harm in learning the underlying tech behind a lot of this stuff even if it is obnoxious and hard.

Scott Tolinski

I have some links for you here. Local first web Scott dev is the best place to really get a handle on the players in this world. There's a great, YouTube channel where they post their monthly meetings. In fact, Wes, one of their meetings is literally going on right now. Kyle Simpson from You Don't Know JS is speaking right now on Discord, and this will be published later on the low.phi_dev YouTube channel that we'll have linked up. The Ink and Switch blog post is well worth your time.

Scott Tolinski

And then the local first Reddit, they post all of the past shows, the same stuff that's on the YouTube if you are interested in that. The last link I'm going to have for you here is something I'm putting up right now.

Scott Tolinski

And you you don't it's not in the in the notes yet, Wes, but I'm putting it up at this very second. And it's a repo that I made.

Scott Tolinski

It's SvelteKit, but the SvelteKit stuff is kind of minimal. Okay? And what's interesting about this repo is I did a basic offline or local first counter. Just counts up. Doesn't even count down. Just counts up.

Scott Tolinski

And I did it in both JS, and I did it in RepliCache. So I did it in both of those 2, and you can kind of compare them directly and say, alright. This is what it looks like in RepliCache. This is what it looks like in JS. And it's just the local parts. This does not get into the server side or syncing to a database just yet. But I I hope to expand upon these little demos even more because it's truly fascinating stuff.

Wes Bos

Scott, man. I I can't believe how much of a, like, a huge community this type of thing is. You know? Like, this is fairly fairly large, so I'm pretty excited to to dip into this and maybe build something myself.

Scott Tolinski

Yes. I'm my eventual goal here is to get my habit tracker working in a way that's offline.

Scott Tolinski

But if you're trying to add this to an existing site, man, there's so many moving parts and, like, I don't wanna mess up my existing database and data stuff. Scott, like, what I'm doing thing. It's tricky.

Scott Tolinski

I'm getting I'm getting, like, basic examples working, then I'm getting a to do list working, and then I'll integrate it into my habit tracker. But that's the eventual goal. Right? Did you just open source it, your local first

Wes Bos

example? Was that you? That was me. I just got a notification.

Scott Tolinski

And I'll put it in the show notes. Local first and text. It doesn't have a read me just yet, but, again, it's just 2 2 SvelteKit sites, Replicash and Yjs. They're both client side only.

Scott Tolinski

They both have instructions, WebSockets. They have a service worker. They they have all the important stuff. They both work offline, and they both sync across browser windows.

Scott Tolinski

So sweet.

Scott Tolinski

Let's get into some sick picks.

Wes Bos

I'm gonna sick pick. I kinda already did mine. I'm sick to pick this Wes code Scott dev. That's the euro where you can get a shirt like this. It's pretty sweet. I forgot to say that, like, for people not on the video, the there's, like, a really nice chenille patch on the front, and then the the back is is puff print, which is really popular right now. Patch. What do you mean by that? What's Chanel? I can go yell at my wife. She knows all these things.

Scott Tolinski

Oh, Chanel? Like, the bright

Wes Bos

the No. Did your wife say Chanel? I trust I trust her judgment on Node side. I I just read it, and I I probably read it wrong. Hold on. Let's see.

Scott Tolinski

Are you talking about, like A wool The French Scott luxury brand? Or no. That's Chanel. Node that's what I was I thought you were talking about Chanel. Chanel.

Wes Bos

Chanel is like, like a fuzzy patch.

Wes Bos

You know? Like, if you were to get, like, a Letterman jacket from the nineties, you know, like, the the captain c would be kinda fuzzy. That's chenille.

Wes Bos

And, I actually looked into getting syntax chenille patches, but a couple of the suppliers were like, you you have to go very large to for this. But this is this is the smallest chenille patch I've seen, so curious how they did that. Anyways, chenille on the front, puff print on the back, sick ESLint, super high quality. Check it out. Wes code

Scott Tolinski

.dev. Nice. I, I got a lot of letters, like, varsity letters in high school, but I never got the jacket. So so I have the the the big letters, but I never got the jack because our our school colors were orange and brown. I was like, who wants an orange and brown? Yeah. I don't want that.

Scott Tolinski

Carnies were blue and white. They were way cooler.

Wes Bos

American high school just seems so wild. Like, I grew up watching, like, Clueless and Sabrina, the Teenage Witch, and all these movies where, like, people are having lunch outside, and, like, they would have, like, jackets that's, like, for the football team and American football. And Canadian high school JS not not nearly as cool as that. We had flag football. That was it.

Scott Tolinski

Well, I got my varsity letters for do you wanna guess what I got my varsity letters for, Wes?

Wes Bos

There are 2 different things I got varsity letters for. Okay. I'm gonna say, like like, one of them's for something like like standing long jump or something silly like that.

Scott Tolinski

And then Node of them I wish I'm a bad jumper.

Wes Bos

Is cool.

Wes Bos

Wrestling.

Scott Tolinski

No. I'm gonna tell you right Node, neither of them are cool. I got, 1 Node letter for academics, for maintaining above that.

Scott Tolinski

For maintaining a high GPA for 3 semesters or something.

Scott Tolinski

Oh, And then my other one was for band. So I got band and academics, which are probably the 2 coolest varsity letters you can Keener.

Wes Bos

I called, like, I called somebody a keener the other day, and my older sister was like, what's a keener? I was like, you are a keener if you don't even know what a keener is.

Wes Bos

That means I'm a keener. I've never heard that. No? Oh, man. No. How many words do I know that are not something that people understand? The amount of people that Canadian word.

Scott Tolinski

Is it? Kieners Canadian. Yeah. It's a Really? Dictionary.com says a Canadian informal

Wes Bos

Oh, really? Yeah. I've never heard of it. Lot of sense. The amount of people that have said that they like, every now and then, tweets go popular from, like, the Korean web development community, and I translate them. And it says, learn English by listening to syntax. And I'm just like, these poor people are learning English from me and Scott.

Scott Tolinski

Yeah. Yeah. I I famously, tested into English as a second language in college. They they my the adviser was like, yeah. I know you you took the test. You did your well, you got into the University of Michigan, but, unfortunately, we think your writing is so poor that we wanna put you with the people who don't speak English.

Wes Bos

You're ruining a generation of of people.

Wes Bos

Anyways.

Scott Tolinski

Okay. My sick pick is going to be monarch money.

Scott Tolinski

You know, since ESLint shutdown, a lot of people are looking for a mint replacement.

Scott Tolinski

This one is not free. So, it's it's not necessarily a Mint replacement in that regard.

Scott Tolinski

But a lot of these financial tracking apps, I used Empower, which is formerly Personal Capital.

Scott Tolinski

I've used YNAB for budgeting. I used Mint. I used a whole bunch of these. A lot of them fall short in a lot of different ways. Right? Like Personal Capital does investments really Wes, but sucks for budgeting, and the UI has been garbage forever.

Scott Tolinski

YNAB is really great for budgeting, but sucks at everything else. And honestly, it has not seen an update in a very long time.

Scott Tolinski

Monarch does everything really well. The budgeting features are great. The UI is really great. It's the same price as YNAB, so I was able to just swap them out.

Scott Tolinski

And it does investments really well. One of my favorite things about this is that it, like, one of those charts where you can see, like, how data flows. Like, they're often used in analytics to show you how people went from web page to web page. Yeah. This shows you where your money is going. So it has all your money over the month, and then it shows this much went over to rent, and this much went to your car, and this much went to groceries.

Scott Tolinski

Sankey guy. Ram. Visualize. Sankey.

Wes Bos

Yeah. I was I went deep into the different names for charts on, the other day with the Nivo Nivo charts. Yeah. Nivo. Because I was trying to figure out, like, what certain charts were called, and then they all have crazy names. The whole data we gotta we gotta put that episode out on oops. I'm a data scientist because there's Yes. That's a whole world. But you so have you not tried actual budget from James Long? Local first. Yes. Let me tell you about actual budget because I have tried actual budget, and actual budget's fine.

Scott Tolinski

There's a a lot of these financial tools,

Wes Bos

a lot of them,

Scott Tolinski

that want you to export your information from your bank, import it into the app, or even worse, hand enter everything.

Scott Tolinski

Yeah. There's no syncing. Right? So, like, they oftentimes use Plaid, for syncing, which connects your your to your financial industry, what or your your wherever your account is and imports all the transactions. If it does not have syncing, I'm not touching it. Not because, like, I I get that there Yarn some security implications there of, you know, giving some of them deals your credentials. Yeah. But if I want to actually use a tool, I'm not gonna keep up with it. Yeah. Every week, I have to input my my money. Oh, man. That drives me crazy. I've been

Wes Bos

battling with FreshBooks for probably 2 years now because their auto syncing from my bank account has stopped right about the time they stopped sponsoring the podcast.

Wes Bos

Oh.

Wes Bos

It's it never works. And, like, I had a I had a whole call with them. Like, I emailed their CEO. I was like, this FreshBooks is, like, crumbling. Like, this the quality of it is just going downhill, and, like, this thing has never worked properly. And they they keep blaming it on, like, these plaid vendors and whatnot, but, like, I had to write my own exporter and converter that converted QuickBooks format to CSV just to import my expenses.

Wes Bos

But Holy cow. Yeah. And it sucks. It it this stuff should be automatic. Right? And that JS well worth paying for. I totally agree with you there.

Scott Tolinski

Yeah. Well and and and if you are gonna pay for 1, I gotta say, Monarch is great. The the the coolest thing, maybe not the coolest thing, is the web app is way better than the native app. Like, how often do you see that? The web app is is incredible.

Scott Tolinski

The desktop app adds a whole ton of extra features. Either way, if you're even looking just for UI inspiration for this type of thing, they do a great job. I do have a referral code. So if you want, if you want to give me that referral, you can click that link. Otherwise, it's just monarch money.com.

Scott Tolinski

So, yeah, a big fan of this. Obviously, not sponsored or anything. It works in Canada.

Wes Bos

I just assumed JS all things, we don't get it in Canada, but it's it's available in Canada.

Wes Bos

There's probably some, yeah, buts in there, but cool. I'll check it out. Yeah. It's a cool app. Alright. Thanks everybody for tuning in. We'll catch you later.

Scott Tolinski

Peace.

Share