My name's Aurora. I work on the Next.js team at Brazil. And React Server Components landed a few years ago. It's been quite a journey. Some of you have shipped app router apps with them. Some of you maybe you tried them, you bounced, you went back to the patterns that already worked for you, and some of you maybe have just been watching from the sidelines. So waiting to see where this goes. But wherever you are with them, the model has come a long way. And I want to show you what React Server Components can do in Next.js today and why I think it's the most interesting time to be building on the web.
But before we talk about Next.js, let's talk about React. The story starts with a thing we already love about React. Why do we love React? You might not have really thought about or articulated why, but you feel it every time you write a component. React is composable. You can build a row, a playlist, a page, snap them together, and they just work. So here's a page with a handful of feature components composed together. React components can be self-contained. A different page can reuse some of the same pieces mixed with new ones for what the page needs. React gives us clear boundaries. Somewhere else, same components reappear, re-stacked in another order. We didn't have to know what was inside each one. So that composability is the thing we want to keep. Everything else in the stack has to earn its place around that.
Now, components have clear boundaries, clear inputs, clear outputs. That's the same property that makes a component easy to reason about for us, also makes it manageable for an agent. So an agent can pick up one piece, change it, and not have to understand the whole app to do that safely. The bigger the code base gets, the more that matters for the agent, for you, and for your teammates. And this is not just true at the component level. People are noticing this in the shape of the whole code base. So this is Antonio. You might have watched his YouTube code with Antonio. It was great. It was like my way when I was learning AppRouter back in the day. But he's been building real apps with agents, and what he also keeps landing on is this small blast radius and clear boundaries. So this is the same property, just scaled up to the code base level. Maybe that would mean feature folder instead of only thinking about single components. But what does all of this look like in practice when you start building? The moment we add data, composability comes under pressure. Some approaches keep it and pay for it somewhere else, and some just lose the composability entirely. So let's walk through what we've tried. We started with useEffect, our favorite. The component can fetch on render, own its loading flag, owns the error flag and runs the request inside the useEffect with the right dependency array. Do you forget a dependency and you get stale data or you add one too many and you start fetching in a loop? So on its own, it looks fine. We have a component here, top boundary grid, it's owning its data. But then the moment another component then needs the same data, we can't just drop this in twice because now we'd be making the same fetch twice. So we hoist it up to a parent component, pass it down through props, and suddenly this component no longer owns its data. Start adding mutations, you have to hoist it higher to execute those state changes, and suddenly your self-contained component is plumbed through three levels of props for reasons that have nothing to do with the UI structure. A whole category of libraries emerged to clean this up. We had React Query, SWIR, Apollo, Relay. So here the data would instead be keyed and cached centrally so that any component can ask for it without prop drilling, and mutations can invalidate from anywhere. And this was a genuine step forward. And these libraries are still a great choice for a lot of apps today.
Comments