or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

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

0

# Why Did You Render

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: @welldone-software/why-did-you-render

7

- **Package Type**: npm

8

- **Language**: JavaScript/TypeScript

9

- **Installation**: `npm install @welldone-software/why-did-you-render --save-dev`

10

11

## Core Imports

12

13

```javascript

14

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

15

```

16

17

For CommonJS:

18

19

```javascript

20

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

21

```

22

23

JSX Runtime (for React 19 automatic JSX transformation):

24

25

```javascript

26

// These are handled automatically when configured as importSource

27

import '@welldone-software/why-did-you-render/jsx-runtime';

28

import '@welldone-software/why-did-you-render/jsx-dev-runtime';

29

```

30

31

## Basic Usage

32

33

```javascript

34

import React from 'react';

35

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

36

37

// Initialize the library (typically in your app's entry point)

38

if (process.env.NODE_ENV === 'development') {

39

whyDidYouRender(React, {

40

trackAllPureComponents: true,

41

trackHooks: true,

42

logOwnerReasons: true

43

});

44

}

45

46

// Your existing React components will now be tracked

47

const MyComponent = React.memo(({ name, age }) => {

48

return <div>{name} is {age} years old</div>;

49

});

50

51

// The component will be automatically tracked for re-renders

52

export default MyComponent;

53

```

54

55

**React Native Usage:**

56

57

```javascript

58

import React from 'react';

59

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

60

61

// For React Native, use __DEV__ instead of process.env.NODE_ENV

62

if (__DEV__) {

63

whyDidYouRender(React, {

64

trackAllPureComponents: true,

65

trackHooks: true,

66

logOwnerReasons: true

67

});

68

}

69

```

70

71

## JSX Runtime Integration

72

73

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

74

75

```javascript

76

// babel.config.js

77

['@babel/preset-react', {

78

runtime: 'automatic',

79

development: process.env.NODE_ENV === 'development',

80

importSource: '@welldone-software/why-did-you-render',

81

}]

82

```

83

84

## Architecture

85

86

Why Did You Render is built around several key components:

87

88

- **Main Function**: The `whyDidYouRender` function that patches React to enable tracking

89

- **Component Patching**: Automatic wrapping of components to monitor re-renders

90

- **Hook Tracking**: Optional monitoring of React hooks for state changes

91

- **Notification System**: Configurable output system for re-render notifications

92

- **JSX Runtime**: Enhanced JSX transformation for seamless integration

93

94

## Capabilities

95

96

### Core Library Setup

97

98

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

99

100

```typescript { .api }

101

function whyDidYouRender(

102

React: typeof React,

103

options?: WhyDidYouRenderOptions

104

): typeof React;

105

```

106

107

[Core Setup and Configuration](./core-setup.md)

108

109

### Component Tracking

110

111

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

112

113

```typescript { .api }

114

interface UpdateInfo {

115

Component: React.Component;

116

displayName: string;

117

prevProps: any;

118

prevState: any;

119

nextProps: any;

120

nextState: any;

121

prevHookResult: any;

122

nextHookResult: any;

123

reason: ReasonForUpdate;

124

options: WhyDidYouRenderOptions;

125

hookName?: string;

126

}

127

128

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

129

```

130

131

[Component Tracking and Notifications](./component-tracking.md)

132

133

### Hook Integration

134

135

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

136

137

```typescript { .api }

138

interface HookDifference {

139

pathString: string;

140

diffType: string;

141

prevValue: any;

142

nextValue: any;

143

}

144

145

type ExtraHookToTrack = [any, string];

146

```

147

148

[Hook Tracking](./hook-tracking.md)

149

150

### JSX Runtime Integration

151

152

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

153

154

```typescript { .api }

155

/**

156

* Enhanced jsxDEV function that wraps React's jsx-dev-runtime

157

* Automatically applies WDYR tracking to components during JSX transformation

158

*/

159

declare const jsxDEV: typeof import('react/jsx-dev-runtime').jsxDEV;

160

```

161

162

[JSX Runtime Integration](./jsx-runtime.md)

163

164

## Type Definitions

165

166

```typescript { .api }

167

interface WhyDidYouRenderOptions {

168

include?: RegExp[];

169

exclude?: RegExp[];

170

trackAllPureComponents?: boolean;

171

trackHooks?: boolean;

172

logOwnerReasons?: boolean;

173

trackExtraHooks?: Array<ExtraHookToTrack>;

174

logOnDifferentValues?: boolean;

175

hotReloadBufferMs?: number;

176

onlyLogs?: boolean;

177

collapseGroups?: boolean;

178

titleColor?: string;

179

diffNameColor?: string;

180

diffPathColor?: string;

181

textBackgroundColor?: string;

182

notifier?: Notifier;

183

getAdditionalOwnerData?: (element: React.Element) => any;

184

}

185

186

interface ReasonForUpdate {

187

hookDifferences: HookDifference[];

188

propsDifferences: boolean;

189

stateDifferences: boolean;

190

ownerDifferences?: {

191

propsDifferences?: HookDifference[];

192

stateDifferences?: HookDifference[];

193

hookDifferences?: Array<{

194

hookName: string;

195

differences: HookDifference[];

196

}>;

197

};

198

}

199

200

type WhyDidYouRenderComponentMember = WhyDidYouRenderOptions | boolean;

201

202

interface WdyrStore {

203

React: typeof React;

204

options: WhyDidYouRenderOptions;

205

origCreateElement: typeof React.createElement;

206

origCreateFactory: typeof React.createFactory;

207

origCloneElement: typeof React.cloneElement;

208

componentsMap: WeakMap<any, any>;

209

ownerDataMap: WeakMap<any, any>;

210

hooksInfoForCurrentRender: WeakMap<any, any>;

211

ownerBeforeElementCreation: any;

212

}

213

```

214

215

**React Module Augmentation:**

216

217

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

218

219

```typescript { .api }

220

declare module 'react' {

221

interface FunctionComponent<P = {}> {

222

whyDidYouRender?: WhyDidYouRenderComponentMember;

223

}

224

225

interface VoidFunctionComponent<P = {}> {

226

whyDidYouRender?: WhyDidYouRenderComponentMember;

227

}

228

229

interface ExoticComponent<P = {}> {

230

whyDidYouRender?: WhyDidYouRenderComponentMember;

231

}

232

233

namespace Component {

234

const whyDidYouRender: WhyDidYouRenderComponentMember;

235

}

236

}

237

```