CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-welldone-software--why-did-you-render

Monkey patches React to notify about avoidable re-renders by tracking pure components and hooks.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Why Did You Render

Why Did You Render is a React development tool that monkey patches React to detect and notify developers about potentially avoidable component re-renders. It tracks pure components (React.PureComponent and React.memo) and custom hooks, analyzing prop and state changes to identify when components re-render with identical values. Works with both React web applications and React Native.

Package Information

  • Package Name: @welldone-software/why-did-you-render
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install @welldone-software/why-did-you-render --save-dev

Core Imports

import whyDidYouRender from '@welldone-software/why-did-you-render';

For CommonJS:

const whyDidYouRender = require('@welldone-software/why-did-you-render');

JSX Runtime (for React 19 automatic JSX transformation):

// These are handled automatically when configured as importSource
import '@welldone-software/why-did-you-render/jsx-runtime';
import '@welldone-software/why-did-you-render/jsx-dev-runtime';

Basic Usage

import React from 'react';
import whyDidYouRender from '@welldone-software/why-did-you-render';

// Initialize the library (typically in your app's entry point)
if (process.env.NODE_ENV === 'development') {
  whyDidYouRender(React, {
    trackAllPureComponents: true,
    trackHooks: true,
    logOwnerReasons: true
  });
}

// Your existing React components will now be tracked
const MyComponent = React.memo(({ name, age }) => {
  return <div>{name} is {age} years old</div>;
});

// The component will be automatically tracked for re-renders
export default MyComponent;

React Native Usage:

import React from 'react';
import whyDidYouRender from '@welldone-software/why-did-you-render';

// For React Native, use __DEV__ instead of process.env.NODE_ENV
if (__DEV__) {
  whyDidYouRender(React, {
    trackAllPureComponents: true,
    trackHooks: true,
    logOwnerReasons: true
  });
}

JSX Runtime Integration

For React 19 with automatic JSX transformation, configure Babel to use the library's JSX runtime:

// babel.config.js
['@babel/preset-react', {
  runtime: 'automatic',
  development: process.env.NODE_ENV === 'development',
  importSource: '@welldone-software/why-did-you-render',
}]

Architecture

Why Did You Render is built around several key components:

  • Main Function: The whyDidYouRender function that patches React to enable tracking
  • Component Patching: Automatic wrapping of components to monitor re-renders
  • Hook Tracking: Optional monitoring of React hooks for state changes
  • Notification System: Configurable output system for re-render notifications
  • JSX Runtime: Enhanced JSX transformation for seamless integration

Capabilities

Core Library Setup

Main function to initialize Why Did You Render with React and configure tracking options.

function whyDidYouRender(
  React: typeof React, 
  options?: WhyDidYouRenderOptions
): typeof React;

Core Setup and Configuration

Component Tracking

Built-in component tracking and notification system with detailed re-render analysis.

interface UpdateInfo {
  Component: React.Component;
  displayName: string;
  prevProps: any;
  prevState: any;
  nextProps: any;
  nextState: any;
  prevHookResult: any;
  nextHookResult: any;
  reason: ReasonForUpdate;
  options: WhyDidYouRenderOptions;
  hookName?: string;
}

type Notifier = (updateInfo: UpdateInfo) => void;

Component Tracking and Notifications

Hook Integration

Advanced hook tracking for monitoring React hooks like useState, useReducer, and custom hooks.

interface HookDifference {
  pathString: string;
  diffType: string;
  prevValue: any;
  nextValue: any;
}

type ExtraHookToTrack = [any, string];

Hook Tracking

JSX Runtime Integration

Enhanced JSX transformation for React 19 automatic JSX runtime with seamless WDYR integration.

/**
 * Enhanced jsxDEV function that wraps React's jsx-dev-runtime
 * Automatically applies WDYR tracking to components during JSX transformation
 */
declare const jsxDEV: typeof import('react/jsx-dev-runtime').jsxDEV;

Type Definitions

interface WhyDidYouRenderOptions {
  include?: RegExp[];
  exclude?: RegExp[];
  trackAllPureComponents?: boolean;
  trackHooks?: boolean;
  logOwnerReasons?: boolean;
  trackExtraHooks?: Array<ExtraHookToTrack>;
  logOnDifferentValues?: boolean;
  hotReloadBufferMs?: number;
  onlyLogs?: boolean;
  collapseGroups?: boolean;
  titleColor?: string;
  diffNameColor?: string;
  diffPathColor?: string;
  textBackgroundColor?: string;
  notifier?: Notifier;
  getAdditionalOwnerData?: (element: React.Element) => any;
}

interface ReasonForUpdate {
  hookDifferences: HookDifference[];
  propsDifferences: boolean;
  stateDifferences: boolean;
  ownerDifferences?: {
    propsDifferences?: HookDifference[];
    stateDifferences?: HookDifference[];
    hookDifferences?: Array<{
      hookName: string;
      differences: HookDifference[];
    }>;
  };
}

type WhyDidYouRenderComponentMember = WhyDidYouRenderOptions | boolean;

interface WdyrStore {
  React: typeof React;
  options: WhyDidYouRenderOptions;
  origCreateElement: typeof React.createElement;
  origCreateFactory: typeof React.createFactory;
  origCloneElement: typeof React.cloneElement;
  componentsMap: WeakMap<any, any>;
  ownerDataMap: WeakMap<any, any>;
  hooksInfoForCurrentRender: WeakMap<any, any>;
  ownerBeforeElementCreation: any;
}

React Module Augmentation:

The library extends React component interfaces to support the whyDidYouRender property:

declare module 'react' {
  interface FunctionComponent<P = {}> {
    whyDidYouRender?: WhyDidYouRenderComponentMember;
  }

  interface VoidFunctionComponent<P = {}> {
    whyDidYouRender?: WhyDidYouRenderComponentMember;
  }

  interface ExoticComponent<P = {}> {
    whyDidYouRender?: WhyDidYouRenderComponentMember;
  }

  namespace Component {
    const whyDidYouRender: WhyDidYouRenderComponentMember;
  }
}

docs

component-tracking.md

core-setup.md

hook-tracking.md

index.md

tile.json