or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

component-tracking.mdcore-setup.mdhook-tracking.mdindex.md
tile.json

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

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@welldone-software/why-did-you-render@10.0.x

To install, run

npx @tessl/cli install tessl/npm-welldone-software--why-did-you-render@10.0.0

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;

JSX Runtime Integration

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;
  }
}