The Mental Model Shift Is Real
The hardest part of adopting React Server Components isn't the API — it's unlearning. For years, the React mental model was: components run in the browser, data fetching happens via hooks or loaders, and the server is just a place that sends HTML for the first paint.
RSC inverts this. The default is now server. You opt into the client. That single inversion changes how you think about data access, bundle size, and component composition in ways that take weeks to fully internalize.
The Performance Win That Actually Matters
Everyone talks about bundle size reduction. That's real, but it's not the most impactful win. The bigger gain is data colocation — the ability to fetch data directly inside the component that needs it, on the server, without waterfalls.
In a traditional client-rendered app, you'd have a parent component fetch data, pass it down, and potentially trigger child fetches in sequence. With RSC, each component can fetch its own data in parallel on the server. The result is a dramatically simpler data layer and faster time-to-content.
“The bundle size story is good. The data fetching story is transformative.”
The Edge Cases That Will Catch You
Context doesn't cross the server/client boundary. If you're used to wrapping your app in a dozen context providers, you'll need to rethink which state actually needs to be global and which can be colocated.
Serialization is a hard constraint. Props passed from server to client components must be serializable — no functions, no class instances, no Dates without conversion. This catches teams off guard when they try to pass callbacks down.
The 'use client' boundary is a subtree boundary, not a component boundary. Once you mark a component as a client component, everything it imports is also pulled into the client bundle. Be deliberate about where you draw that line.
