npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

react-swc-suspense-tracker

v0.5.0

Published

A development tool that tracks which React Suspense boundary catches thrown promises for easier debugging

Readme

react-swc-suspense-tracker

npm version CI

A development tool that helps you track which React Suspense and Error boundaries handle thrown promises and errors, making it easier to debug your React applications that use Suspense for data fetching and Error boundaries for error handling.

Screenshot of React Dev Tools with Suspense Boundary Information

The Problem

React Suspense uses thrown Promises to pause rendering until data is ready, and Error boundaries catch thrown errors to handle failures gracefully. However, there's no public API to identify which boundary catches a suspension or error. This makes debugging difficult when you have multiple nested boundaries and need to understand the flow of suspensions and errors in your app.

The Solution

This package provides:

  • SWC Plugin: Automatically replaces Suspense and ErrorBoundary imports to use trackable versions
  • Development Hooks: Utilities to detect missing boundaries and debug suspension/error flow

Installation

npm install --save-dev react-swc-suspense-tracker

Usage

Next.js Setup

Add the plugin to your next.config.js:

module.exports = {
  experimental: {
    swcPlugins: [
      [
        "react-swc-suspense-tracker/swc",
        {
          // Optional: track custom boundary components
          boundaries: [
            { component: "ErrorBoundary", from: "react-error-boundary" }
          ]
        }
      ],
    ],
  },
};

*Note: The plugin is enabled by default in development mode and disabled in production builds. You can override this behavior by setting the enabled option.

Plugin Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | enabled | boolean | true on development false in production | Enable/disable the plugin transformation | | boundaries | Array<{component: string, from: string}> | [] | Additional boundary components to track (e.g., custom Error boundaries) |

Using with SWC directly

Add to your .swcrc:

{
  "jsc": {
    "experimental": {
      "plugins": [
        [
          "react-swc-suspense-tracker/swc",
          {
            "boundaries": [
              { "component": "ErrorBoundary", "from": "react-error-boundary" }
            ]
          }
        ]
      ]
    }
  }
}

Debugging Suspense Boundaries

The following example shows how you can debug specific hooks that might suspend.

Note: By default suspenseInfo will always be null in production mode. To change that you have to set the enabled option to true in the SWC plugin configuration.

import { useQuery } from 'react-query';
import { wrapSuspendableHook } from 'react-swc-suspense-tracker';

const useQueryWithDebug = process.env.NODE_ENV === 'production'
 ? useQuery
 : wrapSuspendableHook(
  useQuery,
  (suspenseBoundaries, queryKey) => {
    if (suspenseBoundaries.length === 0) {
     console.warn(`Suspense triggered by ${queryKey} but no Suspense boundary found`);
    } else {
     console.info(`Suspense triggered by ${queryKey} for boundary: ${suspenseBoundaries[0]}`);
    }
  }
);

function MyComponent() {
  const { data } = useQueryWithDebug('my-query-key', fetchData);
  return <div>{data}</div>;
}

Throwing Errors for Missing Suspense Boundaries

If you want to ensure that your component is wrapped in a Suspense boundary, you can use the useThrowIfSuspenseMissing hook. This will throw an error in development if the component might suspend but has no Suspense boundary above it.

import { useThrowIfSuspenseMissing } from "react-swc-suspense-tracker";

function MyComponent() {
  // This will throw an error in development if no Suspense boundary is found
  useThrowIfSuspenseMissing();

  const data = useSomeDataHook(); // This might suspend
  return <div>{data}</div>;
}

Result:

Simple usage screenshot of useThrowIfSuspenseMissing

What the SWC Plugin does

The plugin automatically transforms:

// Before transformation
import { Suspense } from "react";
<Suspense fallback={<Loading />}>
  <MyComponent />
</Suspense>

// After transformation
import { Suspense } from "react";
import { BoundaryTrackerSWC } from "react-swc-suspense-tracker/context";
<BoundaryTrackerSWC Component={Suspense} fallback={<Loading />} id="my/file.tsx:123">
  <MyComponent />
</BoundaryTrackerSWC>

Custom logger

For custom logging or logging in production you can use the useSuspenseOwner hook to get the ID of the nearest Suspense boundary:

import { 
  useSuspenseOwner,
} from "react-swc-suspense-tracker";
function MyComponent() {
  const suspenseOwner = useSuspenseOwner();
  
  // Log the Suspense boundary ID
  console.log("Closest Suspense boundary ID:", suspenseOwner);

  const data = useSomeDataHook(); // This might suspend
  return <div>{data}</div>;
}

API Reference

Hooks

useSuspenseOwner(): string | null

Returns the ID of the nearest Suspense boundary above this component. The ID format is "file.tsx:line" if set by the SWC plugin, or a custom string if set manually.

Returns null if no Suspense boundary is found.

useBoundaryStack(): Array<[string, ComponentType]>

Returns information about all boundary components above this component as an array of [boundaryId, BoundaryComponent] tuples, ordered from outermost to innermost boundary.

Returns empty array if no boundaries are found.

useThrowIfSuspenseMissing(skip?: boolean): void

Throws an error in development if this component might suspend but has no Suspense boundary above it - NOOP in production builds

Parameters:

  • skip (optional): If true, skips the check. Defaults to false.

Throws: Error with message explaining the missing Suspense boundary.

wrapSuspendableHook<T>(hook: T, onSuspense: (suspenseBoundaries: string[], ...args: Parameters<T>) => void): T

Wraps a hook to catch Suspense errors and call the provided onSuspense function with the current Suspense boundary information.

Parameters:

  • hook: The hook function to wrap
  • onSuspense: Function called when the hook suspends, receives array of Suspense boundary IDs

Returns: A wrapped version of the hook with the same signature.

Development vs Production

This package is designed for development use only. The SWC plugin should be disabled in production builds to avoid the additional runtime overhead.

Build

Get the Rust toolchain and the right target:

rustup target add wasm32-wasip1
npm run build

The compiled Wasm module will be available as react_swc_suspense_tracker.wasm.

License

MIT