Server Components flipped the contract: instead of "everything is a client component, with server data fetched alongside", we now have a default of server-rendered output that can opt back into the client where interaction is required. The mental shift takes a week. The mental model takes a quarter.
What runs where
Server Components run once, on the server, and never re-render in the browser. Client Components run on both. Anything you import from a server component into a client component crosses the network boundary — which is exactly the moment to start asking serialization questions.
Three rules that survived contact with reality
- Default everything to a Server Component until you need state or effects.
- The smallest
"use client"file is almost always the right one. - Treat the server/client boundary like an HTTP boundary — because it is.
If you take one thing from this article: stop thinking of RSC as "an optimization". It's a different shape of program.