diff --git a/public/images/docs/suspense-panel/boundary-filter.dark.png b/public/images/docs/suspense-panel/boundary-filter.dark.png
new file mode 100644
index 00000000000..d2f6d140afa
Binary files /dev/null and b/public/images/docs/suspense-panel/boundary-filter.dark.png differ
diff --git a/public/images/docs/suspense-panel/boundary-filter.png b/public/images/docs/suspense-panel/boundary-filter.png
new file mode 100644
index 00000000000..19a4b2fbf01
Binary files /dev/null and b/public/images/docs/suspense-panel/boundary-filter.png differ
diff --git a/public/images/docs/suspense-panel/boundary-map.dark.png b/public/images/docs/suspense-panel/boundary-map.dark.png
new file mode 100644
index 00000000000..31210b75155
Binary files /dev/null and b/public/images/docs/suspense-panel/boundary-map.dark.png differ
diff --git a/public/images/docs/suspense-panel/boundary-map.png b/public/images/docs/suspense-panel/boundary-map.png
new file mode 100644
index 00000000000..31210b75155
Binary files /dev/null and b/public/images/docs/suspense-panel/boundary-map.png differ
diff --git a/public/images/docs/suspense-panel/forced-fallback.dark.png b/public/images/docs/suspense-panel/forced-fallback.dark.png
new file mode 100644
index 00000000000..d2f6d140afa
Binary files /dev/null and b/public/images/docs/suspense-panel/forced-fallback.dark.png differ
diff --git a/public/images/docs/suspense-panel/forced-fallback.png b/public/images/docs/suspense-panel/forced-fallback.png
new file mode 100644
index 00000000000..19a4b2fbf01
Binary files /dev/null and b/public/images/docs/suspense-panel/forced-fallback.png differ
diff --git a/public/images/docs/suspense-panel/overview.dark.png b/public/images/docs/suspense-panel/overview.dark.png
new file mode 100644
index 00000000000..31210b75155
Binary files /dev/null and b/public/images/docs/suspense-panel/overview.dark.png differ
diff --git a/public/images/docs/suspense-panel/overview.png b/public/images/docs/suspense-panel/overview.png
new file mode 100644
index 00000000000..31210b75155
Binary files /dev/null and b/public/images/docs/suspense-panel/overview.png differ
diff --git a/public/images/docs/suspense-panel/reveal-timeline.dark.png b/public/images/docs/suspense-panel/reveal-timeline.dark.png
new file mode 100644
index 00000000000..d2f6d140afa
Binary files /dev/null and b/public/images/docs/suspense-panel/reveal-timeline.dark.png differ
diff --git a/public/images/docs/suspense-panel/reveal-timeline.png b/public/images/docs/suspense-panel/reveal-timeline.png
new file mode 100644
index 00000000000..19a4b2fbf01
Binary files /dev/null and b/public/images/docs/suspense-panel/reveal-timeline.png differ
diff --git a/public/images/docs/suspense-panel/suspended-by.dark.png b/public/images/docs/suspense-panel/suspended-by.dark.png
new file mode 100644
index 00000000000..7c443215037
Binary files /dev/null and b/public/images/docs/suspense-panel/suspended-by.dark.png differ
diff --git a/public/images/docs/suspense-panel/suspended-by.png b/public/images/docs/suspense-panel/suspended-by.png
new file mode 100644
index 00000000000..7c443215037
Binary files /dev/null and b/public/images/docs/suspense-panel/suspended-by.png differ
diff --git a/src/content/reference/dev-tools/react-suspense-panel.md b/src/content/reference/dev-tools/react-suspense-panel.md
new file mode 100644
index 00000000000..f309a2e2bc0
--- /dev/null
+++ b/src/content/reference/dev-tools/react-suspense-panel.md
@@ -0,0 +1,652 @@
+---
+title: React Suspense panel
+---
+
+
+
+The Suspense panel in React Developer Tools lets you inspect [``](/reference/react/Suspense) boundaries, find what caused them to suspend, and preview the order in which they reveal their content.
+
+
+
+
+
+The Suspense panel is currently available in the React Developer Tools extension for Chrome when it connects to a development build of React 19.3 Canary. It is not available for production builds. Other browser integrations may not include it yet.
+
+
+
+{/* TODO: Replace the screenshot placeholders before marking this PR ready. */}
+
+
+

+

+
+
+
+
+---
+
+## Usage {/*usage*/}
+
+To open the Suspense panel:
+
+1. [Install React Developer Tools for Chrome](/learn/react-developer-tools#browser-extension).
+2. Open a page that uses a development build of React 19.3 Canary.
+3. Open the browser developer tools and select **Suspense ⚛**.
+
+If the panel does not appear, reload the page with the browser developer tools open.
+
+The examples on this page run inside embedded frames. The screenshots show how each example appears in the Suspense panel. To inspect an example interactively, fork it and open its preview as a separate page.
+
+---
+
+## Panel features {/*panel-features*/}
+
+### Inspecting Suspense boundaries {/*inspecting-suspense-boundaries*/}
+
+The main view is a scaled map of the Suspense boundaries on the page. Each outlined region represents the content inside a boundary.
+
+This example contains an outer boundary for the artist details and a nested boundary for the albums:
+
+
+
+```js src/App.js active
+import { Suspense, use } from 'react';
+import { fetchData } from './data.js';
+
+export default function App() {
+ return (
+
+ The Beatles
+ Loading artist...}>
+
+ }>
+
+
+
+
+ );
+}
+
+function Biography() {
+ const biography = use(fetchData('/biography'));
+ return {biography}
;
+}
+
+function Albums() {
+ const albums = use(fetchData('/albums'));
+ return (
+
+ Albums
+
+ {albums.map(album => (
+ - {album.title}
+ ))}
+
+
+ );
+}
+
+function AlbumsGlimmer() {
+ return (
+
+ );
+}
+```
+
+```js src/data.js hidden
+const cache = new Map();
+
+export function fetchData(url) {
+ if (!cache.has(url)) {
+ cache.set(url, getData(url));
+ }
+ return cache.get(url);
+}
+
+async function getData(url) {
+ if (url === '/biography') {
+ await wait(800);
+ return 'The Beatles were an English rock band formed in Liverpool.';
+ }
+
+ if (url === '/albums') {
+ await wait(1800);
+ return [
+ { id: 1, title: 'Revolver' },
+ { id: 2, title: 'Abbey Road' },
+ { id: 3, title: 'Let It Be' },
+ ];
+ }
+
+ throw Error('Not implemented');
+}
+
+function wait(ms) {
+ return new Promise(resolve => {
+ setTimeout(resolve, ms);
+ });
+}
+```
+
+```css
+.bio {
+ font-style: italic;
+}
+
+.panel {
+ border: 1px solid #aaa;
+ border-radius: 6px;
+ margin-top: 20px;
+ padding: 10px;
+}
+
+.glimmer-panel {
+ background: linear-gradient(90deg, #ddd 0%, #fff 100%);
+ border: 1px dashed #aaa;
+ border-radius: 6px;
+ margin-top: 20px;
+ padding: 10px;
+}
+
+.glimmer-line {
+ background: #f0f0f0;
+ border-radius: 4px;
+ height: 20px;
+ margin: 10px;
+ width: 60%;
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "19.3.0-canary-eb8feb71-20260814",
+ "react-dom": "19.3.0-canary-eb8feb71-20260814",
+ "react-scripts": "latest"
+ },
+ "scripts": {
+ "start": "react-scripts start"
+ }
+}
+```
+
+
+
+Hover over a region in the map to highlight its content on the page. Select a region to inspect that boundary. For nested boundaries, use the breadcrumbs above the map to move through their hierarchy.
+
+You can also select the inspect button in the panel, and then select content on the page.
+
+
+

+

+
+
+### Finding what caused a boundary to suspend {/*finding-what-caused-a-boundary-to-suspend*/}
+
+After you select a boundary, the inspector shows whether it is suspended and which Components rendered it. The **Suspended by** section shows the work that caused it to suspend.
+
+In this example, one boundary waits for a Promise read with [`use`](/reference/react/use), while another waits for a Component loaded with [`lazy`](/reference/react/lazy):
+
+
+
+```js src/App.js active
+import { lazy, Suspense, use } from 'react';
+import { fetchBiography } from './data.js';
+
+const Albums = lazy(async () => {
+ await new Promise(resolve => {
+ setTimeout(resolve, 1800);
+ });
+ return import('./Albums.js');
+});
+
+export default function App() {
+ return (
+
+ The Beatles
+ Loading biography...}>
+
+
+ Loading albums...}>
+
+
+
+ );
+}
+
+function Biography() {
+ const biography = use(fetchBiography());
+ return {biography}
;
+}
+```
+
+```js src/Albums.js hidden
+export default function Albums() {
+ return (
+
+ Albums
+
+ - Revolver
+ - Abbey Road
+
+
+ );
+}
+```
+
+```js src/data.js hidden
+let biographyPromise;
+
+export function fetchBiography() {
+ if (!biographyPromise) {
+ biographyPromise = getBiography();
+ }
+ return biographyPromise;
+}
+
+async function getBiography() {
+ await new Promise(resolve => {
+ setTimeout(resolve, 900);
+ });
+ return 'The Beatles were an English rock band formed in Liverpool.';
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "19.3.0-canary-eb8feb71-20260814",
+ "react-dom": "19.3.0-canary-eb8feb71-20260814",
+ "react-scripts": "latest"
+ },
+ "scripts": {
+ "start": "react-scripts start"
+ }
+}
+```
+
+
+
+Development builds can show causes such as `lazy`, Promises read with `use`, and resources including stylesheets, fonts, and images. Expand a cause to inspect the available details and timing.
+
+
+

+

+
+
+### Previewing a fallback {/*previewing-a-fallback*/}
+
+After this profile finishes loading, select its boundary in the panel. Use the suspend control in the inspector to replace the profile with its fallback. Use the control again to reveal the content.
+
+
+
+```js src/App.js active
+import { Suspense, use } from 'react';
+import { getProfile } from './data.js';
+
+export default function App() {
+ return (
+ }>
+
+
+ );
+}
+
+function Profile() {
+ const profile = use(getProfile());
+ return (
+
+
+
+
{profile.name}
+
{profile.bio}
+
+
+ );
+}
+
+function ProfileGlimmer() {
+ return (
+
+ );
+}
+```
+
+```js src/data.js hidden
+let profilePromise;
+
+export function getProfile() {
+ if (!profilePromise) {
+ profilePromise = loadProfile();
+ }
+ return profilePromise;
+}
+
+async function loadProfile() {
+ await new Promise(resolve => {
+ setTimeout(resolve, 1200);
+ });
+ return {
+ name: 'Rachel Bloom',
+ bio: 'Singer, actor, and comedian.',
+ avatar: 'https://i.imgur.com/yXOvdOSs.jpg',
+ };
+}
+```
+
+```css
+.profile {
+ align-items: center;
+ border: 1px solid #aaa;
+ border-radius: 6px;
+ display: flex;
+ gap: 14px;
+ padding: 14px;
+}
+
+.profile img,
+.avatar {
+ border-radius: 50%;
+ height: 70px;
+ width: 70px;
+}
+
+.glimmer {
+ border-style: dashed;
+}
+
+.avatar,
+.line {
+ background: #e5e5e5;
+}
+
+.line {
+ border-radius: 4px;
+ height: 14px;
+ margin: 8px 0;
+ width: 220px;
+}
+
+.title {
+ height: 22px;
+ width: 140px;
+}
+
+.short {
+ width: 170px;
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "19.3.0-canary-eb8feb71-20260814",
+ "react-dom": "19.3.0-canary-eb8feb71-20260814",
+ "react-scripts": "latest"
+ },
+ "scripts": {
+ "start": "react-scripts start"
+ }
+}
+```
+
+
+
+The suspend control is not available while the boundary is already suspended. Forcing a boundary to suspend lets you check its loading state without changing the app's data or adding temporary code.
+
+
+

+

+
+
+### Replaying the reveal sequence {/*replaying-the-reveal-sequence*/}
+
+The timeline starts with the initial paint and adds a step when a Suspense boundary reveals its content. This example reveals the biography first, followed by the albums and related artists:
+
+
+
+```js src/App.js active
+import { Suspense, use } from 'react';
+import { fetchData } from './data.js';
+
+export default function App() {
+ return (
+
+ The Beatles
+ Loading biography...}>
+
+
+ }>
+
+
+ }>
+
+
+
+ );
+}
+
+function Biography() {
+ const biography = use(fetchData('/biography'));
+ return {biography}
;
+}
+
+function Albums() {
+ const albums = use(fetchData('/albums'));
+ return ;
+}
+
+function RelatedArtists() {
+ const artists = use(fetchData('/related-artists'));
+ return ;
+}
+
+function ItemList({ title, items }) {
+ return (
+
+ {title}
+
+ {items.map(item => - {item}
)}
+
+
+ );
+}
+
+function ListGlimmer() {
+ return (
+
+ );
+}
+```
+
+```js src/data.js hidden
+const cache = new Map();
+
+export function fetchData(url) {
+ if (!cache.has(url)) {
+ cache.set(url, getData(url));
+ }
+ return cache.get(url);
+}
+
+async function getData(url) {
+ const values = {
+ '/biography': {
+ delay: 700,
+ value: 'The Beatles were an English rock band formed in Liverpool.',
+ },
+ '/albums': {
+ delay: 1500,
+ value: ['Revolver', 'Abbey Road'],
+ },
+ '/related-artists': {
+ delay: 2300,
+ value: ['The Beach Boys', 'The Kinks'],
+ },
+ };
+ const result = values[url];
+ if (!result) {
+ throw Error('Not implemented');
+ }
+ await new Promise(resolve => {
+ setTimeout(resolve, result.delay);
+ });
+ return result.value;
+}
+```
+
+```css
+.bio {
+ font-style: italic;
+}
+
+.panel {
+ border: 1px solid #aaa;
+ border-radius: 6px;
+ margin-top: 20px;
+ padding: 10px;
+}
+
+.glimmer-panel {
+ background: linear-gradient(90deg, #ddd 0%, #fff 100%);
+ border: 1px dashed #aaa;
+ border-radius: 6px;
+ margin-top: 20px;
+ padding: 10px;
+}
+
+.glimmer-line {
+ background: #f0f0f0;
+ border-radius: 4px;
+ height: 20px;
+ margin: 10px;
+ width: 60%;
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "19.3.0-canary-eb8feb71-20260814",
+ "react-dom": "19.3.0-canary-eb8feb71-20260814",
+ "react-scripts": "latest"
+ },
+ "scripts": {
+ "start": "react-scripts start"
+ }
+}
+```
+
+
+
+Use the previous and next buttons or drag the timeline to move between steps. Select play to advance through the steps automatically. The panel updates the inspected page to show the fallbacks and content that were visible at each step.
+
+The timeline previews the reveal sequence. It is not a performance recording and does not represent how long each boundary took to load.
+
+
+

+

+
+
+### Showing all boundaries {/*showing-all-boundaries*/}
+
+By default, the panel hides boundaries that do not suspend independently. This includes a boundary that never suspends and one that always reveals with its parent boundary.
+
+The boundary around the heading in this example never suspends. Turn off the boundary filter to include it in the map:
+
+
+
+```js src/App.js active
+import { Suspense, use } from 'react';
+import { getAlbums } from './data.js';
+
+export default function App() {
+ return (
+
+ Loading title...}>
+ The Beatles
+
+ Loading albums...}>
+
+
+
+ );
+}
+
+function Albums() {
+ const albums = use(getAlbums());
+ return (
+
+ {albums.map(album => - {album}
)}
+
+ );
+}
+```
+
+```js src/data.js hidden
+let albumsPromise;
+
+export function getAlbums() {
+ if (!albumsPromise) {
+ albumsPromise = loadAlbums();
+ }
+ return albumsPromise;
+}
+
+async function loadAlbums() {
+ await new Promise(resolve => {
+ setTimeout(resolve, 1200);
+ });
+ return ['Revolver', 'Abbey Road', 'Let It Be'];
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "19.3.0-canary-eb8feb71-20260814",
+ "react-dom": "19.3.0-canary-eb8feb71-20260814",
+ "react-scripts": "latest"
+ },
+ "scripts": {
+ "start": "react-scripts start"
+ }
+}
+```
+
+
+
+
+

+

+
+
+---
+
+## Troubleshooting {/*troubleshooting*/}
+
+### I don't see the Suspense panel {/*i-dont-see-the-suspense-panel*/}
+
+Check that you are using the React Developer Tools extension for Chrome and that the inspected page uses a development build of React 19.3 Canary. Reload the page after opening the browser developer tools so the extension can detect React.
+
+Chrome keeps a custom developer tools panel after an extension creates it. This means the Suspense panel can remain visible if you navigate from a compatible app to a page that uses another version of React. Close and reopen the browser developer tools to check whether the current page supports the panel.
+
+### The panel does not show any boundaries {/*the-panel-does-not-show-any-boundaries*/}
+
+The panel only shows boundaries rendered with [``](/reference/react/Suspense). If the panel says that the root contains no Suspense nodes, check that the inspected page has rendered a boundary.
+
+If the page contains a boundary but it does not appear, turn off the boundary filter.
diff --git a/src/sidebarReference.json b/src/sidebarReference.json
index 06bb6d1cc9e..db519810773 100644
--- a/src/sidebarReference.json
+++ b/src/sidebarReference.json
@@ -409,6 +409,10 @@
"title": "React Performance tracks",
"path": "/reference/dev-tools/react-performance-tracks"
},
+ {
+ "title": "React Suspense panel",
+ "path": "/reference/dev-tools/react-suspense-panel"
+ },
{
"hasSectionHeader": true,
"sectionHeader": "eslint-plugin-react-hooks"