Noncommital Premarital Mischief


Share private packages across your team with npm Orgs, now with simplified billing via the aws marketplace!Learn more »


3.3.8 • Public • Published

Why Did You Render

npm version

why-did-you-render monkey patches React to notify you about avoidable re-renders. (Works with React Native as well.)

For example, when you pass style={{width: '100%'}} to a big pure component and make it always re-render:

It can also help you to simply track when and why a certain component re-renders.

Read More

  • You can read more about the library >> HERE <<.
  • Part 2 - Common fixing scenarios this library can help to eliminate can be found >> HERE <<.
  • Part 3 - React Hooks - Understand and fix hooks issues >> HERE <<.
  • Part 4 - React-Redux - Understand and fix react-redux issues >> HERE <<.


You can test the library in the official sandbox >> HERE <<.


npm install @welldone-software/why-did-you-render --save


yarn add @welldone-software/why-did-you-render

Notice: the required React version for the library is >=16.8 but it might work with older versions by using trackHooks: false in whyDidYouRender's init options.


Execute whyDidYouRender with React as it's first argument.

import React from 'react';
if (process.env.NODE_ENV !== 'production') {
  const whyDidYouRender = require('@welldone-software/why-did-you-render');

If you are building for latest browsers and don't transpile the "class" keyword use the "no-classes-transpile" dist:

import React from 'react';
if (process.env.NODE_ENV !== 'production') {
  const whyDidYouRender = require('@welldone-software/why-did-you-render/dist/no-classes-transpile/umd/whyDidYouRender.min.js');

Not doing so will result in a bug where a transpiled class tries to extend a native class:

Class constructors must be invoked with 'new'.


Mark all the components you want to be notified about their re-renders with whyDidYouRender like so:

class BigListPureComponent extends React.PureComponent {
  static whyDidYouRender = true
    return (
      //some heavy render you want to ensure doesn't happen if its not neceserry

Or like this:

const BigListPureComponent = props => (
    //some heavy component you want to ensure doesn't happen if its not neceserry
BigListPureComponent.whyDidYouRender = true

You can also pass an object to specify more advanced settings:

EnhancedMenu.whyDidYouRender = {
  logOnDifferentValues: true,
  customName: 'EnhancedMenu'
  • logOnDifferentValues:

    Normally only re-renders that are caused by equal values in props / state trigger notifications:

    render(<Menu a={1}/>)
    render(<Menu a={1}/>)

    This option will trigger notifications even if they occurred because of different props / state (Thus, because of "legit" re-renders):

    render(<Menu a={1}/>)
    render(<Menu a={2}/>)
  • customName:

    Sometimes the name of the component can be very inconvenient. For example:

    const EnhancedMenu = Connect(withPropsOnChange(withPropsOnChange(withStateHandlers(withPropsOnChange(withState(withPropsOnChange(lifecycle(withPropsOnChange(withPropsOnChange(onlyUpdateForKeys(LoadNamespace(Connect(withState(withState(withPropsOnChange(lifecycle(withPropsOnChange(withHandlers(withHandlers(withHandlers(withHandlers(Connect(lifecycle(Menu))))))))))))))))))))))))

    will have the display name:


    To prevent polluting the console, and any other reason, you can change it using customName.


Optionally you can pass in options as a second parameter. The following options are available:

  • include: [RegExp, ...] (null by default)
  • exclude: [RegExp, ...] (null by default)
  • trackHooks: true
  • logOnDifferentValues: false
  • hotReloadBufferMs: 500
  • onlyLogs: false
  • collapseGroups: false
  • titleColor
  • diffNameColor
  • diffPathColor
  • notifier: ({Component, displayName, prevProps, prevState, nextProps, nextState, reason, options}) => void

include / exclude

You can include or exclude tracking for re-renders for components by their displayName with the include and exclude options.

Notice: exclude takes priority over both include and whyDidYouRender statics on components.

For example, the following code is used to track all redundant re-renders that are caused by React-Redux:

whyDidYouRender(React, { include: [/^ConnectFunction/] });


You can turn off tracking of hooks changes.

Understand and fix hook issues >> HERE <<.


Normally, you only want notifications about component re-renders when their props and state are the same, because it means these re-renders could of been avoided. But you can also track all re-renders, even on different state/props.

render(<BigListPureComponent a={1}/>)
render(<BigListPureComponent a={2}/>)
// this will only cause whyDidYouRender notifications for {logOnDifferentValues: true}


Time in milliseconds to ignore updates after a hot reload is detected.

We can't currently know exactly if a render was triggered by hot reload, so instead, we ignore all updates for hotReloadBufferMs (default: 500) after a hot reload.


If you don't want to use to group logs by component, you can print them as simple logs.


Grouped logs can start collapsed:

titleColor / diffNameColor / diffPathColor

Controls the colors used in the console notifications


You can create a custom notifier if the default one does not suite your needs.


Inspired by the following previous work: which i had the chance to maintain for some time. where A deep dive into React perf debugging is credited for the idea.


This library is MIT licensed.


npm i @welldone-software/why-did-you-render

Downloadsweekly downloads









last publish


  • avatar
  • avatar
Report a vulnerability