{"id":24141398,"url":"https://github.com/aidenybai/bippy","last_synced_at":"2026-02-09T20:59:44.046Z","repository":{"id":266395941,"uuid":"897892563","full_name":"aidenybai/bippy","owner":"aidenybai","description":"⚠️ hack into react internals","archived":false,"fork":false,"pushed_at":"2025-01-09T15:06:53.000Z","size":3682,"stargazers_count":295,"open_issues_count":4,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-01-09T15:41:42.826Z","etag":null,"topics":["bippy","fiber","internal","react","reconciler"],"latest_commit_sha":null,"homepage":"https://bippy.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aidenybai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-03T12:28:22.000Z","updated_at":"2025-01-09T15:40:24.000Z","dependencies_parsed_at":"2024-12-19T01:21:52.196Z","dependency_job_id":"1600f180-754e-42db-b8ab-b3f708afac75","html_url":"https://github.com/aidenybai/bippy","commit_stats":null,"previous_names":["aidenybai/bippy"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Fbippy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Fbippy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Fbippy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Fbippy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aidenybai","download_url":"https://codeload.github.com/aidenybai/bippy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233562839,"owners_count":18694719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bippy","fiber","internal","react","reconciler"],"created_at":"2025-01-12T04:02:36.069Z","updated_at":"2026-02-09T20:59:44.040Z","avatar_url":"https://github.com/aidenybai.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Projects"],"sub_categories":[],"readme":"\u003e [!WARNING]\n\u003e ⚠️⚠️⚠️ **this project may break production apps and cause unexpected behavior** ⚠️⚠️⚠️\n\u003e\n\u003e this project uses react internals, which can change at any time. it is not recommended to depend on internals unless you really, _really_ have to. by proceeding, you acknowledge the risk of breaking your own code or apps that use your code.\n\n# \u003cimg src=\"https://github.com/aidenybai/bippy/blob/main/.github/public/bippy.png?raw=true\" width=\"60\" align=\"center\" /\u003e bippy\n\n[![version](https://img.shields.io/npm/v/bippy?style=flat\u0026colorA=000000\u0026colorB=000000)](https://npmjs.com/package/bippy)\n[![downloads](https://img.shields.io/npm/dt/bippy.svg?style=flat\u0026colorA=000000\u0026colorB=000000)](https://npmjs.com/package/bippy)\n\nbippy is a toolkit to **hack into react internals**\n\nby default, you cannot access react internals. bippy bypasses this by \"pretending\" to be react devtools, giving you access to the fiber tree and other internals.\n\n- works outside of react – no react code modification needed\n- utility functions that work across modern react (v17-19)\n- no prior react source code knowledge required\n\n```jsx\nimport { onCommitFiberRoot, traverseFiber } from 'bippy'; // must be imported BEFORE react\n\ninstrument({\n  onCommitFiberRoot: (root) =\u003e {\n    traverseFiber(root.current, (fiber) =\u003e {\n      // prints every fiber in the current React tree\n      console.log('fiber:', fiber);\n    });\n  },\n});\n```\n\n## how it works \u0026 motivation\n\nbippy allows you to **access** and **use** react fibers **outside** of react components.\n\na react fiber is a \"unit of execution.\" this means react will do something based on the data in a fiber. each fiber either represents a composite (function/class component) or a host (dom element).\n\n\u003e here is a [live visualization](https://jser.pro/ddir/rie?reactVersion=18.3.1\u0026snippetKey=hq8jm2ylzb9u8eh468) of what the fiber tree looks like, and here is a [deep dive article](https://jser.dev/2023-07-18-how-react-rerenders/).\n\nfibers are useful because they contain information about the react app (component props, state, contexts, etc.). a simplified version of a fiber looks roughly like this:\n\n```typescript\ninterface Fiber {\n  // component type (function/class)\n  type: any;\n\n  child: Fiber | null;\n  sibling: Fiber | null;\n\n  // stateNode is the host fiber (e.g. DOM element)\n  stateNode: Node | null;\n\n  // parent fiber\n  return: Fiber | null;\n\n  // the previous or current version of the fiber\n  alternate: Fiber | null;\n\n  // saved props input\n  memoizedProps: any;\n\n  // state (useState, useReducer, useSES, etc.)\n  memoizedState: any;\n\n  // contexts (useContext)\n  dependencies: Dependencies | null;\n\n  // effects (useEffect, useLayoutEffect, etc.)\n  updateQueue: any;\n}\n```\n\nhere, the `child`, `sibling`, and `return` properties are pointers to other fibers in the tree.\n\nadditionally, `memoizedProps`, `memoizedState`, and `dependencies` are the fiber's props, state, and contexts.\n\nwhile all of the information is there, it's not super easy to work with, and changes frequently across different versions of react. bippy simplifies this by providing utility functions like:\n\n- `traverseRenderedFibers` to detect renders and `traverseFiber` to traverse the overall fiber tree\n  - _(instead of `child`, `sibling`, and `return` pointers)_\n- `traverseProps`, `traverseState`, and `traverseContexts` to traverse the fiber's props, state, and contexts\n  - _(instead of `memoizedProps`, `memoizedState`, and `dependencies`)_\n\nhowever, fibers aren't directly accessible by the user. so, we have to hack our way around to accessing it.\n\nluckily, react [reads from a property](https://github.com/facebook/react/blob/6a4b46cd70d2672bc4be59dcb5b8dede22ed0cef/packages/react-reconciler/src/ReactFiberDevToolsHook.js#L48) in the window object: `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` and runs handlers on it when certain events happen. this property must exist before react's bundle is executed. this is intended for react devtools, but we can use it to our advantage.\n\nhere's what it roughly looks like:\n\n```typescript\ninterface __REACT_DEVTOOLS_GLOBAL_HOOK__ {\n  // list of renderers (react-dom, react-native, etc.)\n  renderers: Map\u003cRendererID, reactRenderer\u003e;\n\n  // called when react has rendered everything for an update and the fiber tree is fully built and ready to\n  // apply changes to the host tree (e.g. DOM mutations)\n  onCommitFiberRoot: (\n    rendererID: RendererID,\n    root: FiberRoot,\n    commitPriority?: number,\n  ) =\u003e void;\n\n  // called when effects run\n  onPostCommitFiberRoot: (rendererID: RendererID, root: FiberRoot) =\u003e void;\n\n  // called when a specific fiber unmounts\n  onCommitFiberUnmount: (rendererID: RendererID, fiber: Fiber) =\u003e void;\n}\n```\n\nbippy works by monkey-patching `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` with our own custom handlers. bippy simplifies this by providing utility functions like:\n\n- `instrument` to safely patch `window.__REACT_DEVTOOLS_GLOBAL_HOOK__`\n  - _(instead of directly mutating `onCommitFiberRoot`, ...)_\n- `secure` to wrap your handlers in a try/catch and determine if handlers are safe to run\n  - _(instead of rawdogging `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` handlers, which may crash your app)_\n- `traverseRenderedFibers` to traverse the fiber tree and determine which fibers have actually rendered\n  - _(instead of `child`, `sibling`, and `return` pointers)_\n- `traverseFiber` to traverse the fiber tree, regardless of whether it has rendered\n  - _(instead of `child`, `sibling`, and `return` pointers)_\n- `setFiberId` / `getFiberId` to set and get a fiber's id\n  - _(instead of anonymous fibers with no identity)_\n\n## how to use\n\nwe recommend installing via npm.\n\nthis package should be imported before a React app runs. this will add a special object to the global which is used by React for providing its internals to the tool for analysis (React Devtools does the same). as soon as React library is loaded and attached to the tool, bippy starts collecting data about what is going on in React's internals.\n\n```shell\nnpm install bippy\n```\n\nsince bippy needs to be imported before react, some bundlers require specific configuration to ensure the correct import order.\n\n### next.js\n\nin next.js 15.3+, use the [`instrumentation-client.js`](https://nextjs.org/docs/app/api-reference/file-conventions/instrumentation-client) file to ensure bippy loads before react. create this file at the root of your application (or inside the `src` folder if you're using the src directory structure):\n\n```typescript\n// instrumentation-client.ts\nimport 'bippy';\n```\n\nthis file executes before react hydration, making it the ideal place to initialize bippy.\n\n### vite\n\nin vite, import bippy at the very top of your main entry point (typically `src/main.tsx` or `src/main.ts`) before any react imports:\n\n```typescript\n// src/main.tsx\nimport 'bippy';\nimport { StrictMode } from 'react';\nimport { createRoot } from 'react-dom/client';\n\n// ... rest of your code\n```\n\nthe import order is critical: bippy must be imported before any react packages.\n\n\u003e **note for library maintainers**: if you're building a library and want to define your own utility functions while minimizing bundle size, you can use `bippy/install-hook-only` (~90 bytes) instead of the main `bippy` export. this only installs the react devtools hook without importing any utility functions, allowing you to import only what you need from `bippy/core` or define your own fiber utilities. that said, the full `bippy` package is only ~4kb gzipped, so bundle size is rarely a concern.\n\n\u003e ```typescript\n\u003e import 'bippy/install-hook-only'; // only installs the hook\n\u003e import { getRDTHook, traverseFiber } from 'bippy/core'; // import only what you need\n\u003e import * as React from 'react'; // import react AFTER the hook is installed\n\u003e\n\u003e const hook = getRDTHook();\n\u003e // define your own utilities or use only specific ones\n\u003e ```\n\n## API reference\n\n### instrument\n\npatches `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` with your handlers. must be imported before react, and must be initialized to properly run any other methods.\n\n\u003e use with the `secure` function to prevent uncaught errors from crashing your app.\n\n```typescript\nimport { instrument, secure } from 'bippy'; // must be imported BEFORE react\nimport * as React from 'react';\n\ninstrument(\n  secure({\n    onCommitFiberRoot(rendererID, root) {\n      console.log('root ready to commit', root);\n    },\n    onPostCommitFiberRoot(rendererID, root) {\n      console.log('root with effects committed', root);\n    },\n    onCommitFiberUnmount(rendererID, fiber) {\n      console.log('fiber unmounted', fiber);\n    },\n  }),\n);\n```\n\n### getRDTHook\n\nreturns the `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` object. great for advanced use cases, such as accessing or modifying the `renderers` property.\n\n```typescript\nimport { getRDTHook } from 'bippy';\n\nconst hook = getRDTHook();\nconsole.log(hook);\n```\n\n### traverseRenderedFibers\n\nnot every fiber in the fiber tree renders. `traverseRenderedFibers` allows you to traverse the fiber tree and determine which fibers have actually rendered.\n\n```typescript\nimport { instrument, secure, traverseRenderedFibers } from 'bippy'; // must be imported BEFORE react\nimport * as React from 'react';\n\ninstrument(\n  secure({\n    onCommitFiberRoot(rendererID, root) {\n      traverseRenderedFibers(root, (fiber) =\u003e {\n        console.log('fiber rendered', fiber);\n      });\n    },\n  }),\n);\n```\n\n### traverseFiber\n\ncalls a callback on every fiber in the fiber tree.\n\n```typescript\nimport { instrument, secure, traverseFiber } from 'bippy'; // must be imported BEFORE react\nimport * as React from 'react';\n\ninstrument(\n  secure({\n    onCommitFiberRoot(rendererID, root) {\n      traverseFiber(root.current, (fiber) =\u003e {\n        console.log(fiber);\n      });\n    },\n  }),\n);\n```\n\n### traverseProps\n\ntraverses the props of a fiber.\n\n```typescript\nimport { traverseProps } from 'bippy';\n\n// ...\n\ntraverseProps(fiber, (propName, next, prev) =\u003e {\n  console.log(propName, next, prev);\n});\n```\n\n### traverseState\n\ntraverses the state (`useState`, `useReducer`, etc.) and effects that set state of a fiber.\n\n```typescript\nimport { traverseState } from 'bippy';\n\n// ...\n\ntraverseState(fiber, (next, prev) =\u003e {\n  console.log(next, prev);\n});\n```\n\n### traverseContexts\n\ntraverses the contexts (`useContext`) of a fiber.\n\n```typescript\nimport { traverseContexts } from 'bippy';\n\n// ...\n\ntraverseContexts(fiber, (next, prev) =\u003e {\n  console.log(next, prev);\n});\n```\n\n### setFiberId / getFiberId\n\nset and get a persistent identity for a fiber. by default, fibers are anonymous and have no identity.\n\n```typescript\nimport { setFiberId, getFiberId } from 'bippy';\n\n// ...\n\nsetFiberId(fiber);\nconsole.log('unique id for fiber:', getFiberId(fiber));\n```\n\n### isHostFiber\n\nreturns `true` if the fiber is a host fiber (e.g., a DOM node in react-dom).\n\n```typescript\nimport { isHostFiber } from 'bippy';\n\nif (isHostFiber(fiber)) {\n  console.log('fiber is a host fiber');\n}\n```\n\n### isCompositeFiber\n\nreturns `true` if the fiber is a composite fiber. composite fibers represent class components, function components, memoized components, and so on (anything that can actually render output).\n\n```typescript\nimport { isCompositeFiber } from 'bippy';\n\nif (isCompositeFiber(fiber)) {\n  console.log('fiber is a composite fiber');\n}\n```\n\n### getDisplayName\n\nreturns the display name of the fiber's component, falling back to the component's function or class name if available.\n\n```typescript\nimport { getDisplayName } from 'bippy';\n\nconsole.log(getDisplayName(fiber));\n```\n\n### getType\n\nreturns the underlying type (the component definition) for a given fiber. for example, this could be a function component or class component.\n\n```jsx\nimport { getType } from 'bippy';\nimport { memo } from 'react';\n\nconst RealComponent = () =\u003e {\n  return \u003cdiv\u003ehello\u003c/div\u003e;\n};\nconst MemoizedComponent = memo(() =\u003e {\n  return \u003cdiv\u003ehello\u003c/div\u003e;\n});\n\nconsole.log(getType(fiberForMemoizedComponent) === RealComponent);\n```\n\n### getNearestHostFiber / getNearestHostFibers\n\ngetNearestHostFiber returns the closest host fiber above or below a given fiber. getNearestHostFibers(fiber) returns all host fibers associated with the provided fiber and its subtree.\n\n```jsx\nimport { getNearestHostFiber, getNearestHostFibers } from 'bippy';\n\n// ...\n\nfunction Component() {\n  return (\n    \u003c\u003e\n      \u003cdiv\u003ehello\u003c/div\u003e\n      \u003cdiv\u003eworld\u003c/div\u003e\n    \u003c/\u003e\n  );\n}\n\nconsole.log(getNearestHostFiber(fiberForComponent)); // \u003cdiv\u003ehello\u003c/div\u003e\nconsole.log(getNearestHostFibers(fiberForComponent)); // [\u003cdiv\u003ehello\u003c/div\u003e, \u003cdiv\u003eworld\u003c/div\u003e]\n```\n\n### getTimings\n\nreturns the self and total render times for the fiber.\n\n```typescript\n// timings don't exist in react production builds\nif (fiber.actualDuration !== undefined) {\n  const { selfTime, totalTime } = getTimings(fiber);\n  console.log(selfTime, totalTime);\n}\n```\n\n### getFiberStack\n\nreturns an array representing the stack of fibers from the current fiber up to the root.\n\n```typescript\n[fiber, fiber.return, fiber.return.return, ...]\n```\n\n### getMutatedHostFibers\n\nreturns an array of all host fibers that have committed and rendered in the provided fiber's subtree.\n\n```typescript\nimport { getMutatedHostFibers } from 'bippy';\n\nconsole.log(getMutatedHostFibers(fiber));\n```\n\n### isValidFiber\n\nreturns `true` if the given object is a valid React Fiber (i.e., has a tag, stateNode, return, child, sibling, etc.).\n\n```typescript\nimport { isValidFiber } from 'bippy';\n\nconsole.log(isValidFiber(fiber));\n```\n\n### getFiberFromHostInstance\n\nreturns the fiber associated with a given host instance (e.g., a DOM element).\n\n```typescript\nimport { getFiberFromHostInstance } from 'bippy';\n\nconst fiber = getFiberFromHostInstance(document.querySelector('div'));\nconsole.log(fiber);\n```\n\n### getLatestFiber\n\nreturns the latest fiber (since it may be double-buffered). usually use this in combination with `getFiberFromHostInstance`.\n\n```typescript\nimport { getLatestFiber } from 'bippy';\n\nconst latestFiber = getLatestFiber(\n  getFiberFromHostInstance(document.querySelector('div')),\n);\nconsole.log(latestFiber);\n```\n\n### getFiberSource\n\nreturns the source code location of a fiber.\n\n```typescript\nimport { getFiberSource } from 'bippy/source';\n\nconst fiber = getFiberFromHostInstance(document.querySelector('div'));\n\nconsole.log(await getFiberSource(fiber));\n```\n\n\u003e note: in order to get accurate source locations in react \u003e= 19, you need to add this in your `tsconfig.json`:\n\u003e\n\u003e ```json\n\u003e {\n\u003e   \"compilerOptions\": {\n\u003e     \"jsxImportSource\": \"bippy/dist\"\n\u003e   }\n\u003e }\n\u003e ```\n\n### overrideProps\n\noverrides component props at runtime by modifying the fiber's props.\n\n```typescript\nimport { overrideProps } from 'bippy';\n\n// override props on a fiber\noverrideProps(fiber, {\n  title: 'new title',\n  config: {\n    enabled: true,\n    count: 42,\n  },\n});\n```\n\nthe function accepts a fiber and a partial object containing the props to override. nested objects are automatically flattened into property paths.\n\n### overrideHookState\n\noverrides hook state (`useState`, `useReducer`, etc.) at runtime by hook id.\n\n```typescript\nimport { overrideHookState } from 'bippy';\n\n// override the first hook (id: 0) with a new value\noverrideHookState(fiber, 0, 'new state value');\n\n// override nested state object\noverrideHookState(fiber, 1, {\n  user: {\n    name: 'john',\n    age: 30,\n  },\n});\n```\n\nthe hook id parameter corresponds to the order of hooks in the component (0-indexed). the function can accept either a primitive value or an object for nested state updates.\n\n### overrideContext\n\noverrides react context values at runtime by finding the appropriate context provider.\n\n```typescript\nimport { overrideContext } from 'bippy';\n\n// override context value\noverrideContext(fiber, MyContext, {\n  theme: 'dark',\n  user: {\n    id: 123,\n    name: 'jane',\n  },\n});\n\n// override with primitive value\noverrideContext(fiber, ThemeContext, 'dark');\n```\n\nthe function traverses up the fiber tree to find the context provider matching the provided context type and overrides its value.\n\n### getSource\n\ngets the source code location of a composite fiber.\n\n```typescript\nimport { getSource } from 'bippy/source';\n\n// random fiber on the DOM\nconst hostFiber = getFiberFromHostInstance(document.querySelector('div'));\n\n// get nearest composite fiber up the tree\nconst compositeFiber = traverseFiber(\n  hostFiber,\n  (fiber) =\u003e {\n    if (isCompositeFiber(fiber)) {\n      return fiber;\n    }\n  },\n  true,\n);\n\nconst source = await getSource(compositeFiber);\n// {\n//   columnNumber: 12,\n//   fileName: 'path/to/file.tsx',\n//   lineNumber: 12,\n// }\n```\n\n\u003e **caveats:**\n\u003e\n\u003e - only available in dev mode\n\u003e - only works for composite fibers (function/class components)\n\u003e - captures the location where the component is _used_, not where it's _defined_\n\u003e - in react 18, resolves `_debugSource` directly (see [react#31981](https://github.com/facebook/react/issues/31981))\n\u003e - in react \u003e18, `_debugSource` is not available for host fibers\n\n## example\n\nhere's a mini toy version of [`react-scan`](https://github.com/aidenybai/react-scan) that highlights renders in your app.\n\n```javascript\nimport {\n  instrument,\n  secure,\n  getNearestHostFiber,\n  traverseRenderedFibers,\n} from 'bippy'; // must be imported BEFORE react\n\nconst highlightFiber = (fiber) =\u003e {\n  if (!(fiber.stateNode instanceof HTMLElement)) return;\n  // fiber.stateNode is a DOM element\n  const rect = fiber.stateNode.getBoundingClientRect();\n  const highlight = document.createElement('div');\n  highlight.style.border = '1px solid red';\n  highlight.style.position = 'fixed';\n  highlight.style.top = `${rect.top}px`;\n  highlight.style.left = `${rect.left}px`;\n  highlight.style.width = `${rect.width}px`;\n  highlight.style.height = `${rect.height}px`;\n  highlight.style.zIndex = '999999999';\n  document.documentElement.appendChild(highlight);\n  setTimeout(() =\u003e {\n    document.documentElement.removeChild(highlight);\n  }, 100);\n};\n\n/**\n * `instrument` is a function that installs the react DevTools global\n * hook and allows you to set up custom handlers for react fiber events.\n */\ninstrument(\n  /**\n   * `secure` is a function that wraps your handlers in a try/catch\n   * and prevents it from crashing the app. it also prevents it from\n   * running on unsupported react versions and during production.\n   *\n   * this is not required but highly recommended to provide \"safeguards\"\n   * in case something breaks.\n   */\n  secure({\n    /**\n     * `onCommitFiberRoot` is a handler that is called when react is\n     * ready to commit a fiber root. this means that react is has\n     * rendered your entire app and is ready to apply changes to\n     * the host tree (e.g. via DOM mutations).\n     */\n    onCommitFiberRoot(rendererID, root) {\n      /**\n       * `traverseRenderedFibers` traverses the fiber tree and determines which\n       * fibers have actually rendered.\n       *\n       * A fiber tree contains many fibers that may have not rendered. this\n       * can be because it bailed out (e.g. `useMemo`) or because it wasn't\n       * actually rendered (if \u003cChild\u003e re-rendered, then \u003cParent\u003e didn't\n       * actually render, but exists in the fiber tree).\n       */\n      traverseRenderedFibers(root, (fiber) =\u003e {\n        /**\n         * `getNearestHostFiber` is a utility function that finds the\n         * nearest host fiber to a given fiber.\n         *\n         * a host fiber for `react-dom` is a fiber that has a DOM element\n         * as its `stateNode`.\n         */\n        const hostFiber = getNearestHostFiber(fiber);\n        highlightFiber(hostFiber);\n      });\n    },\n  }),\n);\n```\n\n## glossary\n\n- fiber: a \"unit of execution\" in react, representing a component or dom element\n- commit: the process of applying changes to the host tree (e.g. DOM mutations)\n- render: the process of building the fiber tree by executing component function/classes\n- host tree: the tree of UI elements that react mutates (e.g. DOM elements)\n- reconciler (or \"renderer\"): custom bindings for react, e.g. react-dom, react-native, react-three-fiber, etc to mutate the host tree\n- `rendererID`: the id of the reconciler, starting at 1 (can be from multiple reconciler instances)\n- `root`: a special `FiberRoot` type that contains the container fiber (the one you pass to `ReactDOM.createRoot`) in the `current` property\n- `onCommitFiberRoot`: called when react is ready to commit a fiber root\n- `onPostCommitFiberRoot`: called when react has committed a fiber root and effects have run\n- `onCommitFiberUnmount`: called when a fiber unmounts\n\n## misc\n\nbippy was initially created for [react-scan](https://github.com/aidenybai/react-scan), which is deployed with proper safeguards to ensure it's only used in development or error-guarded in production.\n\nif you're seeking more robust solutions, you might consider [its-fine](https://github.com/pmndrs/its-fine) for accessing fibers within react using hooks, or [react-devtools-inline](https://www.npmjs.com/package/react-devtools-inline) for a headful interface.\n\nif you plan to use this project beyond experimentation, please review [react-scan's source code](https://github.com/aidenybai/react-scan) to understand our safeguarding practices.\n\nthe original bippy character is owned and created by [@dairyfreerice](https://www.instagram.com/dairyfreerice). this project is not related to the bippy brand, i just think the character is cute.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidenybai%2Fbippy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faidenybai%2Fbippy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidenybai%2Fbippy/lists"}