The Mental Model That Finally Made React Server Components Click
Forget 'server' and 'client' as a spectrum. The model that actually clicked was thinking in terms of what crosses the network boundary.
Tanjil Ahmed
Lead Software Engineer · Notionhive
React Server Components confused me for longer than I'd like to admit, because I kept thinking of 'server' and 'client' as two flavors of the same component model. The mental shift that made it click was different: stop thinking about where code runs, and start thinking about what data crosses the network as serialized props.
The boundary is a serialization boundary, not a rendering boundary
A Server Component can pass a plain object, a string, a number — anything JSON-serializable — down to a Client Component as props. It cannot pass a function, a class instance, or a Date object without care. Once I started asking 'can this cross a serialization boundary?' instead of 'does this need interactivity?', the placement of the `"use client"` directive stopped being a guessing game.
- Push `"use client"` as low in the tree as possible — it's contagious downward, not upward.
- Server Components can be async and fetch data directly; that's a feature, not a workaround.
- Context providers need a client boundary — they can't live purely on the server.
- Composition beats prop drilling: pass Server Component children into Client Component slots to keep more of the tree server-rendered.
RSC isn't a new rendering mode to learn. It's the same React, with a new question: what has to cross the wire?
