In a conversation recently, a friend I respect said that if he were starting a new project, he would probably reach for React + Vite and build a client-only app instead of using React Server Components at all. Not for performance. Because he cannot reliably reason about the RSC boundary in Next.js.
That hit me. The hardest part of RSC is not the core concept. The hardest part is that the architecture is hard to observe while the app is running.
This post is for people already on the App Router who care about debugging and teaching RSC, not a primer on how the model works.
A friend's tradeoff
The conversation was simple. He said the system felt opaque. He could read the code and infer where server and client responsibilities should sit, but he could not verify that model quickly in runtime tooling.
So for a greenfield app, he would rather ship client-only React than adopt RSC. Plain React + Vite gives up some server-first patterns, but the runtime story becomes easier to inspect and debug. That tradeoff is what he would optimize for on a hypothetical new project.
I hear the same tradeoff from other experienced developers. They are not rejecting modern rendering patterns. They are rejecting invisible architecture.
Inference instead of a live map
RSC is a legitimate pattern. Separating server execution from client interactivity is rational. Keeping heavy data work on the server and shipping less JavaScript can be a good default.
The issue is observability. In practice, you infer boundaries from conventions like 'use client', file structure, and framework behavior. You do not get a first-class runtime view that says: this subtree rendered on the server, this client subtree hydrates in the browser, this boundary moved because of a dependency.
When the model can only be rebuilt from static cues and guesswork, debugging slows down. You stop asking "what is happening" and start asking "what do I think is happening." That is a weaker loop. In my own workflow, without a map I fall back to grepping for 'use client' and tracing imports; with an overlay I can sanity-check the live page in seconds.
If you can't see the boundary, you can't reason about the system
This is bigger than React. Any architecture with hidden boundaries creates the same failure mode.
If the boundary is invisible, developers build a mental model from incomplete signals. That model works until it does not. When it breaks, bugs are expensive to diagnose because the runtime gives you little help validating assumptions.
Then the framework gets blamed for being complex or unpredictable. Sometimes that criticism is fair. Sometimes the architecture is fine but the instrumentation is missing.
Good developer experience is not just faster scaffolding and nicer error screens. It is whether I can verify what is running and point to evidence in the tooling, not only what I inferred from the code.
Next.js dev tooling today
When I used Nuxt, Nuxt DevTools felt like one coherent surface: components, payloads, and server routes were easy to relate to what I saw in the browser, and I actually kept it open. I cite that only as a benchmark for devtools quality: how polished first-party, in-app inspection can feel. Nuxt's stack is not the same shape as the App Router plus RSC, and I am not claiming the two frameworks are interchangeable. The useful carryover is the standard it set for me, not a one-to-one feature match.
Next.js is already moving in a useful direction. During next dev, the in-app dev indicator (the small Next.js menu in the corner) covers routes, preferences, and the signals you reach for every day. Vercel also ships next-devtools-mcp, which connects assistants to Next.js documentation, upgrade and Cache Components workflows, and (on Next.js 16+ with a running dev server) runtime diagnostics such as errors and dev logs. Those pieces matter, especially for agent-driven workflows.
The next layer I would love to see, and where the ecosystem is still improvising, is a first-class answer to the App Router-specific question: where does the server/client split sit on this page, right now? Neither the indicator nor MCP, as I use them today, maps server regions to client roots in the live tree. React DevTools shows the component tree but, in my day-to-day use, not that page-level boundary map either. So the split still has to be reconstructed from 'use client', imports, and convention unless you add your own overlay or discipline.
My read, at least in conversations I have had, is that this visibility weighs as heavily as docs when teams decide whether to commit to the pattern. If you cannot inspect a model, you cannot teach it well, review it well, or debug it under pressure. On teams I have seen weigh RSC, that missing view is often the difference between "we should use this pattern" and "let's simplify the stack."
RSC Boundary
That missing view is what RSC Boundary is for: a dev-only overlay for Next.js App Router that highlights client component roots and server regions while you work. Wrap your root layout with RscBoundaryProvider, toggle highlights in development, and you get a concrete map instead of pure inference from 'use client' and file paths. Production builds stay a pass-through.
It does not replace React DevTools or Next.js diagnostics. It targets one question: where does the server and client split show up on this page, right now?
Treat it as a sketch of the boundary, not a substitute for understanding serialization and import graphs. Dynamic imports and third-party packages can still surprise you, and any overlay can tempt you to over-trust a static picture.
RSC Boundary ships its own UI so you can toggle highlights without waiting on the framework. That was the practical way to ship. Given the choice, I would rather hang the same controls off Next.js's existing dev indicator (the corner menu people already open during next dev), so boundary visibility lives in the same surface as routes and preferences instead of a separate overlay chrome.
One constructive idea is a stable extension point so libraries can register entries in that dev-indicator menu (toggles, doc links, lightweight overlays). Ecosystem tooling would meet developers where they already look. Today that surface is framework-owned; a small hook would make third-party observability feel native instead of bolt-on.
The same seam elsewhere
The same failure mode shows up wherever the system is split but the seam is hard to see:
- Microservices without request-flow clarity
- Edge versus origin without a clear execution path
- Any setup where tooling does not show the boundary under real traffic
Observable boundaries are how teams keep a shared model through incidents.
The same applies when the system is the framework. If the runtime story is subtle, developers need evidence in the tool, not only in the documentation. Next.js dev tooling is already useful; in-context App Router boundary visibility would still close the loop for teaching, review, and debugging under pressure. That belongs with routing and errors as core infrastructure, not as optional polish.
- Next.js
- React
- RSC
- Nuxt
- DevTools