| 1 | # `react-devtools-core` |
| 2 | |
| 3 | This package provides low-level APIs to support renderers like [React Native](https://github.com/facebook/react-native). If you're looking for the standalone React DevTools UI, **we suggest using [`react-devtools`](https://github.com/facebook/react/tree/main/packages/react-devtools) instead of using this package directly**. |
| 4 | |
| 5 | This package provides two entrypoints: labeled "backend" and "standalone" (frontend). Both APIs are described below. |
| 6 | |
| 7 | # Backend API |
| 8 | |
| 9 | Backend APIs are embedded in _development_ builds of renderers like [React Native](https://github.com/facebook/react-native) in order to connect to the React DevTools UI. |
| 10 | |
| 11 | ### Example |
| 12 | |
| 13 | If you are building a non-browser-based React renderer, you can use the backend API like so: |
| 14 | |
| 15 | ```js |
| 16 | if (process.env.NODE_ENV !== 'production') { |
| 17 | const { initialize, connectToDevTools } = require("react-devtools-core"); |
| 18 | |
| 19 | initialize(settings); |
| 20 | // Must be called before packages like react or react-native are imported |
| 21 | connectToDevTools({...config}); |
| 22 | } |
| 23 | ``` |
| 24 | |
| 25 | > **NOTE** that this API (`connectToDevTools`) must be (1) run in the same context as React and (2) must be called before React packages are imported (e.g. `react`, `react-dom`, `react-native`). |
| 26 | |
| 27 | ### `initialize` arguments |
| 28 | | Argument | Description | |
| 29 | |---------------------------|-------------| |
| 30 | | `settings` | Optional. If not specified, or received as null, then default settings are used. Can be plain object or a Promise that resolves with the [plain settings object](#Settings). If Promise rejects, the console will not be patched and some console features from React DevTools will not work. | |
| 31 | | `shouldStartProfilingNow` | Optional. Whether to start profiling immediately after installing the hook. Defaults to `false`. | |
| 32 | | `profilingSettings` | Optional. Profiling settings used when `shouldStartProfilingNow` is `true`. Defaults to `{ recordChangeDescriptions: false }`. | |
| 33 | | `componentFilters` | Optional. Array or Promise that resolves to an array of component filters to apply before DevTools connects. Defaults to the built-in host component filter. See [Component filters](#component-filters) for the full spec. | |
| 34 | |
| 35 | #### `Settings` |
| 36 | | Spec | Default value | |
| 37 | |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| 38 | | <pre>{<br> appendComponentStack: boolean,<br> breakOnConsoleErrors: boolean,<br> showInlineWarningsAndErrors: boolean,<br> hideConsoleLogsInStrictMode: boolean,<br> disableSecondConsoleLogDimmingInStrictMode: boolean<br>}</pre> | <pre>{<br> appendComponentStack: true,<br> breakOnConsoleErrors: false,<br> showInlineWarningsAndErrors: true,<br> hideConsoleLogsInStrictMode: false,<br> disableSecondConsoleLogDimmingInStrictMode: false<br>}</pre> | |
| 39 | |
| 40 | #### Component filters |
| 41 | Each filter object must include `type` and `isEnabled`. Some filters also require `value` or `isValid`. |
| 42 | |
| 43 | | Type | Required fields | Description | |
| 44 | |------|-----------------|-------------| |
| 45 | | `ComponentFilterElementType` (`1`) | `type`, `isEnabled`, `value: ElementType` | Hides elements of the given element type. DevTools defaults to hiding host components. | |
| 46 | | `ComponentFilterDisplayName` (`2`) | `type`, `isEnabled`, `isValid`, `value: string` | Hides components whose display name matches the provided RegExp string. | |
| 47 | | `ComponentFilterLocation` (`3`) | `type`, `isEnabled`, `isValid`, `value: string` | Hides components whose source location matches the provided RegExp string. | |
| 48 | | `ComponentFilterHOC` (`4`) | `type`, `isEnabled`, `isValid` | Hides higher-order components. | |
| 49 | | `ComponentFilterEnvironmentName` (`5`) | `type`, `isEnabled`, `isValid`, `value: string` | Hides components whose environment name matches the provided string. | |
| 50 | | `ComponentFilterActivitySlice` (`6`) | `type`, `isEnabled`, `isValid`, `activityID`, `rendererID` | Filters activity slices; usually managed by DevTools rather than user code. | |
| 51 | |
| 52 | ### `connectToDevTools` options |
| 53 | | Prop | Default | Description | |
| 54 | |------------------------|---------------|---------------------------------------------------------------------------------------------------------------------------| |
| 55 | | `host` | `"localhost"` | Socket connection to frontend should use this host. | |
| 56 | | `isAppActive` | | (Optional) function that returns true/false, telling DevTools when it's ready to connect to React. | |
| 57 | | `path` | `""` | Path appended to the WebSocket URI (e.g. `"/__react_devtools__/"`). Useful when proxying through a reverse proxy on a subpath. A leading `/` is added automatically if missing. | |
| 58 | | `port` | `8097` | Socket connection to frontend should use this port. | |
| 59 | | `resolveRNStyle` | | (Optional) function that accepts a key (number) and returns a style (object); used by React Native. | |
| 60 | | `retryConnectionDelay` | `200` | Delay (ms) to wait between retrying a failed Websocket connection | |
| 61 | | `useHttps` | `false` | Socket connection to frontend should use secure protocol (wss). | |
| 62 | | `websocket` | | Custom `WebSocket` connection to frontend; overrides `host` and `port` settings. | |
| 63 | | `onSettingsUpdated` | | A callback that will be called when the user updates the settings in the UI. You can use it for persisting user settings. | | |
| 64 | |
| 65 | |
| 66 | ### `connectWithCustomMessagingProtocol` options |
| 67 | | Prop | Description | |
| 68 | |---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| 69 | | `onSubscribe` | Function, which receives listener (function, with a single argument) as an argument. Called when backend subscribes to messages from the other end (frontend). | |
| 70 | | `onUnsubscribe` | Function, which receives listener (function) as an argument. Called when backend unsubscribes to messages from the other end (frontend). | |
| 71 | | `onMessage` | Function, which receives 2 arguments: event (string) and payload (any). Called when backend emits a message, which should be sent to the frontend. | |
| 72 | | `onSettingsUpdated` | A callback that will be called when the user updates the settings in the UI. You can use it for persisting user settings. | |
| 73 | |
| 74 | Unlike `connectToDevTools`, `connectWithCustomMessagingProtocol` returns a callback, which can be used for unsubscribing the backend from the global DevTools hook. |
| 75 | |
| 76 | # Frontend API |
| 77 | |
| 78 | Frontend APIs can be used to render the DevTools UI into a DOM node. One example of this is [`react-devtools`](https://github.com/facebook/react/tree/main/packages/react-devtools) which wraps DevTools in an Electron app. |
| 79 | |
| 80 | ### Example |
| 81 | ```js |
| 82 | import DevtoolsUI from "react-devtools-core/standalone"; |
| 83 | |
| 84 | // See the full list of API methods in documentation below. |
| 85 | const { setContentDOMNode, startServer } = DevtoolsUI; |
| 86 | |
| 87 | // Render DevTools UI into a DOM element. |
| 88 | setContentDOMNode(document.getElementById("container")); |
| 89 | |
| 90 | // Start socket server used to communicate between backend and frontend. |
| 91 | startServer( |
| 92 | // Port defaults to 8097 |
| 93 | 1234, |
| 94 | |
| 95 | // Host defaults to "localhost" |
| 96 | "example.devserver.com", |
| 97 | |
| 98 | // Optional config for secure socket (WSS). |
| 99 | { |
| 100 | key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), |
| 101 | cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') |
| 102 | } |
| 103 | ); |
| 104 | ``` |
| 105 | |
| 106 | ### Exported methods |
| 107 | The `default` export is an object defining the methods described below. |
| 108 | |
| 109 | These methods support chaining for convenience. For example: |
| 110 | ```js |
| 111 | const DevtoolsUI = require("react-devtools-core/standalone"); |
| 112 | DevtoolsUI.setContentDOMNode(element).startServer(); |
| 113 | ``` |
| 114 | |
| 115 | #### `connectToSocket(socket: WebSocket)` |
| 116 | > This is an advanced config function that is typically not used. |
| 117 | |
| 118 | Custom `WebSocket` connection to use for communication between DevTools frontend and backend. Calling this method automatically initializes the DevTools UI (similar to calling `startServer()`). |
| 119 | |
| 120 | #### `openProfiler()` |
| 121 | Automatically select the "Profiler" tab in the DevTools UI. |
| 122 | |
| 123 | #### `setContentDOMNode(element: HTMLElement)` |
| 124 | Set the DOM element DevTools UI should be rendered into on initialization. |
| 125 | |
| 126 | #### `setDisconnectedCallback(callback: Function)` |
| 127 | _Optional_ callback to be notified when DevTools `WebSocket` closes (or errors). |
| 128 | |
| 129 | #### `setProjectRoots(roots: Array<string>)` |
| 130 | _Optional_ set of root directories for source files. These roots can be used to open an inspected component's source code using an IDE. |
| 131 | |
| 132 | #### `setStatusListener(callback: Function)` |
| 133 | _Optional_ callback to be notified of socket server events (e.g. initialized, errored, connected). |
| 134 | |
| 135 | This callback receives two parameters: |
| 136 | ```js |
| 137 | function onStatus( |
| 138 | message: string, |
| 139 | status: 'server-connected' | 'devtools-connected' | 'error' |
| 140 | ): void { |
| 141 | // ... |
| 142 | } |
| 143 | ``` |
| 144 | |
| 145 | #### `startServer(port?, host?, httpsOptions?, loggerOptions?, path?, clientOptions?)` |
| 146 | Start a socket server (used to communicate between backend and frontend) and renders the DevTools UI. |
| 147 | |
| 148 | This method accepts the following parameters: |
| 149 | | Name | Default | Description | |
| 150 | |---|---|---| |
| 151 | | `port` | `8097` | Port the local server listens on. | |
| 152 | | `host` | `"localhost"` | Host the local server binds to. | |
| 153 | | `httpsOptions` | | _Optional_ object defining `key` and `cert` strings. | |
| 154 | | `loggerOptions` | | _Optional_ object defining a `surface` string (to be included with DevTools logging events). | |
| 155 | | `path` | | _Optional_ path to append to the WebSocket URI served to connecting clients (e.g. `"/__react_devtools__/"`). Also set via the `REACT_DEVTOOLS_PATH` env var in the Electron app. | |
| 156 | | `clientOptions` | | _Optional_ object with client-facing overrides (see below). | |
| 157 | |
| 158 | ##### `clientOptions` |
| 159 | |
| 160 | When connecting through a reverse proxy, the client may need to connect to a different host, port, or protocol than the local server. Use `clientOptions` to override what appears in the `connectToDevTools()` script served to clients. Any field not set falls back to the corresponding server value. |
| 161 | |
| 162 | | Field | Default | Description | |
| 163 | |---|---|---| |
| 164 | | `host` | server `host` | Host the client connects to. | |
| 165 | | `port` | server `port` | Port the client connects to. | |
| 166 | | `useHttps` | server `useHttps` | Whether the client should use `wss://`. | |
| 167 | |
| 168 | These can also be set via environment variables in the Electron app: |
| 169 | |
| 170 | | Env Var | Description | |
| 171 | |---|---| |
| 172 | | `REACT_DEVTOOLS_CLIENT_HOST` | Overrides the host in the served client script. | |
| 173 | | `REACT_DEVTOOLS_CLIENT_PORT` | Overrides the port in the served client script. | |
| 174 | | `REACT_DEVTOOLS_CLIENT_USE_HTTPS` | Set to `"true"` to make the served client script use `wss://`. | |
| 175 | |
| 176 | ##### Reverse proxy example |
| 177 | |
| 178 | Run DevTools locally on the default port, but tell clients to connect through a remote proxy: |
| 179 | ```sh |
| 180 | REACT_DEVTOOLS_CLIENT_HOST=remote.example.com \ |
| 181 | REACT_DEVTOOLS_CLIENT_PORT=443 \ |
| 182 | REACT_DEVTOOLS_CLIENT_USE_HTTPS=true \ |
| 183 | REACT_DEVTOOLS_PATH=/__react_devtools__/ \ |
| 184 | react-devtools |
| 185 | ``` |
| 186 | The server listens on `localhost:8097`. The served script tells clients: |
| 187 | ```js |
| 188 | connectToDevTools({host: 'remote.example.com', port: 443, useHttps: true, path: '/__react_devtools__/'}) |
| 189 | ``` |
| 190 | |
| 191 | # Development |
| 192 | |
| 193 | Watch for changes made to the backend entry point and rebuild: |
| 194 | ```sh |
| 195 | yarn start:backend |
| 196 | ``` |
| 197 | |
| 198 | Watch for changes made to the standalone UI entry point and rebuild: |
| 199 | ```sh |
| 200 | yarn start:standalone |
| 201 | ``` |
| 202 | |
| 203 | Run the standalone UI using `yarn start` in the [`react-devtools`](https://github.com/facebook/react/tree/main/packages/react-devtools). |