FeaturesEdit this page.md

DevTools

The built-in DevTools panel lets you inspect your running application during development. It covers server process health, RSC payload contents, cache behavior, the route tree, outlet layout, remote and live components, worker threads, and server logs — all without leaving the browser.

Pass --devtools when starting the development server:

pnpm react-server ./App.jsx --devtools

Or add it to your config so it stays on across restarts:

// react-server.config.mjs export default { devtools: true, };

DevTools is development-only. It is never included in production builds.

Once enabled, a small floating button with the react-server logo appears in the bottom-right corner. Click it to open the panel, or use the keyboard shortcut:

ShortcutPlatform
Ctrl+Shift+DWindows / Linux
Cmd+Shift+DmacOS

The same shortcut closes the panel again.

The toolbar at the top of the panel has four dock-mode buttons. Click one to switch where the panel sits:

In any docked mode, drag the handle between the panel and your page to resize it.

All panel state — open/closed, dock mode, size, and float position — is saved to localStorage so it persists across page reloads.

The / button in the toolbar toggles between light and dark mode. DevTools picks up your app's theme automatically by checking, in order:

  1. A dark or light class on <html>
  2. A dark=1 or dark=0 cookie
  3. The system prefers-color-scheme media query

Clicking the toggle updates both the panel and your host page, and persists the choice via a cookie.

The panel has nine tabs. If the panel is too narrow to fit them all, the ones that don't fit collapse into an overflow menu behind the » button on the right side of the tab bar. The currently active tab is always kept visible, even if it would normally overflow.

The Status tab shows your development server's resource usage. It is a "use live" component that streams fresh numbers every second.

Three cards are displayed:

CardWhat it shows
ProcessNode.js version, PID, platform/architecture, and uptime
CPUUsage percentage as a gauge (green under 50 %, amber up to 80 %, red above), core count, and 1/5/15-minute load averages
MemoryHeap used versus heap total, RSS, external allocations, array buffers, and OS-level free/total memory — each metric has its own gauge bar

Use this tab to watch for memory growth over time (a sign of leaks) or to check whether a rendering change is spiking CPU.

The Payload tab captures every React Server Components Flight response and decodes it so you can see exactly what the server sent.

At the top of the tab, a stacked bar breaks down the initial HTML document into three segments:

SegmentColorWhat it contains
RSC PayloadGreenThe Flight stream embedded in the HTML
HydrationPurpleSerialized "use cache" entries inlined for the client
HTMLBlueEverything else (markup, scripts, styles)

Total and transferred sizes are shown below the bar. If the transferred size is smaller, the server is compressing the response.

The dropdown lists every payload captured during the session. Each entry shows the URL, total byte size, and chunk count. Select one to inspect it.

LabelWhat it captures
⚡ initialThe Flight data from the first page load
🔄 streamAdditional chunks that arrived after the initial response (streamed through Suspense boundaries)
🧭 navFlight responses triggered by client-side navigations

Below the summary badges, the chunk list shows every Flight protocol row:

ColumnMeaning
IDThe chunk identifier
TypeA colored tag: Model (component tree data), Module (client component import), Error, Hint (resource preload), Debug, Text, Binary, or Console
SizeHow many bytes that chunk occupies
DataA truncated preview of the chunk content

Type the name of a tag (e.g., module) or any content substring into the filter field to narrow the list.

Expand the Client References section to see every "use client" module the server referenced. Each entry shows the module path and exported name. Hover over a reference to highlight the corresponding DOM element on the page with a green overlay. Click a reference to scroll the chunk list to the matching Module chunk.

The Cache tab records every "use cache" call — both on the server and on the client — and shows whether it was a hit, a miss, or a revalidation.

Each row in the event list contains:

ColumnMeaning
TimeWhen the call happened
Typehit (served from cache), miss (computed and stored), or revalidate (re-computed in the background)
Providerrequest (lives for one request only) or default (persists across requests)
FunctionThe cached function name and the arguments it was called with
SourceFile path and line number — click to open in VS Code
TTLShown on misses and revalidations; how long the entry is valid

The toolbar at the top shows aggregate hit/miss/revalidation counts. Use the filter buttons to show only one type at a time.

Hover over any default-provider cache event and click on the right. This immediately invalidates the entry on the server and removes it from the event list. The next call to that function will be a miss. Request-scoped cache entries cannot be invalidated manually because they are discarded at the end of the request anyway.

If your page uses "use cache" with request-scoped caching, the server serializes those cache entries into the HTML so the client can hydrate without re-fetching. The collapsible request cache section at the top of the Cache tab lists these hydrated entries with their hashed keys, byte sizes, and a preview of the serialized data.

The Routes tab shows the full route tree produced by the file-system router. Every page, layout, middleware, API route, error boundary, loading state, fallback, template, and named outlet is listed.

ControlHow to use it
Text filterType a path fragment, filename, outlet name, or HTTP method to narrow the list
Type buttonsClick a type (page, layout, middleware, api, error, loading, fallback, template, outlet) to show only that type. The count badge on each button tells you how many routes of that type exist
Active toggleClick "active" to hide everything that does not match the current server pathname. This is useful to see exactly which layouts, middlewares, and pages are involved in rendering the current URL

Routes matching the current server pathname are highlighted with a green left border. The matching accounts for dynamic segments ([param]), optional parameters ([[optional]]), and catch-all patterns ([...slug]). Layouts, middlewares, and templates match as prefixes (they are active for all child paths), while pages must match exactly.

Note: the pathname used for matching is the server pathname (after any rewrites), not the client-visible URL.

Each route row shows a file-type icon (React/JSX, TypeScript, MDX, etc.) and the relative source path. Click the source path to open the file in VS Code.

Below the file-router tree, a Component Routes section appears if your app registers routes via <Route> components in code. Each entry shows the route pattern, type (server, client, or fallback), and flags like remote, exact, or loading. Active component routes display the matched path parameters inline.

The Outlets tab lists every named outlet currently rendered on the page. Outlets are the named slots (@sidebar, @content, etc.) that layouts receive as props, plus PAGE_ROOT for the root rendering slot.

FieldMeaning
NameThe outlet identifier
URLThe URL the outlet content was loaded from (if applicable)
BadgeHow the outlet is managed: router (file-router), remote (fetched from another server), live (streaming), defer (lazily loaded), or static

Hover over any outlet card. A colored dashed rectangle appears around that outlet's rendered area on the page, with a label showing the outlet name. Each outlet gets a distinct color so you can visually map the cards to sections of the page.

The highlight overlay handles edge cases: hidden marker elements, outlets that render as multiple sibling elements (the overlay covers the union bounding rect), and full-screen backdrop elements (which are filtered out so the actual content is highlighted).

ActionWhat it does
Scrolls the page to the outlet's position
Re-renders that single outlet without a full page reload — useful when you want to test server-side changes for one section of the page without navigating away

If your app uses <RemoteComponent> to load RSC content from other react-server instances, the Remotes tab shows each one.

Each card shows:

FieldMeaning
Remote URLThe URL the component is fetched from. Click to open it in a new browser tab
Outlet nameThe outlet this remote component renders into
TTL badgeHow long the response is cached
isolate badgeThe component is rendered in a sandbox
defer badgeThe component is loaded lazily
live badgeThe component streams real-time updates

Hover to highlight the remote component on the page. Click to scroll to it. Click to jump to its outlet in the Outlets tab.

The Live tab monitors every "use live" component — async generator functions on the server that yield successive renders to the client.

Each card shows the component's name, its current state, and runtime statistics:

StateMeaning
startingThe generator is being initialized
waitingWaiting before the next yield
running / connectedActively streaming to the client
finishedThe generator returned normally
abortedThe client disconnected
errorThe generator threw an exception (the error message is shown inline)

A streaming badge appears while data is being sent. The card also shows how many times the generator has yielded, when the last yield happened, and when the component started. If the component is loaded from a remote server, a remote badge appears.

The Workers tab tracks "use worker" threads — both server-side Worker Threads (Node.js) and client-side Web Workers.

The toolbar summarizes how many workers exist, broken down by type. Use the filter buttons to show only server or only client workers.

Each worker entry shows:

FieldMeaning
Typeserver or client
StateSpawning (thread starting), Ready (idle), Error (last call failed), or Restarting
Module pathThe file that defines the worker, shortened to the last few path segments
Call countTotal invocations and how many are currently in flight
Error / restart countsHelps spot unstable workers
Last functionThe name of the most recently called export
TimingWhen the worker was spawned and when it was last invoked

The Logs tab streams all server terminal output (stdout and stderr) into the browser so you don't need to switch back to the terminal.

ControlHow to use it
Stream buttonsClick stdout or stderr to show only that stream. The count on each button tells you how many entries of that type exist
Search fieldType any text to filter log entries. The search matches against the plain text content with ANSI codes stripped

Server logs often contain ANSI escape codes for colors and text styling. The Logs tab renders these faithfully — 4-bit, 8-bit, and 24-bit (true-color) sequences are all supported, including bold, italic, underline, and dim. What you see in the panel matches what you'd see in a terminal.

By default the log view stays pinned to the bottom so new entries scroll into view as they arrive. Scroll up to pause auto-scrolling. A Scroll to bottom button appears at the bottom of the panel — click it to resume.

Click Clear in the toolbar to empty the log buffer.

Several tabs let you hover over an item to highlight the corresponding element on the page:

The overlay is a colored dashed rectangle with a label badge showing the name. It repositions in real time as you scroll or resize the page.

The panel UI runs inside an iframe served from /__react_server_devtools__/*. This keeps the DevTools React tree separate from your app — it won't interfere with your component state or styling.

Three communication channels connect the parts: