Skip to content

vladbars/whyrn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

WhyRN

WhyRN

See exactly why your React Native components re-render.

npm version npm downloads license


WhyRN Demo

Components flash on re-render. A badge tells you why. No more guessing.


Why?

Ever stared at your React Native app and asked:

  • "Why is this re-rendering?"
  • "Why is my FlatList so laggy?"
  • "Which prop is causing this?"

React Native doesn't tell you. The Profiler gives you timing, not reasons. Console logs don't show you where.

WhyRN does.

It highlights re-renders on screen, shows the exact reason β€” which prop changed, which state updated, whether it's a new reference or a real value change β€” and paints a heatmap so you can spot the hottest components instantly.


Features

  • πŸ” Highlights re-renders in real time β€” components flash with a colored border
  • 🧠 Shows exact reason β€” props, state, hooks, or parent re-render
  • πŸ” Props diff β€” distinguishes reference change vs value change
  • 🌑️ Heatmap mode β€” cold (blue) to hot (red) based on render frequency
  • ⚑ Zero config β€” wrap your app, done
  • πŸ“± React Native first β€” built for mobile, not a web port
  • πŸͺΆ Zero dependencies β€” only React and React Native as peers
  • πŸ”‡ Dev only β€” no-op in production, tree-shaken away

Install

npm install whyrn.dev
yarn add whyrn.dev

Usage

import { WhyRN } from 'whyrn.dev';

export default function App() {
  return (
    <WhyRN>
      <YourApp />
    </WhyRN>
  );
}

That's it. No init function, no config files, no babel plugins.

Every component that re-renders will flash on screen with a badge showing the reason.


Example Output

When a component re-renders, you see this in the console:

πŸ” UserCard re-rendered (#4)
  prop "user" changed (new reference, same value)
  state[0] changed: 1 β†’ 2

And on screen:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ UserCard β€” props: user       β”‚  ← badge
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                              β”‚
β”‚     β”Œβ”€β”€β”€ red border ───┐    β”‚  ← flash overlay
β”‚     β”‚                   β”‚    β”‚
β”‚     β”‚    UserCard       β”‚    β”‚
β”‚     β”‚                   β”‚    β”‚
β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Track Specific Components

Don't want to track everything? Use the HOC:

import { withWhyRN } from 'whyrn.dev';

function UserCard({ user }) {
  return <Text>{user.name}</Text>;
}

export default withWhyRN(UserCard);

Or the hook, for full control:

import { useWhyRN } from 'whyrn.dev';

function UserCard(props) {
  const reasons = useWhyRN('UserCard', props);
  // reasons = [{ type: 'props', propChanges: [...] }]
  return <Text>{props.user.name}</Text>;
}

Heatmap Mode

See which components render the most β€” cold (blue) means few renders, hot (red) means many:

<WhyRN heatmap>
  <YourApp />
</WhyRN>

The border color shifts based on render frequency in a 5-second sliding window.


Configuration

All options are passed as props. Every prop is optional.

<WhyRN
  enabled={__DEV__}              // Kill switch (default: __DEV__)
  trackHooks                     // Track useState/useReducer (default: true)
  logToConsole                   // Log to console (default: true)
  heatmap                        // Heatmap mode (default: false)
  flashDuration={600}            // Flash duration in ms (default: 600)
  flashColor="#FF6B6B"           // Flash border color (default: #FF6B6B)
  heatmapColdColor="#3B82F6"     // Heatmap cold color (default: #3B82F6)
  heatmapHotColor="#EF4444"      // Heatmap hot color (default: #EF4444)
  include={[/Screen/, /Card/]}   // Only track matching names (default: [])
  exclude={[/^RN/, /^RCT/]}     // Skip matching names (default: RN internals)
>
  <YourApp />
</WhyRN>

API Reference

<WhyRN>

Root provider. Wraps your app to enable visual overlays and auto-tracking.

withWhyRN(Component, name?)

HOC that tracks a specific component. Works with or without <WhyRN> β€” without the wrapper, it logs to console only.

useWhyRN(name, props)

Hook that returns an array of RenderReason objects for the current render. Useful for custom debugging UI or logging.

useRenderCount(name?)

Simple hook that returns how many times the component has rendered. Optionally logs to console.


Comparison

Feature why-did-you-render React DevTools WhyRN
React Native support ⚠️ Partial βœ… βœ…
Visual overlay ❌ ⚠️ Border only βœ… Flash + badge
Shows why ⚠️ Console only ❌ βœ… On screen
Props diff βœ… ❌ βœ…
Reference vs value ⚠️ ❌ βœ…
Heatmap ❌ ❌ βœ…
Zero config ❌ Needs init + babel ❌ βœ…
Hook tracking βœ… ❌ βœ…

How It Works

  1. <WhyRN> patches React.createElement on mount to wrap tracked components with a thin HOC
  2. The HOC stores previous props in a useRef and diffs on every render
  3. When a re-render is detected, it calls measureInWindow to get the component's screen position
  4. A global overlay renders an Animated.View border that fades out, plus a reason badge
  5. In heatmap mode, the border color is computed from the render rate in a sliding window

Since we only care about re-renders (not the first render), patching at mount time is fine. The library is a complete no-op when __DEV__ is false.


Requirements

  • React 18+
  • React Native 0.70+
  • Hermes or JSC

Roadmap

  • Expo Snack playground
  • State variable name extraction (babel plugin)
  • Flipper / DevTools integration
  • Per-component render timeline
  • Re-render count badge overlay
  • Context tracking with provider name

Contributing

Contributions are welcome! Please open an issue first to discuss what you'd like to change.


License

MIT


If WhyRN helps you debug faster, consider giving it a ⭐
github.com/vladbars/whyrn

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors