Dan Abramov & Joe Savona from the React Team join Jerod & Nick for a wide-ranging discussion about React’s place in the frontend ecosystem. We cover everything from React competing with React, their responses to SPA fatigue and recent criticisms, to Server Components and the future of the framework.
Fly.io – The home of Changelog.com — Deploy your apps and databases close to your users. In minutes you can run your Ruby, Go, Node, Deno, Python, or Elixir app (and databases!) all over the world. No ops required. Learn more at fly.io/changelog and check out the speedrun in their docs.
Changelog++ – You love our content and you want to take it to the next level by showing your support. We’ll take you closer to the metal with extended episodes, make the ads disappear, and increment your audio quality with higher bitrate mp3s. Let’s do this!
|Chapter Start Time
|It's party time, y'all
|Welcoming Joe & Dan
|To what do we bestow this honor?
|React competing with React
|Reacting to recent criticisms
|There's no silver bullet
|React Server Components (RSC)
|The scope of RSC
|How to get started with RSC
|Grappling with RSC terminology
|RSC in production at Meta
|Sponsor: KBall Growth
|RSC as the skeleton
|The easiest way to think about it
|Resources for learning RSC
|Why Dan doesn't like TypeScript
|Next up on the pod
Play the audio to listen along while you enjoy the transcript. 🎧
Hello, friends. We are back for another episode of JS Party. I’m Jerod, your internet friend, and I’m joined by my friend on the internet and in real life - it’s Nick Nisi. What’s up, man?
Hoy-hoy. How’s it going?
I hear you’re famous now, Nick. You’re famous in the React documentary. Do you want to tell everybody how this happened, how you got on the React documentary? Because this will play into our conversation today.
I suppose so. Not nearly as famous as our guests, but… Yeah, I was there at JSConf in 2013, and I have a tweet that is highlighted in that documentary. I was a big Backbone fan in 2013, nice separation of concerns, and seeing that JSX was not great in 2013… But I have definitely come around. [laughs]
So you’re on the React documentary, eating crow, as one of the original skeptics of React, which then went to take over the frontend world. And we are joined today by two members of the React team. We have Joe Savona and Dan Abramov on the show. Welcome to the JS Party, guys.
Thanks for having us.
It’s great to be here.
Now, many people who are in the React ecosystem know Dan, because you’re very vocal, you’re a guy who’s in the spotlight, you talk to everybody, you blog, you write docs…
Twitter threads are legendary.
Yeah, legendary. But a little more behind the scenes, Joe - do you want to introduce yourself, your role on the team, and let the JS Party people get to know you a little bit?
Yeah. Maybe like five people in the world know me from Relay, but… Yeah, so I’ve been at Meta for about eight and a half years now. Most of that time I worked on Relay, which is our GraphQL client for React, but the last couple of years I’ve been working on React itself, really starting with Server Components. And more recently, I’m working on an auto memo-izing compiler for React, but that’s a bit further out and maybe not so much ready to talk about yet.
Not yet, so teeing up maybe a future conversation. So we’ve been doing JS Party for a long time now. Not 2013, Nick, but I think this is episode 267… And we’ve had members of the React team on the show over time. But this is our first time, I think, where we’ve been personally emailed by the React team - shout-out to Matt - and saying, “Hey, can we come on the show and talk?” And so I’m curious what you guys think about that. Either we’ve arrived, as a podcast, or there’s something going on, there’s something that happening out there in the world? What are your thoughts, Dan?
Yeah… So I think we wanted to get out a little bit more, because I think it is a very difficult balance to hit, because a lot of the projects we work on have a multi-year span, and I think sometimes we’ve erred on the side of talking about stuff a bit too early, before it was ready. And so that creates kind of like a hype cycle, and then people are disappointed, because there aren’t kind of more updates, or it’s just taking a long time to actually straighten out the story… And in some cases, things we kind of announced have been surprises. So I think we’re trying to strike a balance.
And I think what’s been happening recently is we’ve actually felt like the whole field got reenergized again. And you see, there are new players, so there are new libraries, there are new frameworks… And I think what we’re seeing – one thing we’re seeing a lot is a lot more emphasis on the server, particularly being able to not just run your existing client code on the server, but being able to kind of take full advantage of what the server offers, and combining that with parts we already have on the client.
So there are new players, like Astro, and Qwik, and SvelteKit, and a bunch of others that kind of play with some of these things… And we’ve also been working on that; like, we’ve been working on that since maybe 2017, but we’ve been slowly building the pieces towards the vision, towards our vision… And I think these libraries have switched to kind of louder marketing, and reaching more people, and talking about their approaches, so we felt that maybe it’s time for us to talk too, because we’ve also been working on these problems, and we think we have some exciting things that are also interesting and we’d like people to have a look at.
Well said. I was looking at your blog the other day - not your blog, Dan, but the official React blog… The last post was June 15th of last year, “What we’ve been working on”, and it was talking about Server Components, which had been in development December 2020. So lots going on, but like from the outside, as users, as just like ecosystem members, you just don’t know exactly what’s going on. And as you said, Dan, a lot of new things have popped up. We’ve had a whole slew of podcasts about these new frameworks… And just to be frank - I mean, they’re all kind of shooting for you. They’re all like “Here’s why we’re better than React in this way, and here’s why we’re better than React in that way.” And they’ll throw some other ones in there as well, but React is the dominant frontend tooling in the world right now, and so everyone’s kind of gunning for React and trying to differentiate.
[06:10] Yeah, I think we’ve kind of tried to avoid direct comparisons in the past… And I think now we’re realizing that maybe we should do some of those comparisons, just like we did in the early days, to better explain kind of how what we’re building is different from other solutions. But I think a part of it – like, with it’s totally fair to aim at React, and I totally get that… But when you listen to a lot of those comparisons, I think what they tend to compare with is kind of the old React, or the traditional thing that we know as React. And I think that is actually what we want to do as well. We’re also, in a way - we think like React enables really rich client-side interactive apps, but we just think it can’t be the whole story; there should be more to it.
Jordan Walke had this tweet, which I think is – so Jordan Walke is the creator of React, and he had this tweet which I think might ruffle some feathers, but it says that the biggest competitor to React right now is React. And I think it is – I totally get that there is a little bit of this kind of [unintelligible 00:07:15.27] there. Of course, the field is broad. But it’s also true that we are competing with ourselves as well, and that is a part of what we’re trying to do here. Joe?
I think you said it better than I could. But I was just gonna say, it’s great to have all this competition, though. The field builds a lot, a lot of apps; there doesn’t have to be a single solution. And so I just want to take a moment to recognize all the great work that like our competitors are doing. We think it’s great to have that competition, to have other ideas coming from other places. We don’t have a monopoly on good ideas. So just – there’s so many great developers out there doing awesome things, and that’s really cool.
Yeah, the healthy competition just drives innovation… So that’s really good to hear. Dan, going back a little bit, you mentioned React competing with React… And I’m curious what you see as the version of React that you’re competing with. Is it like React is just a view library that’s doing this, and now you’re trying to be more than that? Or can you define the two Reacts that are competing right now?
Yeah, this is a very tricky question… I think the way I would think about the old React - which is, again, not to say… The tricky thing is the thing we’re building is not the – it’s not a different thing. So I think what we’re doing is we’re extending React. Because the new thing we’ll build is not an alternative. You can think of it as like there is a circle in the middle, and then there’s the bigger circle. And so what we’re building out now is the bigger circle, where the circle in the middle is - you know, you can build components, you can have some state, you can have some effects… This lets you build very rich, very client-side interactions that are instant, that the user can just like type something, see something immediately… But then when you try to bring anything asynchronous into the picture, it gets a lot more complicated.
So frameworks that build on top of React, like Next.js, Remix, Gatsby - they’ve all kind of added some of their own opinions there, and they solved some problems. So with Next.js data fetching you were able to get server-side props, and then that kind of integrates with React, but lets you do this efficiently. And then like Remix did nested layouts, but on the server, and that also improves things, and gave a stronger integration.
[10:27] And so I think what we’re really trying to build is to take the best of the solutions we’ve seen, but instead of building them into React itself, we’re making React more powerful, so that those solutions can take better advantage of it. And so this is really – I guess there’s a React… Like, one way I’ve been explaining it is there’s React the library, which is the client-side library you’re running in the browser, or on the server as well; but there is also a bigger thing, which is React as an architecture, where we do have some opinions about “How do we integrate data fetching with React, so that we can do it most efficiently? How do we make it most declarative? How do we make it so that you can share components on npm that can take advantage of server-only features?”, and things like this. So kind of taken React full stack. So React architecture is not any specific framework, it’s more a set of APIs and things inside React that frameworks can build on top of, that make frameworks a lot more powerful.
Would you call that a meta framework? I’m sorry… [laughter]
I don’t like – I find this term confusing. The layering – I think if you call React a library, then I think there’s React the library, there’s the React architecture, and then there’s React frameworks that can implement this architecture. If you call React a framework, then you have to call those things meta frameworks… But whatever floats your boat, I guess.
Well, to get technical, any framework that you guys and the React team make is a meta framework…
Sorry… Dad joke. Couldn’t avoid it. Moving on… I would love to talk about your guys’s (I don’t know) feelings for a moment… Because in addition to the competition and some of the people taking shots at you, technical shots, which we all say are fair… Maybe not fair in the way they go about them, but you know, competition is a good thing. There’s also been kind of a swing of the pendulum. I’ve been in the industry for a very long time, and I’ve seen the reaction and overreaction of the tech trends move, and the pendulum swings in both directions. Sometimes we call this the hype cycle, sometimes we talk about broader terms… What I’m describing it now as a little bit of SPA fatigue, where people are starting – Dan, you said it, they’re kind of starting to think server-side again. And for a while, it was like all client-side, like everything, and then it was like “Well, we’re gonna swing back in the other direction.” And I’m curious, from your guys’ perspective, I’d love to hear both of your guys’ thoughts on this… As an insider on the team - you’re toiling and you’re building stuff, you’re trying to communicate your thoughts, etc. it can get sometimes personal and emotional on the internet about these things… Especially there’s – we had Alex Russell on the show a couple episodes back, talking about web development’s last decade; he wrote this kind of scathing piece where I’m not sure if he actually called React out specifically, but obviously, it was implied in there, of this, like, hoodwinking that’s been going on… And I would love to hear your guys’ response, either to Alex, or to just this general sense of… I think, Dan, you said it on Twitter, like “Oh, you guys are gonna cancel React?” Do you feel like the world is turning against React, or something, or what are your thoughts?
I think, as you said, there was a long period where people were really focusing on SPAs.
And it’s important to understand why that happened. I’ve been around in the field for a while, too. I remember building apps before React. I remember using Backbone… And people chose React and started building SPAs for a reason, which was that it was a cohesive developer experience.
[14:17] So there are a lot of developer experience benefits to that stack, but there were user experience trade-offs that came with it. And our team over the years has talked a lot about like how you can kind of balance that, certain patterns that you can use to avoid the downsides of an SPA, for example like loading your data in parallel with loading the code, things like that… But ultimately - yeah, people chose SPAs for a reason; that had some user experience trade-offs. That wasn’t like a nefarious thing we did. Developers opted into it because it was – like, that was overall a reasonable trade-off for them. But we’ve learned a lot from that, and we’ve been working on a way to kind of expand React’s capabilities to kind of bridge the best of SPAs (single-page apps) and MPAs (multiple-page apps). Other people have been working on that, too. It’s kind of a natural – to me, it feels like a natural progression; we kind of started server-side heavy, we went to client-side heavy, and now we’re gonna say, “Okay, we’ve got better tools. We’ve learned a lot as a frontend community to start creating solutions that really bridge the best of both.” So to me, it feels like just a pretty natural evolution. And yeah, I’m excited about the next phase of bridging client and server.
Dan, what are your thoughts and feelings around this topic?
Yeah, I think I would maybe be a bit less apologetic about our stance here… I would say that - you know, I was working on an app in 2013, right before React came out. And I did not pick React because of a better developer experience; I picked React because we just couldn’t create the kind of dynamic UI that we wanted with Backbone. So we were using Backbone at the time, and our app was kind of a mixed app, where there were parts that were content-heavy… So you would be able to like create posts that look kind of like magazine layouts, with covers, and text… Do you remember in 2013 scroll checking was the thing, like parallax scrolling, except we actually hooked into a request animation frame, we actually made sure that it’s fast, and so on. It was not janky, it was actually really cool. Although the effect is not popular anymore.
But anyway, our app lets users create those kinds of things. So that part of the app was pretty content-heavy, but then the editor - so we needed to build an editor for these posts, and in the editor you needed to kind of drag and drop different kinds of blocks, it would need to instantly show a preview… And with Backbone it was just super-hard to even make it work. And React made it so much easier to deliver those features that we were able to - we started the React rewrite in the process, and we rewrote the whole app in React in like nine months, and we added features while rewriting. So React actually let us finish the product that we didn’t even know if we could like make it work otherwise.
And so I think the reason a lot of people picked React is not because they were misled by a Cabal of Illuminati, but because people who were not only busy - and with all respect to people who work on the standards; all of this stuff is super-important. But I think you do need to be in those shoes of - you’re building a really dynamic thing, and the tools just don’t cut it. Like, they can’t express this kind of complexity. And that is why a lot of people picked React. And it also comes down to user experience, not just developer experience. Because the user experience we wanted is a drag-and-drop; the user experience we wanted is you press a button and you see the result as it happens. And that was difficult to do with existent tools at the time, in a way that composes to bigger themes.
[18:07] But I think what I’ve seen is really this focus on the client side - it is correct; it is the good approach to building rich interactions that have to happen instantly. But where it doesn’t work as good is when it’s content-oriented, or when there’s a lot of data fetching going on, and these kinds of things, because they’re just more natural to do with kind of a request-response model, where - you know, if you were writing PHP, you’re just like “I’m gonna go grab some stuff from the database, and I’m gonna render it.” You don’t think of it from the perspective of “I’m writing the page, it has an effect, that has a fetch, that does a set state, and it calls something.” You really want to express it as passing the data down. And I think that is what – because people liked React composition models so much, and people found it valuable, that they tried to build bigger and bigger apps using React, that some of them are more content-oriented, and I think that is the gap that we want to fill a bit better, and we think that knowledge is… We want to kind of unify the models.
Yeah. You said it way better than I did… But yeah, that’s exactly what I mean; that kind of component - the component-oriented way of designing apps was just such a better way to build apps, that people just were like “Let me use React for everything”, because it had so many benefits.
Yeah. Plus the – I want to say the unidirectional data flow, that pattern was really key in me coming over to that…
But also, I was just gonna say, another thing is we all seem to have been writing SPAs before React, so I don’t think it was the gateway into that pattern of creating apps. It was there before, and React just made it better.
Yeah, I think when we talk about SPAs in the large, it goes back to Fred Brooks’ no silver bullet. And we tend as an ecosystem to point out the next silver bullet and then use it for everything. Or the old saying, like, when all you have is a large hammer, everything looks like a nail… And Nick, you know me for a long time; I’ve been talking about the right tool for the job the entire time as we swing the pendulum back and forth… And that’s a difficult conversation to have, because in a sense it’s kind of a cop-out. Like, “Well, it’s an easy thing to say, right tool for the job. But it’s a hard thing to actually select the right tool for the job.” What’s easy is to find a great tool, and then use it for all of your jobs. And then you realize that actually it’s great at this specific thing, and maybe it’s okay that other thing, but it’s not perfect. And now, all of a sudden, we’re just hitting ourselves on the thumb with this large hammer, trying to use it wrong. And then we get mad at the toolmaker eventually, we’re like “Hey man, this tool doesn’t do all the things that I want it to do.” And it’s like “Yeah, it doesn’t.”
But I guess to your guys’ credit, you’re trying to adapt, you’re trying to change React to fit more use cases, or to move as people realize that SPAs for all the things is a bad way to look at life. It’s not the way to do it. It’s the way to do it for certain things, but not all things. And so now you’re taking React and changing it, which leads us into our next point, which we’ll talk about right after this.
So to satisfy the epic teaser that I put on the other side of the break, React Server Components - this is an old thing that’s also a new thing, and I guess there’s changes, there’s things happening… What’s the state of the world with RSC? Obviously, it helps React move into this new world, or stay in the new world… I don’t know, I’m not sure where the status is, so help us out.
Yeah, so Server Components kind of extend the React programming model and let you write code that runs – you can write traditional React client components that run on the client, but Server Components allow you to extend that and write code that runs on the server. And what that means is you get to really take full advantage of being on the server, being potentially right near your data, so you can actually access file system, access your databases, whatever backend services you have, while kind of still retaining the component-oriented model. So each component can be calling out and getting the data that it needs, calling in the services that it needs, and then hand off to the client side. So this kind of provides a way to kind of structure your applications.
It doesn’t strictly require nested routing integration, but it works really well with things like a nested routing solution, where each route point can start with a server component, and then gradually hand off the client components. But this kind of provides a lot of the benefits that frameworks like Relay, or Remix Loaders - like, it kind of provides a lot of those benefits, and even builds on them. So an example of this is, instead of – the parts of your app that are written as server components, they stay on the server, and we only send down the actual rendered output to the client. So you can kind of think about it as if we’re running the Server Components to compute the set of client components, and then executing the client components kind of as a second step. So this means you actually get to choose which client components you’re rendering. So you’re not sending down to code for those Server Components, you even get to choose dynamically…
So for example, imagine you have lots of different content types that might appear on your site, and a given user might only see one or two of those content types in a given session… You can actually send the code just for the components that are actually going to get rendered, and have a lot less code in the client. You can also share components between the client and server. So for example, if you wanted to have something that the user’s looking at an item on an eCommerce site - that can be mostly server-rendered, because you’re just looking at a static view. But if you are an administrator for the site and actually editing an item’s details, you could have a live preview. We’re using the same components to show a live preview as you actually edit the properties. So you can share code and render it in different contexts, server or client, kind of depending on the page that you’re on.
So it really expands the model and allows you to have the benefits of an SPA, highly interactive client-side pieces where you need it, and also use the server where you need it. But it’s kind of hard… It’s almost hard to talk about Server Components, because depending on kind of where you’re coming from, I think different pieces of it might appeal to you. So for example, if you’re coming from Remix, you might say “Oh, that sounds a lot like Loaders.” And then there’s like different pieces that you might be interested in. If you’re using Astro, you’d say, “Oh, Server Components kind of sound like Astro components.” It’s like, yes, they are, but there’s some details that are probably important to you. So it kind of depends on where you’re coming from. And of course, if you were around back in the days of writing mixed, like Rails and React apps, it sounds a lot like that; or we were kind of writing PHP apps back in the day… But again, some important nuance that we’ve iterated forward… But yeah, I’ll pass it off to Dan, if you want to add more.
[26:00] Yeah, I think that’s kind of what I’m gathering… The thing that Joe talked about, about “We’re not shipping code to the client”, or “We only ship the code that the client needs” - I think those are kind of optimizations. So I almost think of them - that’s not the goal; that’s not the feature. That’s the consequence of the model. So the model has a lot of these – because my personal opinion, I think the model makes sense. There’s just many natural optimizations that just happened to fall out of it, because we’ve connected two different things and gave you the power to use both of these things to their full extent. But I think if we kind of zoom out, like “Why do you want it?”, I think… With React - you’re right, React was not the beginning of SPAs, right? You could build SPAs with Backbone, you could build SPAs with Prototype JS, you could build them with MooTools, you could build them with jQuery. But I think there was a turning point when React came – and, I mean, there was Angular, and so on. But there was a turning point when React came on, and I think part of the turning point is that it really enabled people to put components together. And this sounds like a really – of course, Backbone had views, right? You could say, “Well, Backbone views could also be put together.” But I think where React really innovated is that it really composes like Lego blocks. You can combine two components made by two different people, who never talked to each other; you can put them together, you can pass some state to them, and they will just update, and they will work. And this is actually really hard to do from a programming model perspective. You couldn’t do that with Backbone views, because you had to manage how to update each of them. They had different conventions. So they didn’t allow this kind of decoupling where different people can put components – this is why you didn’t have many Backbone npm components, but you had many React components, because they compose.
And so that is the thing that React brought to the client… And now if you think from like the server perspective, we don’t really have an ecosystem like this for server – kind of that takes the same level of advantage to the server and it composes the same way. Like, you can’t put a component on the server that can stay in the server and handle a mutation, for example. You can’t have a component like django admin table, where it just renders a table that’s connected to the database, and it’s able to like update… You kind of always have to hoist it out of React.
And so I think the vision here is that we wanted to do for a server or build time ecosystem what React did for the client ecosystem; this ability to put things together made by different people, and have them in a single tree. And so that is really the pitch, but it’s very abstract, right? But then if you focus on specific audiences, like for example if you’re familiar with remix, we can say, “Well, Server Components is like Remix, except that you can have as many loaders in the tree as you like, and they can go as deep as you like, and they’re not tied to routing. And you can execute rendering code there, and you can put them on npm.”
And if we compare it to Astro, it’s kind of like Astro, except that navigating between pages doesn’t reload the page and destroy like all your state. It feels like an SPA. We can compare it to Rails with Turbolinks, but you write the client part and the server parts in the same language, and we can even reuse the components between them. So it’s similar to all of those things, but it has a unique twist on it, which is that you write in a single paradigm, and you have a single tree that’s composed of components, some of them server-only, or like build time-only, and some of them can run on the client as well. And so you use some of them for data fetching or some kind of server work, and some of them for interactions.
[29:55] What is the scope of Server Components? Because when I think about React, one of the things that was kind of a blessing and became a curse maybe eventually was how it was so scoped even inside of the frontend as a view library. Like, it’s not the everything you need to build an app; you’re going to take React and some other things, for instance maybe you grab Redux, maybe you grabbed React Router etc, etc. in order to have a full-featured application. It was a piece of that puzzle, and kind of a dominant mindset piece.
Yeah, it’s a great question, and I think it really underscores the design ethos of React, that we really are not trying to create a – like, our job is components. Our job is how these things compose together. Our job is how you put them in a tree. And we view all of those other features through that prism.
So to give you an example, for example Server Components support data fetching. Data fetching is kind of the point. You’re close to the data, you should be able to fetch it. In traditional React and client-side React we didn’t really have a primitive for this, and so the question might be, “Okay, should we add data fetching capabilities to React itself?” But the way we approach it in Server Components is more like the features that we added are integrations for data fetching solutions. So a framework building with React Server Components can provide its own data fetching layer, or you can use like an ORM, or really anything that supports async/await. Because basically, the data fetching in Server Components is just async/await. But then we provide you a way to, for example, specify that while a part of your tree is not ready, for example, it’s doing the fetch - like, in PHP, that would be blocking. So in PHP, if you read from the database, the user’s not going to see anything while it’s doing that, but what we let you do is we let you wrap that part into what we call a suspense component. That’s the thing provided by React where you say, “Well, this part is not ready. I want to show a skeleton screen, or a glimmer”, and then the user would see progressively more and more content streaming in from the server, even while the server is doing data fetching.
And so kind of to come back to your question, what I was trying to say here is just we view this from the perspective of what should the component abstraction be able to do, but then React Server Components by itself is not really something you can install. Like, it’s not a library. It’s not even an API.
What is it…? [laughs]
Yeah, it’s a good question.
Is it kind of like how like Facebook way back when came out with this concept of Flux, but they didn’t really release a library, and then you came around with Redux?
No, no. I don’t think this is similar. Flux actually was a library.
Oh, it was. Okay.
It was a canonical – yeah. But I think Server Components are a lot deeper than that. It is a piece of technology, we do provide some actual building pieces, but it is not something you would probably use directly. It’s designed for frameworks, or if you’re like at the big shop, you can kind of invest some effort, you can build your own kind of set up that’s like a framework. But it’s really an architecture and a few pieces of code, and a set of conventions, almost like a spec, that frameworks can implement.
[34:12] Next.js 13 App Router is the most comprehensive implementation to date. I know that Gatsby 5 preview I think also supports it on some level… I haven’t checked in detail. I think it doesn’t have like all of the features that Next.js has. But it’s really like this thing that frameworks can implement, and we’d like to make it easier to implement, but because it depends on Bundler support, it’s also tricky for frameworks right now. Like, if your framework is not super-easy to adopt unless you’re willing to invest some time into building some of these pieces.
So it’s still a bit of an early time, but I think it is a spec, and it is a few pieces that we provide, and some pieces you need to fill in as the framework author to really build the whole solution, like you said, that has all the features, like routing, and so on.
I want to dig in and ask a few kind of more implementation-specific questions about how to actually get started with Server Components. So you mentioned you can use Suspense to kind of display something while the server is rendering something else, or while it’s fetching the data. Does that Suspense piece go in the server component, does it go in the client component? Where does that go?
Yes, that would go in a server component. I mean, you can use Suspense on the server and on the client, to clarify. This also gets kind of complicated, because there’s Server Components that render, and sort of hand off to server-side rendering… Which then kind of hands off to hydration. And so the interesting part about Server Components is like that first phase, running the Server Components, can run dynamically at runtime, or it can actually run at build time. So if you’re doing static site generation, you can actually run the Server Components at static build time. That’s something that I think Next 13 App Router also either supports, or is working on supporting. But the idea is that wherever in your tree, you can put a Suspense component, and if anything underneath that part of the tree is not ready, then we will show the fallback, kind of depending on UX. So that can mean on the server, so if you use Suspense in a server component, and the children are not ready, we’ll be able to start streaming down the parts kind of around that.
So you can kind of imagine the kind of layout for your page, and then put a Suspense component around the main content. If the main content is not ready, you can now still send the outer frame, like in a layout of the page down, while the content is being prepared.
That totally makes sense, but for some reason just crossing that server-client barrier messed with my head of where would that actually go. But as you were saying it, I’m like “That was a dumb question.”
Yeah, ultimately it just kind of goes – you think about like the hierarchy, and you just put the Suspense boundary… And it’s really about – it’s not about saying like Suspense has to go in the server or client, it’s about you think about the structure of your application, like for the UX of your site, where does it make sense to have loading boundaries. What does it make sense to wait for, and what does it make sense to say, “Yeah, if we can’t show this content, there’s no point showing anything, so don’t put a Suspense boundary”? You think about Suspense, it’s based on UX, not about kind of like loading characteristics, or like server-client.
The difference between a server component and like a server, or like a statically-rendered on the server component, if there is a difference - is that something that you have to distinguish, or is that something that Next can just determine based on how it’s used?
Yeah, my understanding is like that Next - I think they’re able to look at what APIs you’re using, and kind of figure out “Can this be statically-rendered, or does it have to be dynamically-rendered?” That was my understanding.
[37:56] Yeah. I would maybe add that if we use – so the terminology gets really confusing, because Server Components, which sometimes we abbreviate as RSC, like React Server Components - it’s really a separate layer. It’s like a completely separate layer from what is traditionally called server-side rendering. And the thing is, with Server Components you would usually use both. So Next.js uses both of these layers. And so it gets confusing to talk about, because really what happens is that, first, we execute the Server Components layer, and that is a layer that runs only on the server. So this is why you’re able to read a file, or a database, or anything like this, or that layer could run during the build time. So that could also happen.
So SSR becomes – you know, it’s just an optimization layer for first load, but the React Server Components is really about taking full advantage of the server, both the first load, and for navigation, so that they can grab some data. Data replaces APIs, really. I think another way to look at it is like - it’s not about replacing the server-side rendering, it’s about replacing the part where you have to talk to an API, and it’s kind of like “Well, if I’m going to talk to an API and I’m hitting the server anyway, why not also execute some components on it, so I don’t have to carry them on the client?” And then you realize, “Maybe I don’t need to expose APIs at all.”
So if I’m hearing you right, it’s not a client-side component that happens to be rendered on the server; it actually IS your server side component. It’s your server. And that distinction is one that you guys are gonna have to explain over and over to everybody… And maybe the goal here, Dan - and you kind of said it as like “This actually just kind of tucks up underneath other technologies”, and so that, Joe and Jane Blow, the frontenders, or full-stackers, or whatever they are, who just making their apps, don’t necessarily have to know this. Because as a person who is an app developer, and I’m thinking about like “Okay, how would I use this, and stuff?” I’m sitting here thinking like “This sounds really complicated”, you know? And not because you guys aren’t good at explaining it, but because - well, there’s a lot of moving parts, and there are nuances that are difficult to explain.
Does this exist as a thing? You said like Next 13 kind of has it going on… Is meta using any of this? Are there people using this in production to build stuff, and are you getting feedback from them?
So we had a successful early prototype using Server Components at Meta; definitely on the path to like full adoption at Meta, but it’s kind of a bit longer road for us. But I think the easier place – like, the thing that is able to move faster is Next 13. And Dan, I think you know more about the current status there.
Yeah. Just to kind of respond to the – I think the underlying current there… Like you said, “Oh, this sounds really complicated…” There’s a question of how do you explain it to the framework authors, or people who build the underlying technology, and how do you explain it to the end users. And I feel like there was a completely different explanations. And that’s why it’s hard. Because from the framework author perspective, you kind of need to understand the flow of how does this new architectural piece feed into the architecture I already have? And you kind of know what those boxes are, and you need to see where the new box fits in. But then if you ask people today how does – people who used Next.js before Server Components, you ask them how does server-side rendering work; a lot of them don’t really know, because it’s kind of the behind the scenes optimization. What they know is they can create a page, they can import a component from it, and that code will run both on the server and the client. Sometimes they have errors, and they know, “Oh, I can’t use window here, because it runs on the server”, and so they fix it. But they don’t really think so much about how it works.
And so with Server Components, I think it is similar. And to Joe’s point that – for example, where do you put Suspense? You don’t think about it from the perspective of where something runs. You have JSX that says “comments”, and you’re like “I want to show comments glimmer before comments are ready.” And so you just wrap it into that tag, and you don’t really think about why that works.
So I think with Server Components it is a little difficult to kind of wrap your mind around if you’re used to React, because the way you add state – like, it forces you to create kind of a split point. So if you’re used to just creating components and putting state anywhere, built in with Next.js 13 App Router (that’s their new version with Server Components), it does require you to learn how to compose components a little bit differently. But other than that, people definitely are starting to use it, so there’s a lot of people who are trying the Next.js 13 App Router, they get a lot of feedback there… They’re saying not to put it in production yet, but I know for a fact that there’s a bunch of places that have it in production.
I think Vercel is currently converting a bunch of their stuff to Server Components, and then people converting it are not the people who contribute to Server Components. So they also get a lot of internal feedback from regular React developers.
[45:41] But I think like the way to try this definitely – you know, Next.js 13 App Router I think would give like a good first impression of what it feels like, and there are rough edges where we just don’t have documentation that kind of teaches you how to structure your app differently yet… And I think that is a point pain point, but I also think it’s addressable. And as there are more like guides and tutorials, I think the broader community will be able to get on board with it.
Yeah. And I think in terms of that point of what other things you’ve got to think about as a developer, I think the idea is that a lot of the code that you write in the Server Components world is just a server component; you sort of start there as your default. So for example, the root of your page is generally going to be a server component. And you just kind of keep on writing server components, just accessing the data that you need, all the way down, and then you eventually realize, “Oh, I need some interactivity here. Okay, let me use a client component.” If you make a mistake, and you use some state, you’ll get feedback in your IDE, and then you’ll say, “Oh, right, it’s just like accessing window in a client component. Oh, yeah, I can’t do that here. Let me go and switch this to a component.” And as you go, you’re gonna get that feedback and structure it. And I think also, over time, we’ll see more component libraries kind of adapting to this world, so that it’ll be easier to say, “Oh, I’ve got like this rich client component. I need to add some logging, but I don’t have to create a custom client component just to add like a one-off log here or there. There’s like a way for me to pass that through, just have that kind of automatically happen.” And so you’re gonna be able to stay mostly in a server component world, and so won’t even feel as much like a distinction. So I think it’s – yeah, today there’s a bit more of like having to be aware, but over time, I think that’ll kind of go away.
I’m trying to come up with different ideas of how to distinguish in my brain between a server component and an SSG component. And that leads me to a question of “Can a server component–” I know it can go fetch data. But can it pull data and continuously update with different things? How does that work?
Yeah, we don’t have support for that right now.
But I know one of the things we’ve talked about – so for example, you can wait for a single piece of data to resolve. You can do an async/await, and – one of the things that we’re exploring is support for like an async iterable, so that you can actually await for a list of values to resolve, and then stream those down. So that kind of addresses it, but that is the sort of list of items use case, where you want to just like load one after the other, and kind of incrementally stream them in. If you’re talking about things like WebSockets, where you want to just have kind of like a Pub/Sub system that’s like sending you information, that right now would be kind of done as a client component.
Got it. Okay. Yeah, that’s what I was thinking of, of like a Twitter firehose type thing, where it was just constantly doing that… So right now the solution would probably be more of a client-side fetching approach, or polling approach.
[49:44] Yeah. I wanted to add one thing… I really like the way Joe explained it in terms of you don’t really think about it that much, you just start writing your components as usual, and then when you need some interactivity, you kind of add these client points. And the metaphor I’ve been using, that I’ve found resonates with a lot of people, is you kind of think of Server Components as the skeleton. So Server Components really – like, they’re not these things that you decide “We’re gonna throw around… Like, this server, this client.” I think that sounds a bit messy in your head. But if you think of the – like, the server components kind of give you a structure. So maybe you have like a page, and it has like a footer, and a header, and content area. And then maybe the content area has like a feed, and like composer, or something like this.
One thing we want to add to Server Components is built-in support for mutations. So you would be able to pass a function from the server as a prop down to, for example, like a form. So you would be able to say, “Here’s like create a tweet form”, it has an input, and it has a – somewhat similar to what Remix does, which is inspired by original HTML, the way you did forms back in the day. You just have a form and it submits an action. And so what you would be able to do is say - like, in your server component you have “function, handle, add”, or “create to do”, and you just pass that to a form, and that hooks it up. So you can build a large part of your app without writing any client code at all.
In the beginning it’s just limited in what it can do, but then at some point you’re like “Okay, I want to make this bar like a tab switcher”, or something that you type and you see preview immediately, like a theme toggle. So things that have to respond instantly, without a round trip. And so this is where I’m gonna take the skeleton, and I’m gonna wrap some muscles around it. And so client components are kind of like those muscles that you build around the skeleton, that give it that kind of progressive enhancement with the client parts.
This adds some complexity, because you have to separate the two worlds, and be conscious of where the seams between the worlds are. But this also removes a bunch of complexity, because - well, what would you do before? You would add a state management library, you would add like a data fetching library, or you would have effects, that like fetch, and set state, and so on, and now you just pass the data from the server to the client by props. And so I think that is kind of the mindset, that we’re adding a bunch of things, but the goal is to also make a bunch of things, things you don’t have to think about anymore, and you’re gonna think of it – as you said… I think Nick said that for React it’s really the unidirectional data flow that helps it click. So this is putting the server into that unidirectional data flow. The server is like the first part of that flow, and so if you update, you do a mutation, you go through the server, and that updates your component, that gives you the new component tree. So yeah, it removes some things, and it adds some things.
Yeah, to that metaphor of adding in the server to the unidirectional data flow - I guess I’m trying to understand how… I’m still like separating it right where there might be like a page; like, my Server Components might be the page that I’m loading, and then it passes it off eventually to client components that are only run in the client. Is there any way to retrigger that flow with the server component again, or is that only like a page refresh type thing?
Yeah, so that is a really good question, and I think maybe this is what you were getting at with like can it update continuously, and stuff like this.
[53:49] So the way the model – I think the easiest way to think about the model is it’s request-response. So you can imagine it as old school PHP, or Rails, where you just go to the server, you request the thing, you get the response. So this is why if you want to kind of refresh the server tree, you have to do that explicitly. So you have to be like “I’m refreshing”, except it’s not gonna actually reload the page, it’s just going to go to the server, get the new virtual DOM, if you want to call it that, and kind of put it in place so that it updates without destroying the state. But then what the router does – the thing is it’s not going to be efficient if you have to do a full kind of refresh of the entire server tree every time something small changes. And so this is why we recommend using Server Components together with a router, like the Next.js App Router, that supports nesting… Because Next.js App router actually - it lets you say “I want to refresh just this part. So like I’m navigating from a tab to a tab, and it actually in turn – you’re not exposed to that, but internally it actually has a separate entry point for different route segments. And so this is how it’s able to update a part of it.
And so if you’re a framework, or if you really go to like low-level pieces, or you want to do math science experiments, in principle you could absolutely have a part of your app that’s driven by Server Components and you continuously poll it, or even – we could, in principle, connect it to sockets, but still, it’s request response. You have to say, “I want to refresh a part”, and then the part comes in.
Got it. Okay, yeah, that lines up with what I was thinking.
Is there anything we haven’t talked about with regard to Server Components? Is there something upcoming? Is there a place where people can plug in to this world? Or do we normal people who just use React - are we just waiting for the awesomeness to like come in the next version of our favorite meta framework? What’s the next steps from here for listeners, for myself, for Nick, with regards to React and this new tech that you guys are working on?
Yeah, so there’s a few ways if you want to kind of learn more about Server Components or try it out; there’s a few different resources to look at. So Dan and Lauren Tan gave an introduction to Server Components way back - I think it was like December 2020. All the times are off post pandemic, but yeah, I think that was right. It was a great overview… Some details have changed, but I think that’s still like a really good, really great introduction to the overall concept and it helps you understand… We have a small demo app, which is – the demo app that we created for that was not perfect, but it does help you get like a bit of an intuition for things like “Oh, I can have a server-rendered view, and then I can also reuse that same code with for an interactive preview…” So it kind of gives some a good intuition.
Plugging the thing that I wrote - I wrote the RFC, so if you want some kind of more technical details, and kind of the rationale and things, the RFC is a good thing to look at. That’s been merged into the RFCs repo. And then - again, so Gatsby 5 has experimental support, but really the best place to check it out right now is Next 13 App Router. The Next team has a lot of great docs for how to actually use, not just Server Components, but really like how to use Server Components in the context of Next 13 and all their utilities around it. That’s just a great place to try it out. So yeah, hopefully those are some good resources. And we also have an upcoming post, kind of follow-up to our React Labs post from last year, that’ll kind of give us some more details for people to follow along. So as always, kind of watch the React blog for more. I don’t know, Dam, if you want to add any other resources…
I agree with everything Joe said. I think if you want to actually try and give it a spin, definitely I’d say Next 13 App Router is the most comprehensive implementation. Next was basically rewritten, almost from scratch, to build on top of this. Yeah, it’s still a bit rough, so expect some rough edges… But it gives you a good idea for what the bleeding edge is.
[58:02] And I think if you want to dig in deeper, if you’re a framework author, or if you want to become one, if you’re interested in the kind of under the hood nitty-gritty, one thing that’s exciting is – like, part of the reason why it’s hard to adopt in a custom stack is because a large part of Server Components spec, or the things that frameworks need to implement is really the bundling part. And the bundlers today are not designed to treat server and client as kind of a unified module graph that runs into different environments. It’s the same shift on the level as if you remember there used to be bundlers, before Webpack, like RequireJS, and then Webpack made code-splitting very easy. And so code-splitting was like a big feature that really changed the bundler landscape, and then every bundler supported it. And so Server Components are kind of on that level, where they require – it’s agnostic of React; the features we want in the bundle are agnostic of React, and we think they’ll be useful beyond React. But we’re really in this space where mainstream bundlers don’t have built-in support for it yet, so you kind of have to build a plugin. We have an example Webpack plugin, but we don’t think it’s production-ready. It’s more like a prototype. And then the thing in Next.js is production ready, the thing in Gatsby is probably production-ready; we haven’t tried it.
So for bundlers, the thing that I’m excited about is - we started working with other bundlers. So we started working with Bonn and with Parcel, and so maybe if you’re interested, keep track what those bundlers are doing, because they probably will announce some levels of support at some point, and you’ll be able to play with it.
Also, there is a demo in React Repo for kind of advanced users, at fixtures/flight. This is the codename of Server Components from old days. But it has like a small end-to-end demo that shows it without Next.js. So if you’re like “Oh, is this Next.js-specific?” It’s really not. But if you wanted to run it into a real framework, you’re gonna have to figure out a bunch of pieces, like routing and bundling, and that requires some investment. We hope it will be easier to do it in the future, and that we’ll have a React Server Components ecosystem.
Very cool. Well, guys, this has been awesome. It’s been eye-opening for me, and hopefully for our listeners. Well, Nick, any final words – or sorry, anything to say? I don’t want to threaten you like that… Before we call it a show.
Something you want us to quote in the next documentary?
Yeah, exactly. [laughter] Let’s get Nick on the record here. “React Server Components will be an utter fail. No one will use them.”
No, I don’t know… I was gonna start with –
I was just kidding.
Why don’t you like TypeScript? I guess I’ll go with that.
Oh, good question. That’s gonna be a good one for the socials. Come on, Dan… Why Dan Abramov does not like – no, let’s use the word “hate”. “Why Dan Abramov hates TypeScript.” Go!
I would say I think this is a bit too strong for my public persona, but…
Okay, why Dan Abramov does not like TypeScript that much. Go!
I just get errors all the time, and then those are not the errors that I want to fix. And then I do have bugs, and those are not the bugs that it caught, and I’m frustrated. But I think part of it is I haven’t properly learned it. I guess that’s how a lot of people feel about React; it’s like, I’m too lazy to read the docs, and so when I get confused, I just spend a bunch of time trying to fix it by myself, and I get frustrated. But I know it’s great for a lot of people.
Good answer. Good answer. Very reasonable. We were hoping for something that we could really start a flame war with… But we’ll take it, Dan. We’ll take it. Joe, Dan, thanks so much for coming on the show. Shout-out again to Matt for collaborating on this. Definitely hook us up with a list of links. I’ll follow up and we’ll get those for the show notes. So listener, everything Joe mentioned at the end there, resources, plugging in things that we were talking about - they are in your show notes for easy clickings. But that is JS Party for this week. I’m Jerod, that’s Nick over there… Joe and Dan from the React team… Welcome back. Anytime you guys like to come join us. We love having you on the podcast.
Thanks for having us.
Our transcripts are open source on GitHub. Improvements are welcome. 💚