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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@moraisdeoliveirawesley/react-performance-guard

v0.0.3

Published

React performance library that automatically detects unnecessary re-renders, mutable props, heavy components, and more

Downloads

409

Readme

react-performance-guard

npm version npm downloads GitHub Repo stars

React performance library that automatically detects common issues and points to where they occur (file:line via stack trace). Use it in development to fix unnecessary re-renders, mutable props, heavy components, render storms, inline objects, large lists, setState after unmount, and more.

Features

| Detector | What it catches | Where it points | |----------|------------------|------------------| | Unnecessary re-render | Same props (shallow) but component re-rendered | Component that re-rendered (use React.memo or move state down) | | Mutable props | Props object mutated after being passed | Component that received mutated props | | Heavy component | Commit phase > threshold (e.g. 16ms) | Component (or tree) under <PerfGuardBoundary> | | Render storm | Too many re-renders in a short window | Component that stormed | | Possible setState in render | Synchronous re-renders (e.g. 5 in <5ms) | Component that likely calls setState during render | | Inline objects/functions | New object/function references in props every render | Component receiving inline props (parent should use useMemo/useCallback) | | Large list | Rendering many items without virtualization | Where useLargeListCheck(length) was called | | setState after unmount | setState called after component unmounted | Component that used useSafeState and triggered after unmount |

Every reported issue includes optional stackTrace and location (parsed file, line, column) so you can jump straight to the problematic code.

Install

npm install react-perf-guard
# or
yarn add react-perf-guard
pnpm add react-perf-guard

Peer dependency: React 16.8+ (hooks).

Quick start

1. Optional: global config (e.g. in app root)

import { configurePerfGuard } from 'react-perf-guard';

configurePerfGuard({
  onIssue: (issue) => {
    // issue.location => { file, line, column } — where the problem was detected
    console.warn('[Perf]', issue.category, issue.message, issue.location);
  },
});

2. Per-component: hook (recommended)

import { usePerfGuard } from 'react-perf-guard';

function MyCard({ title, count }: { title: string; count: number }) {
  usePerfGuard({ title, count }, { componentName: 'MyCard' });
  return <div>{title}: {count}</div>;
}

This enables: re-render, mutable props, render storm, and inline props detection. In the console you’ll see the location (file:line) when an issue is found.

3. Heavy components: <PerfGuardBoundary>

import { PerfGuardBoundary } from 'react-perf-guard';

<PerfGuardBoundary id="ProductList" heavyThresholdMs={16}>
  <ProductList />
</PerfGuardBoundary>

4. Large lists: useLargeListCheck

import { useLargeListCheck } from 'react-perf-guard';

function ProductList({ items }: { items: Product[] }) {
  useLargeListCheck(items.length, { componentName: 'ProductList', threshold: 50 });
  return (
    <ul>
      {items.map((p) => <li key={p.id}>{p.name}</li>)}
    </ul>
  );
}

5. Avoid setState after unmount: useSafeState

import { useSafeState } from 'react-perf-guard';

function Search() {
  const [query, setQuery] = useSafeState('', { componentName: 'Search' });
  useEffect(() => {
    const id = setTimeout(() => fetchResults(query).then(setResults), 300);
    return () => clearTimeout(id);
  }, [query]);
  // If fetchResults resolves after unmount, setState would run — useSafeState warns and no-ops
  return <input value={query} onChange={(e) => setQuery(e.target.value)} />;
}

6. HOC: withPerfGuard

import { withPerfGuard } from 'react-perf-guard';

const MyCard = withPerfGuard(
  function MyCard({ title }: { title: string }) {
    return <div>{title}</div>;
  },
  { componentName: 'MyCard' }
);

Where is the problem?

Each PerfIssue can include:

  • location{ file?, line?, column?, functionName?, raw? } — parsed from the stack (first frame that isn’t react-perf-guard or React).
  • stackTrace — full Error.stack string.

So in onIssue you can do:

onIssue: (issue) => {
  if (issue.location?.file) {
    console.warn(`${issue.category} at ${issue.location.file}:${issue.location.line}:${issue.location.column}`);
  }
  console.warn(issue.message, issue.details);
}

Stack capture is on by default. To disable (e.g. in production): setCaptureStack(false).

API

Hooks

  • usePerfGuard(props, options?) — Re-render, mutable props, render storm, inline props. Pass props + optional componentName, onIssue, disabled, or per-detector options.
  • useReRenderDetection(props, options?) — Only re-render (same props, shallow).
  • useMutablePropsDetection(props, options?) — Only mutable props.
  • useRenderStormDetection(options?) — Only render storm (and possible setState-in-render when re-renders are synchronous).
  • useInlinePropsDetection(props, options?) — Only new object/function references in props.
  • useLargeListCheck(itemCount, options?) — Warns when itemCount ≥ threshold (default 50). Use in components that render long lists.
  • useSafeState(initialState, options?) — Like useState; warns and no-ops if setState is called after unmount.
  • useHeavyComponentReport(options?) — Returns onRender for <Profiler>. Used by PerfGuardBoundary.

Components

  • <PerfGuardBoundary id="..." heavyThresholdMs={16} onIssue={...}> — Wraps children in Profiler, reports when commit duration exceeds threshold.
  • withPerfGuard(Component, options?) — HOC that injects usePerfGuard.

Config / utils

  • configurePerfGuard(config) — Global onIssue, thresholds, etc.
  • setOnIssue(cb) — Set or clear global issue callback.
  • setCaptureStack(enabled) — Turn stack/location capture on or off (default on).
  • report(issue) — Manually report a PerfIssue.
  • createAndReport(issue) — Like report but enriches with stack/location (used by detectors).
  • captureStackTrace() / parseStackLocation(stack) / captureLocation() / enrichWithLocation(issue) — Low-level stack/location helpers.

Types

  • PerfIssue{ category, severity, message, componentName?, details?, timestamp, stackTrace?, location? }
  • SourceLocation{ file?, line?, column?, functionName?, raw? }
  • IssueCategory'unnecessary-re-render' | 'mutable-props' | 'heavy-component' | 'render-storm' | 'inline-objects' | 'large-list' | 'setState-after-unmount' | 'possible-setState-in-render'
  • OnIssueCallback(issue: PerfIssue) => void

Collecting issues for O1 / evidence

const issues: PerfIssue[] = [];
configurePerfGuard({
  onIssue: (issue) => {
    issues.push(issue);
    if (process.env.NODE_ENV === 'development') {
      console.warn('[react-perf-guard]', issue.category, issue.message, issue.location);
    }
  },
});
// Later: export or send `issues` (including location) for documentation/evidence

License

MIT.