Announcing Starbeam: Universal Reactivity

Rate this content
Bookmark

Starbeam is a library for building reactive data systems that integrate natively with UI frameworks such as React, Vue, Svelte or Ember. In this talk, Yehuda will announce Starbeam. He will cover the motivation for the library, and then get into the details of how Starbeam reactivity works, and most importantly, how you can use it to build reactive libraries today that will work natively in any UI framework. If you're really adventurous, he will also talk about how you could use Starbeam in an existing app using your framework of choice and talk about the benefits of using Starbeam as the state management system in your application.

27 min
20 Jun, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Starbeam is a library for building reactive user interfaces with JavaScript, similar to Svelte, Vue, and Ember. It provides a data structure and query feature for filtering and sorting. The useStarBeam function ensures JSX reconciliation only occurs when reactive dependencies change. Starbeam tracks every read and write operation to update the component accordingly. It can be used with React and other frameworks, and offers debugging tools and locale integration.

Available in Español

1. Introduction to Starbeam

Short description:

Today I'm here to talk to you about Starbeam, a library for building reactive user interfaces with JavaScript. Starbeam is not the next hot new JavaScript framework. We have similar examples in Svelte, Vue, and Ember. Let's start by taking a look at the app we're going to be building. It has a form to create new users, filtering, deleting items, and more.

Hi, everybody. Today I'm here to talk to you about Starbeam. Starbeam is a library for building reactive user interfaces based on the guiding principle that if you write your reactive code just like any other code, you can build a radically simpler, more reliable user interfaces with the JavaScript skills you already have.

Now, people have said a lot of similar things like that before, so I don't blame you for being skeptical and jaded. Before I get started, I want to be really clear about something. Starbeam is not the next hot new JavaScript framework. The demo I'm doing today uses Starbeam inside a React app, and we have similar examples in Svelte, Vue, and Ember. The people who work with me on Starbeam are pretty tired of the way that new front-end ideas are always packaged up with a whole new framework you need to migrate to. We think we can do better, and I hope that by the time I'm done here, I'll have piqued your interest.

Let's start by taking a look at what the app that we're going to be building looks like. Here's the finished app. So we have a form we can create some new users. I can write leah-silver-portland. I can append it. As you can see, once I have appended it, there is some information on the bottom about what happened. I can filter. I can write portland...here. And when I do that, you see that this changes to say two filtered out of five. I can delete items while I'm filtered. Everything works as you would expect. I can delete all the items. I can add people back in. Like that. And that's about it. That's basically what this app does.

2. Data Structure and Query Feature

Short description:

Let's start by using the non-finished version of the demo. The data that backs our component consists of a table with rows and columns. Each row represents a person with a name and a location. We can append, delete, and clear rows. Additionally, we can use the query feature to implement filtering and sorting.

Well, the very first thing I want to do is change to using the non-finished version of the demo. So let's start there.

Okay, great. And as you can see, there's some features here already, but nothing, there's no filters. There's nothing that made it very interesting. And more importantly, nothing works here.

Before we get started, let's take a look at the data that backs our component. Now it's a little bit of an involved JavaScript thing here, but the reason it's involved is less that Starbeam cares that you do anything interesting here and more that I want to show that even if you use pretty advanced fancy JavaScript features, everything still continues to work.

So let's take a look at the first piece of this, which is the table. So a table has an ID which starts at zero and that's what we can allocate IDs as we create new rows. We have a list of rows, which is a map from a string to a row. Now what's a row? Well, here we have an example of a person. So a person has a name, which is a string, a location, which is a string, and all a row is is that thing plus an ID added to it. So we're going to map from the ID to a row of a person, in this case, and that means it's going to be the person plus an ID. We're going to take a bunch of columns so that we have a way of reflectively creating headers. We're going to have a getter for rows. So what does the getter for rows do? It gets the values out of our map and splats it onto an array. This gives us an array back. How do we append a row? Well, we make a new ID as a string and then we make a new object that contains the ID and the columns that we specified, and then we set the string ID onto the map and give it the row as the value, return the row, pretty vanilla stuff. How do we delete an ID? Well, we delete it from the row. How do we clear rows? We clear the map. And then there's one additional feature here, which we're going to use to implement filtering, which is the query feature. So what is query? A query is another very simple object. A query has a table that backs it, and then it has a bunch of filters and an optional sort. What's a filter? It's a thing that takes a row and gives back a Boolean. What's a sort? It's a thing that takes two rows and gives you back a number, which is what the compare functions do. Okay, now what happens if you ask for a list of rows from a query? Well, the first thing that happens is that we get the rows from the table, and as a reminder, that does this splatting thing. Then, we loop through all the rows and we make sure that all the filters match the row. And then if we have a sort, we sort the filtered things by the sort, otherwise we just return the array. So basically it's a little object, wraps a table, has some filters, and gives us back new rows.

3. Data Structure, Query, and App Component

Short description:

So, that's the table and the query. The people class has a table and a query. There are two convenience methods for sorting and filtering. The filter method adds a filter to the existing query based on text. The sort method sorts the values in the query's column using the Intel API and returns a new people object. The important thing to note is that there are no reactive concepts or special objects. Now, let's look at the app. We have the useStarBeam hook that wraps the component and allows access to reactive data.

Okay. So, that's the table, that's the query. And then we have a little people class. So what is a people? Well, it has a table of person, it has a query of person. And then what happens, if you get the table it gives you back the table. If you get the rows for people, it gives you back the query's rows. And then there's two convenience methods for adding sorting and filtering.

Let's look at filter first. So you can filter based on text. What it does is it takes the existing query, it adds a filter to it that checks if the row's name includes text or the row's location includes text, and then it returns a new people object with the table and the query. Then, what does the sort method do? It takes a column, so that would be a name or location, and then it takes a locale. The reason it takes a locale is because we're going to want to use the Intel API to sort things so that we get the right behavior for different languages. And this looks like a lot of things are going on here, but really all that's going on is we're making a new collator for the locale that we passed in, and then we're giving query a sort, which is going to get the values out of the column. So let's say we're sorting by name, so we're going to get the name out, and then we're going to use the collator from intel.collator to compare, and it gives back a new people so that when we go to get the rows, it does the right thing.

Now, here's the most important thing. You didn't have to follow necessarily all of that, but the thing to note is that there's no reactive concepts in here. This is just an object. Locale is just a string. There's nothing about hooks. There's nothing about needing to run something multiple times. There's no special kind of objects that you need. There's no piping. There is one place that we've seen so far where we have a reactive object, which is right here, this reactive map. But other than that, all we've seen so far is just functions that work with that, ultimately that underlying map and produce new values. Okay, so that's basically how the data works under the hood. And now what we're going to do is we're going to go look at our app. So we replaced the app already with the unfinished data table, and now let's take a look at the component. So, the first thing that you're going to notice here is that we have this useStarBeam hook and useStarBeam basically wraps your entire component, and its job is just to get you into StarBeam mode so you can access and work with all of the reactive data. Now, inside of StarBeam, inside of a useStarBeam component, there's two sections. There's the top section, everything up until the point where you return this JSX chunk.

4. The useStarBeam Function

Short description:

The useStarBeam function has two parts: the top part runs once for setup, and the bottom part, a callback, runs repeatedly for JSX reconciliation. StarBeam ensures that the callback only reruns when its reactive dependencies change, similar to React.Memo.

So the top part of a useStarBeam function runs exactly one time, and it's a good place to set up stuff like this table that you only want to set up one time or functions that you don't want to have changing under you. And the bottom part, this callback, this chunk of JSX, that's the thing that runs over and over so that React has JSX to reconcile. But the critical thing here is that StarBeam makes sure that it doesn't rerun if none of the dependencies, the reactive dependencies that are used inside of the callback run. And we'll see what that means in a minute. You can sort of think of it as a React.Memo on steroids.

5. Implementation Details

Short description:

Let's take a look at the actual implementation. We have a JSX form that currently doesn't work. We loop over the columns and turn them into THs. There's also an option to clear all rows. We loop through the rows, creating TRs with TDs for each person's name and location. We can also delete individual rows. Finally, the summary section displays the total number of items.

So let's take a look at the actual implementation here. So we have a JSX. We have this form here. And you'll see if you run the form, you can see that the form doesn't really work. Right? Because if we look at what the append function does, it doesn't do anything. So we'll take a look at that form in a second.

Then we loop over all the columns on the table. And, just remember, the columns are just a field that's on the table. And we turn them into THs. And then we have one last TH here that gives you the ability to clear all the rows. And that's what happens if I clear all the rows. We'll talk about that in a second.

Then I loop through all the rows that I have. And for each one, I make a TR. I give it the key of the ID that we created. And then I give it TDs for the person and the name and the location. And then I have one final action here which allows me to delete the person.id. Now I just want to reiterate, when you click on, when you look at clear, that's just doing rows.clear. When I do Table.deletePersonId, that's just doing rows.deleteId. So even though these are callback functions that are happening inside of here, they're happening inside of JSX, you didn't have to do anything fancy here. They're working with StarBeam data. OK.

And then finally, we have this summary section over here. And the summary section has a data items attribute of the length. And that's basically so that when there's zero of them, there's some CSS that makes it look different. And then we have a TD, which prints out the total. And what is the total? Right now, it's very simple. It just says items, colon, Table.rows.length. OK, cool. Now, what I want to quickly look at here is, so we already have some interesting data here, right? If I reload and I start deleting things, you can see that there's already items 2 here.

6. Reactive State and Form Implementation

Short description:

We don't have any kind of useState or dependency arrays. The way it works is that when you get the rows of the table, it gets this.rows.values. StarBeam knows that when you do this.rows.values, that means you are reading the iteration of the whole map. It doesn't matter if we specifically use people.rows or if we use it through something else. When you say table.deletePerson.id, Starbeam knows that this people.rows.length invalidated and re-renders the JSX. We have a non-working form with e.preventDefault. The form has an OnSubmit, input fields for name and location, and a submit button.

You can see that the array got filtered and stuff like that, right? And so how did that happen? What exactly happened here? So notice that we don't have any kind of useState. We don't have any dependency arrays. We're not using React concepts really at all. So how does that work? So the way it works is that if we go back and look at our table, like I said, there's this little piece of reactive state here. And when you get the rows of the table, it gets this.rows.values. And StarBeam knows that when you do this.rows.values, that means that you are reading the iteration of the whole map. And that means that whenever anything changes the iteration of the whole map, that will invalidate the read of this.rows.values.

But the thing is, we don't actually use the table rows directly most of the time. What we mostly do is use it through other abstractions. And we'll see that's going to get more and more elaborate over time. And so the point is that it doesn't matter if we specifically use people.rows here, or if we use it through something else. The fact that we access the data that is inside of people.rows somehow. So people.rows, just as a reminder, is not actually directly... It's not the table, it goes to the query. And the query, as a reminder, goes to the filter, right? So there's actually a lot of steps in between what looks like, oh, it's just the rows, and that piece of state. But you don't have to say anything about that. You're able to just write normal JavaScript code here.

Okay, so that's great and all. And what that basically means is that when you say table.deletePerson.id, Starbeam knows that this people.rows.length invalidated, and therefore knows to re-render the template. Not the template, the JSX. So what's the next thing we want to do? Well, we have a non-working form here in this append, so let's go and implement it. So the thing we have right now is we just have e.preventDefault. Let's take a quick look at the form. So we have a form here, and it has an OnSubmit. And then we have inputType="text", name="name". So we're using the HTML way of giving it a name. We're saying it's required. There's some CSS stuff here for errors. And the second input field has the name of a location. We have a buttonType="submit", right? So that just means that when we hit Enter, we hit Tab and Space, we click whatever it's going to hit, it's going to call the Submit.

7. Form Data and Table Append

Short description:

To get the form data, we extract the form and convert it into an object using form data. This object contains the valid field names and their corresponding values. We then use the append method to add the name and location columns to the table. After that, we reset the form. This process works because Starbeam tracks every read and write operation and updates the component accordingly.

So what do we want to do with that? Well, the first thing we need to do is get the form out of the event. And the second thing we're going to do is we're going to make a new form data out of the form. Now, if you don't know what a form data is, it's pretty interesting. What it basically does is it takes the form, it gets all the names of fields that are valid, in other words non-disabled fields and stuff like that, and it turns it into an object that has those keys and those values. And what's really cool about form data is that it implements iterable of entries. So you can just say object.fromEntries of a form data, and you get back something that looks exactly like what you would expect. It's a little bit of incantations here, but we take a form, we make a form data, we do object.fromEntries, and we get back this. We get back an object that has a name and location, which is precisely what we want. Our table has an append on it. The append takes columns, which is the name and location. And when we're done with that, we're going to reset the form so it empties out what we already did. So at this point, we would kind of expect it to work, I think. So let's check. I'm going to add Lea-Silber, and I'm going to add Portland, and it worked. Great. So why did that work? What exactly happened here? So what basically happened is that when we clicked on table.append, that set a row on the map here. And because other parts of that same component read from, ultimately, the this.rows.values over here, which is in iteration, the fact that we added something to the map means that it invalidated anybody who tried to read, anybody who cared about the iteration, right? In other words, because I cared about, because at some point I computed a list of all the keys and the values, if the keys and values change, then anybody who read the list of keys needs to recompute, right? So the fact that I called append, it looks like, you know, I'm just mutating an object, Behind the scenes, Starbeam keeps track of every read, every write, and links them up together. Cool.

8. Implementing the Filter

Short description:

To implement the filter, we need a cell to store the filter value. The query will be based on the people table and will use the filter function. By accessing filter.current, we can modify the cell with the current target value. The rows will now return the query rows instead of the table rows, ensuring that the component depends on both the filter and the rows.

Okay, so now that we did that, the next thing we probably want to do is implement the filter. So in order to implement the filter, we're going to need a cell. So a cell in Starbeam is just a very simple object that is a space for storing one thing, right? So we have a cell here, and it's a space for storing a string because the filter is gonna have a string in it.

We're gonna want to make another field here that's just gonna be our filter. So what does that field look like? Well, it's going to have a default value of the current filter.current, and so filter.current is reading from that cell, right? So that's a thing, it's a reactive thing, it's reading from the cell. And what happens when you type something in? No problem, we set the filter, so filter.set is how you modify a cell with the value of the current target, right? So now, if I type something, I was able to type in the filter, but we didn't do anything yet, so we still need to do something here.

So in order to make it useful, we don't want to just make the rows just a bunch of rows, we want to make a query, right? So what's gonna be the query? The query is gonna be the people table that we have, and we're gonna use that filter function that we wrote before to filter based on filter dot current. Now note, just accessing filter dot current in here is enough to know that we're accessing the underlying filter. So we have a function here called query, it's a regular function, nothing special here, and we're making a new query, which filters by the thing we typed here, and we're also gonna sort by the locale for good measure.

Okay, so now that we did that, we're just gonna update the rows here to return the queries rows instead of the tables rows. And now if I type something, Portland, Yehuda, right, if I type Sherag, if I type NYC, right, all that worked. And so why did that work? Well, part of why it worked is that the filter does this somewhat complicated thing, right, it goes and for each row, it checks if the name or location includes the text. And when we said query.rows, that's the thing that actually went ahead and ran the filter, right? So again, this is just pretty normal JavaScript code. And all we did was make a new function here called query. And all we did was make our existing function rows use the query. But the fact that this code down here, the code that loops over says rows, the fact that that accessed the query, what does that mean? It means that it has a dependency on two things. It has a dependency on this filter thing. And it also has a dependency on this rows thing, which has a dependency ultimately on the table rows, which is this iteration. So basically, just the normal way of accessing, the normal way of writing code here means that our computation of rows here caused StarBeam to know that this whole component depends both on the filter and it also depends on the rows.

9. Adding Filtered Item Count Feature

Short description:

In this part, we add a feature to display the number of filtered items. We replace the total function to calculate the number of rows in the query and the total number of rows in the table. If they are the same, we return the previous value. Otherwise, we display the number of filtered items over the total number of items. This implementation demonstrates how dependencies are automatically tracked and updated in Starbeam.

Okay, so one thing that I think is worth noting here is that there's surprisingly a few pieces of root state here for a pretty complicated setup. So we're going to add one more feature here and what we're going to do is we're going to make it so that if we filtered something, we want this to not say items for, we want it to say items some amount of filtered over for, right? So how are we going to do that? We're just going to replace this total function here. The first thing we're going to do is we're going to get our rows and that's going to be the amount of rows that were in the query, right? And the second thing we're going to do is we're going to get the total number of rows in the table. Now, if the two things are the same, the filter count and total count, we return what we had before. Otherwise, we say items filtered count filtered over total count total, right? So if we just reload the page, obviously nothing happened here. But if we start filtering, we say Gerog, we say NYC, we can see it worked. And once again, this total function has a dependency on rows. It has a dependency on table.rows, right? It has a dependency. And what does rows have a dependency? It has a dependency on the query, which has a dependency on the filter. So all this is just a pretty natural way of writing normal code without having to write anything special, without having to say anything special about how things are connected to each other. And it all sort of works out.

10. Debugging Tool and Dependency Tracking

Short description:

Now, let me show you a debugging tool in Starbeam that allows you to see dependencies more explicitly. By grabbing the logger from Starbeam debug and setting the logger level to debug, you can open the dev tools and see additional information. The debugging tool shows the dependencies of the useStarBeam block and allows you to track invalidations. You can also assign names to pieces of root state to make the debugging tool less noisy.

Okay. Now, I keep saying things are dependencies of other things. But you sort of have to imagine that. But let me show you a little debugging tool that we have that lets you see it more explicitly. And to turn it on, we're just going to grab the logger from starbeam. We're going to grab the logger from starbeam debug. Debug. We're going to say logger.level equals loglevel.debug. Debug.

Okay. And now once we do that, if we open up the dev tools, we see that we're starting to get some additional information. It's showing us that this use starbeam block, which is located over here. Let's pull that down. You can see exactly where it's located. It tells you that that has a dependency on this cell, has dependency on this map. I'll make it a bit smaller.

Okay. Now, the next thing that we can do with this debugging tool is if we invalidate something. Let's say we go back to this filter here and we say see. What we're going to see is that it tells us that use starbeam invalidated and tells us exactly what invalidated, which is this cell here. It gives us a link to exactly this location. Now, this is a little bit noisy. Built into this setup is a way of saying for each new piece of root state, you can give it a name. Here we can say cell, we can give it a name of filter. And we can go to our table and we can say I already did it. I gave map a name table, right? And we can go to, I think those are the only pieces of state, right? So now if we look at it, we'll see that it gives us the names instead of the very long words. And if you wanted to turn it on and you wanna see the stack traces anyway, the longer links so you can click on them, you can just always turn it on to trace mode. And that will give you the links no matter what, right? So you open it up and you always have these links here, great. Let's turn that off, okay. Now we have one last feature that I wanna implement.

11. Locale Integration and Sorting

Short description:

We want to pass the locale directly into our component. To achieve this, we use the useProp hook provided by Starbeam React. By changing system locale to locale.current, we can bridge the gap between React and Starbeam. This allows us to sort words differently based on the selected locale, as demonstrated with the word 'name' in Swedish.

Which is so far, everything is self-contained inside of StarBeam. But like we said, this is inside of a React app. And so we really would like to be able to have this component take some arguments from React. So in this case what I wanna do, instead of just using the system locale as a sort, I wanna get the locale from the React app.

Okay, so in order to facilitate that, I created a locale switcher here. So we're just gonna implement it using a pretty normal React pattern, right. We're gonna use state. We're going to just gonna grab some stuff here. I'm gonna format the locale. But it's a select box, right. It sets the state. And now that we did that, if we turn it on over here, right. And we can see that we have the select box.

And what we would like to be able to do, is just pass the locale directly into our component. And of course, there's no reason why we wouldn't be able to do that. This is just a regular React component. So we can say props locale string here. But there's a bit of a problem here, which is that the way React works is it's just gonna keep calling this function over and over again with new props, but Starbeam doesn't really have any idea what that's about. And so we really need a way of turning this locale into something that Starbeam understands. And for this kind of situation, there's a hook that we provide called useProp. So we can say cons locale equals useProp props.locale. Okay, we're gonna pull in useProp from Starbeam React. And now all we gotta do here is we just have to change system locale to locale.current, right, so that just shim the React world into the Starbeam world.

And now here's why I set it up this way. So this unwanted word, name, is differently sorted in Swedish and other languages. So let's switch to Swedish real quick. And as you can see, it's now sorted at the bottom. Let's bring back up our dev tools. And now what we can see is that we actually have three pieces of state here. We have this cell, the filter cell.

12. Dependency Tracking and Universal Libraries

Short description:

We have the Prop and the Map. The function has dependencies on filter, props, and the Map. StarBeam tracks these dependencies and invalidates when they change. Components using StarBeam do not invalidate each other. StarBeam can be used with React and other frameworks. You can write universal libraries using StarBeam concepts and adaptors. Come check it out on our Discord and GitHub. Join us and help with debugging tools and more.

We have the Prop and we have the Map that we've been talking about the whole time. And just like anything else, we can give this a name. So let's just call it props.locale for convenience in our debugging. All right, so now we can see, okay, we have those three things. And now if I go and select Swedish, you can see that that is exactly the thing that invalidated it, right? And if I was to instead type in like NYC or something like that, what we can see is that now we know the filter's the thing that invalidated it.

Now this is still a pretty early debugging tool. This is just a logging just for convenience. We would expect some more elaborate debugging tools eventually built on this infrastructure. But the basic idea here is that from StarBeam's perspective, this function over here has dependencies of just three things. Now one of the things the Map is a little bit of an elaborate thing so that we can do more granular tracking. But in general, there's only three pieces of root state. It doesn't matter that we have this total function, it doesn't matter that we have this rows function, it doesn't matter that when we go and look at this rows thing, it's doing this complicated going through multiple steps, it's doing this complicated filters thing, none of that matters. At the end of the day, the only thing StarBeam actually cares about is that it has a dependency on filter, it has a dependency on the props, it has a dependency on the Map. And whenever we go and change something, let's go create a new person, right? So let's make a new person, we'll make Leia again, and we'll say pdx, right? What you can see is that the thing that invalidated is the Map, right? So at the end of the day, even though there's a lot of complexity here in your code, that complexity is all in very standard, normal JavaScript stuff. And the reactivity is really just saying that this callback here, this thing that generates JSX, has a dependency on three things. It has a dependency on a Map, on the iteration of the Map. It has a dependency on a filter. And it has a dependency on the locale, the locale prop. And now all StarBeam has to do is keep track of those three things. Whenever they change, it invalidates and notifies React and invalidates.

The nice thing about this is that if you have a lot of components in your app that use StarBeam, each individual one doesn't invalidate any of the other ones. It's like I said, it's kind of like a souped up react.memo. So what happens is without you having to say anything, simply by accessing values using normal functions, using normal getters, using normal methods, using normal access patterns, you're telling StarBeam exactly what the dependencies are. And StarBeam is able to keep track of exactly when it needs to invalidate. You can shim into the React world pretty easily, too, if you need to, and that works totally fine.

Now, one thing that's pretty cool, I think that last thing I want to say here, is if you go back and look at our table, there's no actual imports from StarBeam React or from React, right? And that's because this code, this table code, this query code, this people code, this is all pure StarBeam stuff. And that means that this exact same code will work in Svelte, it will work in Vue, it will work in Ember, and that's pretty cool. It means you can start writing libraries that are kind of like this toy example, but bigger, something like a GraphQL library, and you can write it mostly in StarBeam, in StarBeam concepts, and then expose it to React, to Svelte, to Vue using these adaptors. You don't have to build universal code with StarBeam, you can just build stuff inside of the React app, but you also could build these universal libraries, and I'm pretty excited to see what's going to happen once the ecosystem has the ability to start writing reactive code in a way that's decoupled from individual frameworks. I think that's going to be really awesome. If you're excited by this, definitely come check it out. Come to our Discord, you can come to our GitHub, you can start, you can like it, you can submit issues, you can try to integrate it, you can try to do some work. You can try to help with debugging tools, there's so much stuff going on. I'm pretty excited about how far we already got, but there's still a ton left to do. And if you're the kind of person who likes getting in on the ground floor and making a run for something, great, join us, we're excited to have you. Thanks so much, and enjoy the rest of your conference.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
Top Content
When we think about Vuex, Pinia, or stores in general we often think about state management and the Flux patterns but not only do stores not always follow the Flux pattern, there is so much more about stores that make them worth using! Plugins, Devtools, server-side rendering, TypeScript integrations... Let's dive into everything beyond state management with Pinia with practical examples about plugins and Devtools to get the most out of your stores.
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
JSNation 2022JSNation 2022
28 min
Full Stack Documentation
Top Content
Interactive web-based tutorials have become a staple of front end frameworks, and it's easy to see why — developers love being able to try out new tools without the hassle of installing packages or cloning repos.But in the age of full stack meta-frameworks like Next, Remix and SvelteKit, these tutorials only go so far. In this talk, we'll look at how we on the Svelte team are using cutting edge web technology to rethink how we teach each other the tools of our trade.
React Summit Remote Edition 2020React Summit Remote Edition 2020
30 min
React Query: It’s Time to Break up with your "Global State”!
Top Content
An increasing amount of data in our React applications is coming from remote and asynchronous sources and, even worse, continues to masquerade as "global state". In this talk, you'll get the lowdown on why most of your "global state" isn't really state at all and how React Query can help you fetch, cache and manage your asynchronous data with a fraction of the effort and code that you're used to.

Workshops on related topic

React Summit 2020React Summit 2020
96 min
Rethinking Server State with React Query
Top Content
Featured Workshop
The distinction between server state and client state in our applications might be a new concept for some, but it is very important to understand when delivering a top-notch user experience. Server state comes with unique problems that often sneak into our applications surprise like:
- Sharing Data across apps- Caching & Persistence- Deduping Requests- Background Updates- Managing “Stale” Data- Pagination & Incremental fetching- Memory & Garbage Collection- Optimistic Updates
Traditional “Global State” managers pretend these challenges don’t exist and this ultimately results in developers building their own on-the-fly attempts to mitigate them.
In this workshop, we will build an application that exposes these issues, allows us to understand them better, and finally turn them from challenges into features using a library designed for managing server-state called React Query.
By the end of the workshop, you will have a better understanding of server state, client state, syncing asynchronous data (mouthful, I know), and React Query.
JSNation 2023JSNation 2023
170 min
Building WebApps That Light Up the Internet with QwikCity
Featured WorkshopFree
Building instant-on web applications at scale have been elusive. Real-world sites need tracking, analytics, and complex user interfaces and interactions. We always start with the best intentions but end up with a less-than-ideal site.
QwikCity is a new meta-framework that allows you to build large-scale applications with constant startup-up performance. We will look at how to build a QwikCity application and what makes it unique. The workshop will show you how to set up a QwikCitp project. How routing works with layout. The demo application will fetch data and present it to the user in an editable form. And finally, how one can use authentication. All of the basic parts for any large-scale applications.
Along the way, we will also look at what makes Qwik unique, and how resumability enables constant startup performance no matter the application complexity.
React Summit 2023React Summit 2023
106 min
Back to the Roots With Remix
Featured Workshop
The modern web would be different without rich client-side applications supported by powerful frameworks: React, Angular, Vue, Lit, and many others. These frameworks rely on client-side JavaScript, which is their core. However, there are other approaches to rendering. One of them (quite old, by the way) is server-side rendering entirely without JavaScript. Let's find out if this is a good idea and how Remix can help us with it?
Prerequisites- Good understanding of JavaScript or TypeScript- It would help to have experience with React, Redux, Node.js and writing FrontEnd and BackEnd applications- Preinstall Node.js, npm- We prefer to use VSCode, but also cloud IDEs such as codesandbox (other IDEs are also ok)
React Summit Remote Edition 2021React Summit Remote Edition 2021
71 min
State Management in React with Context and Hooks
WorkshopFree
A lot has changed in the world of state management in React the last few years. Where Redux used to be the main library for this, the introduction of the React Context and Hook APIs has shaken things up. No longer do you need external libraries to handle both component and global state in your applications. In this workshop you'll learn the different approaches to state management in the post-Redux era of React, all based on Hooks! And as a bonus, we'll explore two upcoming state management libraries in the React ecosystem.
Node Congress 2021Node Congress 2021
128 min
Learn Fastify One Plugin at a Time
Workshop
Fastify is an HTTP framework for Node.js that focuses on providing a good developer experience without compromising on performance metrics. What makes Fastify special are not its technical details, but its community which is wide open for contributions of any kind. Part of the secret sauce is Fastify plugin architecture that enabled developers to write more than a hundred plugins.This hands-on workshop is structured around a series of exercises that covers from basics "hello world", to how to structure a project, perform database access and authentication.

https://github.com/nearform/the-fastify-workshop
JSNation 2023JSNation 2023
66 min
Build a Universal Reactive Data Library with Starbeam
WorkshopFree
This session will focus on Starbeam's universal building blocks. We'll use Starbeam to build a data library that works in multiple frameworks.We'll write a library that caches and updates data, and supports relationships, sorting and filtering.Rather than fetching data directly, it will work with asynchronously fetched data, including data fetched after initial render. Data fetched and updated through web sockets will also work well.All of these features will be reactive, of course.Imagine you filter your data by its title, and then you update the title of a record to match the filter: any output relying on the filtered data will update to reflect the updated filter.In 90 minutes, you'll build an awesome reactive data library and learn a powerful new tool for building reactive systems. The best part: the library works in any framework, even though you don't think about (or depend on) any framework when you built it.
Table of contents- Storing a Fetched Record in a Cell- Storing multiple records in a reactive Map- Reactive iteration is normal iteration- Reactive filtering is normal filtering- Fetching more records and updating the Map- Reactive sorting is normal sorting (is this getting a bit repetitive?)- Modelling cache invalidation as data- Bonus: reactive relationships