Concept At multi-team scale, the architecture question stops being “how do I structure one feature” and becomes “how do teams work on this app without stepping on each other” — folder structure, shared UI, and where server-side logic lives all have to encode team boundaries.
Example Feature folders (features/checkout/, features/search/) each own their components, Server Actions, and tests. Server Actions live colocated with the feature that uses them by default; only truly cross-cutting actions (auth, analytics) go in a shared actions/ module. A shared UI package holds only genuinely reusable primitives (Button, Input, layout tokens) — feature-specific composites stay in the feature folder even if they look reusable at first.
Gotcha A shared Client Component that wraps too much of the tree (a top-level <Providers> client wrapper holding onto everything from theme to analytics to a state library) drags every page's bundle up with it and forces server-rendered subtrees underneath it to hydrate as client code even when they didn't need to. This is the multi-team version of a God Context — everyone imports it, no one can safely change what's inside it.
Senior answer Push "use client" to the leaves — the smallest component that actually needs interactivity, not the top of the tree — so Server Components stay the default and client bundle growth is attributable to a specific feature, not a shared root. Since Next 16 removed the build's “First Load JS” metric, measure bundle impact with route-level awareness via Lighthouse CI or Vercel Analytics instead, and gate PRs on a regression there rather than eyeballing a build log. Give each team folder-level ownership (enforced via code-owners) so the boundary is structural, not just a convention people forget. Trade-off: colocating Server Actions per feature means some duplication across features versus one shared module, in exchange for teams being able to change their own actions without a cross-team review.