Bippy: React Internals Hacking Toolkit
Bippy is a specialized JavaScript library designed to provide direct access to React's internal Fiber tree and other non-public APIs, primarily for advanced instrumentation, debugging, and experimental tooling. It operates by emulating React DevTools' hook (`window.__REACT_DEVTOOLS_GLOBAL_HOOK__`) before React itself initializes, thus bypassing standard access restrictions. The current stable version is 0.5.39. While there isn't a fixed release cadence, updates typically occur reactively to maintain compatibility with new React major or minor versions (currently supporting v17-19) as internal structures change. Its key differentiator is providing simplified utility functions to traverse the Fiber tree and extract properties like `memoizedProps`, `memoizedState`, and `dependencies` across different React versions, reducing the need for deep React source code knowledge. It's explicitly not recommended for production applications due to its reliance on unstable internal APIs.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'current')
cause Bippy's internal hooks were not successfully established because the `instrument` function was called after React had already initialized.fixMove `import { instrument } from 'bippy'; instrument({...});` to the very top of your application's main entry file, ensuring it executes before any React-related imports or rendering calls. -
Error: Could not find __REACT_DEVTOOLS_GLOBAL_HOOK__ on window.
cause Bippy failed to find the expected React DevTools global hook object on `window` before React initialized, or another library clobbered it.fixVerify that Bippy is the absolute first script to run. If other development tools or libraries that also interact with React internals are present, they might be conflicting. Try isolating Bippy's usage or investigating load order.
Warnings
- breaking Bippy relies heavily on undocumented and unstable React internal APIs (e.g., Fiber tree structure, global hooks). These internals can change without warning in any React version, potentially breaking your application or causing unexpected behavior, including runtime errors or memory leaks.
- gotcha Bippy's `instrument` function MUST be called BEFORE React is imported or initialized (e.g., `ReactDOM.createRoot().render()`) in your application. Failure to do so will result in Bippy being unable to hook into React's internals, leading to silent failures or errors.
- gotcha The exact structure of React's Fiber nodes (`memoizedProps`, `memoizedState`, `dependencies`, `type`, etc.) can vary subtly between major React versions (v17, v18, v19). While Bippy provides some abstractions, direct Fiber inspection may require version-specific handling.
Install
-
npm install bippy -
yarn add bippy -
pnpm add bippy
Imports
- instrument
const { instrument } = require('bippy')import { instrument } from 'bippy' - onCommitFiberRoot
import onCommitFiberRoot from 'bippy'
import { onCommitFiberRoot } from 'bippy' - traverseFiber
const { traverseFiber } = require('bippy')import { traverseFiber } from 'bippy'
Quickstart
import { instrument, onCommitFiberRoot, traverseFiber } from 'bippy'; // Must be imported BEFORE React
// This block MUST execute before any React import or ReactDOM.createRoot call.
// For a typical SPA, place this at the very top of your main entry file (e.g., index.ts/js).
instrument({
onCommitFiberRoot: (root) => {
console.log('React commit detected for root:', root.current); // root.current is the actual Fiber root
traverseFiber(root.current, (fiber) => {
// This callback runs for every fiber in the current React tree upon commit.
// 'fiber' contains properties like type, memoizedProps, memoizedState, etc.
if (fiber.elementType && typeof fiber.elementType === 'function') {
// Log component names (functional or class components)
console.log(`Component Fiber: ${fiber.elementType.displayName || fiber.elementType.name || 'AnonymousComponent'}`);
} else if (fiber.stateNode instanceof HTMLElement) {
// Log host (DOM) element tags
console.log(`Host Fiber (DOM): <${fiber.stateNode.tagName.toLowerCase()} />`);
} else if (fiber.type) {
// Log other types of fibers (e.g., HostText, Suspense, Provider)
console.log(`Other Fiber Type: ${typeof fiber.type === 'symbol' ? fiber.type.toString() : fiber.type}`);
}
});
},
// Additional hooks can be configured here, e.g., onMount, onUnmount
// onMount: (fiber) => console.log('Fiber Mounted:', fiber),
// onUnmount: (fiber) => console.log('Fiber Unmounted:', fiber),
});
console.log('Bippy instrumentation activated successfully. Your React app will now be monitored.');
// Your React application's entry point would typically follow here,
// e.g., import ReactDOM from 'react-dom/client'; ReactDOM.createRoot(...).render(...);