What is React Suspense?

Suspense lets a component wait for something before rendering — a lazy-loaded chunk, a data fetch — and shows a fallback in the meantime. Here's how the boundary works.

4 min read
React
Fundamentals

TABLE OF CONTENTS
What is React Suspense?

React Suspense is a mechanism that lets a component "wait" for something before rendering — usually a lazy-loaded code chunk or a data fetch. While waiting, it shows a fallback (a spinner, skeleton, or placeholder). Suspense is the boundary: it catches the in-progress state and renders the fallback until the child components are ready.


Suspense for Code Splitting

The most common use: React.lazy() defers loading a component until it's first rendered. Suspense catches the loading state:

When React reaches <HeavyChart />, it sees the component isn't loaded yet. It walks up the tree to the nearest <Suspense> boundary and renders its fallback instead. When the import resolves, React replaces the fallback with the real component.

Without Suspense, you'd need loading state, error state, and manual coordination — Suspense collapses all of that into a declarative boundary.


How It Works Under the Hood

Suspense relies on a capability added in React 16.6: components can throw promises. When React.lazy() encounters an unloaded component, it throws the import promise. React catches it at the nearest Suspense boundary, renders the fallback, and waits. When the promise resolves, React re-renders the suspended subtree.

This is an intentional design choice — "throwing" a promise during render signals to React "I'm not ready yet, come back when I am."


Multiple Suspense Boundaries

You can nest Suspense boundaries to control the loading experience granularly:

The outer boundary waits for everything. Inner boundaries isolate loading states — MainContent and Sidebar load independently. If Sidebar takes longer, only the sidebar section shows its skeleton; the main content renders as soon as it's ready.


Suspense and Streaming SSR

React 18 introduced streaming SSR with Suspense. The server sends HTML in chunks as components resolve, rather than waiting for the full page:

The browser receives the shell HTML immediately. <Reviews> arrives later — when its server-side data fetch completes — as an additional chunk of HTML streamed into the page. This eliminates the all-or-nothing wait of traditional SSR.


What Suspense Is NOT

Suspense is not a data-fetching library. It's a coordination mechanism. You still need a data-fetching solution that integrates with Suspense — React Query, SWR, or frameworks like Next.js that provide async Server Components.

Suspense also isn't an error boundary. Use <ErrorBoundary> (or React's built-in error boundary support) alongside Suspense to handle both the loading and error states cleanly.


When to Use It

  • Route-level code splitting. Wrap each route in Suspense with React.lazy().
  • Heavy components below the fold. Charts, editors, maps — split them out and load on demand.
  • Streaming SSR. Mark slow server-side data dependencies with Suspense boundaries for progressive HTML delivery.

Suspense is a declarative loading state primitive. It takes what used to be imperative boilerplate — isLoading, setIsLoading, spinner rendering logic — and replaces it with a boundary that says "if anything in here isn't ready, show this fallback."


Let's Connect

© 2026 Naveen Karthik // Built with React & MUI