### Start Example React-Native App Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/index.md Starts the example React Native application to test Reactotron changes. ```bash yarn start:example ``` -------------------------------- ### Setup and Usage of Reactotron Client Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-client/README.md Demonstrates how to set up a Reactotron client with various configuration options and how to connect to the server. Includes examples of sending different types of log messages, state updates, API responses, and benchmark reports. ```javascript import { createClient } from "reactotron-core-client" // setup a reactotron client const client = createClient({ // injected in for compatibility createSocket: (path) => new WebSocket(path), host: "localhost", port: 9090, name: "I am a client!", // fires when we get connected to a server onConnect: () => console.log("hi"), // fires when we get disconnected from the server onDisconnect: () => console.log("bye"), // fires when the server is telling us something onCommand: ({ type, payload }) => { switch (type) { case "server.intro": const { name, version } = payload break case "state.values.request": const { path } = payload // the path to the state break case "state.keys.request": const { path } = payload // the path to the state break case "state.values.subscribe": const { paths } = payload // string array of state paths break case "state.action.dispatch": const { action } = payload // an object to be dispatch through the state plugin break } console.log(`I just received a ${type} command`) console.log(payload) }, }) // connect to the server client.connect() // send a log message as a string client.send("log", { level: "debug", message: "hello!" }) // send a log message as a string that's important client.send("log", { level: "debug", message: "hello!" }, true) // sending an object log message client.send("log", { level: "debug", message: { nested: [1, 2, { hello: "there" }], fun: true, }, }) // send a warning client.send("log", { level: "warn", message: "oops" }) // send an error with an optional stack trace client.send("log", { level: "error", message: "crap", stackTrace: [], }) // report that an action is complete client.send("state.action.complete", { name: "LOGIN_REQUEST", action: { type: "LOGIN_REQUEST", email: "steve@kellock.ca", password: "secret...shhh....", }, }) // report that values have changed client.send("state.values.response", { path: "user.givenName", value: "Steve", valid: true, }) // list the keys at a given path in state client.send("state.keys.response", { path: "user", keys: ["givenName", "familyName"], valid: true, }) // let the server know the state values they're subscribed to have changed client.send("state.values.change", { changes: [ { path: "user.givenName", value: "Steve" }, { path: "user", value: { givenName: "Steve", familyName: "Kellock" }, }, ], }) // report any API activity client.send("api.response", { request: { url: "https://api.example.com/v1/people", method: "POST", data: { user: { givenName: "Steve", familyName: "Kellock" }, }, headers: { Accept: "application/json", Cookie: "__ispy=mylittleye; __something=blue", }, }, response: { body: { result: "ok" }, status: 200, headers: { Connection: "keep-alive", Server: "cloudflare-nginx", }, }, duration: 150.0, }) // send a benchmark report up to the server client.send("bench.report", { title: "My Fast Algorithmz", steps: [ { title: "Step 1", time: 0 }, { title: "Step 2", time: 123 }, { title: "Step 3", time: 1024 }, ], }) // a utility to time things const elapsed = client.startTimer() // do something you want to time const ms = elapsed() // the number of ms it took. ish. // display a custom event client.display({ name: "MY EVENT", value: { color: "green", vegetable: "spinach", variant: "baby", salad: true }, important: true, preview: "What's in my appetizer?", }) ``` -------------------------------- ### Install Dependencies and Start Reactotron App Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/index.md Installs project dependencies and starts the Reactotron Electron app in development mode. ```bash yarn yarn start ``` -------------------------------- ### Install reactotron-core-contract Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-contract/README.md Install the package using npm or yarn. ```bash npm install reactotron-core-contract # or yarn add reactotron-core-contract ``` -------------------------------- ### Install reactotron-apisauce with npm Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/apisauce.md Install the plugin using npm. ```bash npm i --save-dev reactotron-apisauce ``` -------------------------------- ### Install reactotron-apisauce with yarn Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/apisauce.md Install the plugin using yarn. ```bash yarn add reactotron-apisauce -D ``` -------------------------------- ### Install reactotron-redux Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/redux.md Install the reactotron-redux package using npm or yarn. ```bash npm install --save-dev reactotron-redux ``` ```bash yarn add reactotron-redux -D ``` -------------------------------- ### Install create-react-app Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-js.md Installs the create-react-app tool globally. Use this to bootstrap a new React JS project. ```bash npm i -g create-react-app ``` -------------------------------- ### Configure ESLint Plugin Reactotron Source: https://github.com/infinitered/reactotron/blob/master/lib/eslint-plugin-reactotron/README.md Configure your ESLint setup to include the reactotron plugin and enable specific rules. This example shows how to add it to your package.json. ```json "eslintConfig": { "plugins": [ "reactotron" ], rules: { "reactotron/no-tron-in-production": "error" } } ``` -------------------------------- ### Install reactotron-template with npm or yarn Source: https://github.com/infinitered/reactotron/blob/master/scripts/template/README.md Use this command to install the package as a development dependency. ```bash npm i --save-dev reactotron-template # or yarn add -D reactotron-template ``` -------------------------------- ### Install reactotron-apisauce Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-apisauce/README.md Install the package as a development dependency using npm or yarn. ```bash npm i --save-dev reactotron-apisauce # or yarn add -D reactotron-apisauce ``` -------------------------------- ### Install reactotron-react-native-mmkv Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-react-native-mmkv/README.md Install the package as a development dependency using npm or yarn. ```bash npm i --save-dev reactotron-react-native-mmkv # or yarn add -D reactotron-react-native-mmkv ``` -------------------------------- ### Configure Reactotron Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-js.md Basic Reactotron configuration and connection setup. This file should be imported on application startup. ```javascript import Reactotron from "reactotron-react-js" Reactotron.configure() // we can use plugins here -- more on this later .connect() // let's connect! ``` -------------------------------- ### Create and Configure Reactotron Server Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-server/README.md Demonstrates how to import, create, and configure a Reactotron server with a specified port. It also shows how to listen for various server events like start, connect, command, and disconnect. ```javascript import { createServer } from "reactotron-core-server" // configure a server const server = createServer({ port: 9090, // default }) // The server has started. server.on("start", () => console.log("Reactotron started")) // A client has connected, but we don't know who it is yet. server.on("connect", () => console.log("Connected")) // A client has connected and provided us the initial detail we want. server.on("connectionEstablished", (conn) => console.log("Connection", conn)) // A command has arrived from the client. server.on("command", (cmd) => console.log("Command: ", cmd)) // A client has disconnected. server.on("disconnect", (conn) => console.log("Disconnected", conn)) // The server has stopped. server.on("stop", () => console.log("Reactotron stopped")) // Port is already in use server.on("portUnavailable", () => console.log("Port 9090 unavailable")) // start the server server.start() // check to see if it started if (!server.started) { console.log("Server failed to start") return } // say hello when we connect (this is automatic, you don't send this) server.send("hello.server", {}) // request some values from state server.send("state.values.request", { path: "user.givenName" }) // request some keys from state server.send("state.keys.request", { path: "user" }) // subscribe to some state paths so when then change, we get notified server.send("state.values.subscribe", { paths: ["user.givenName", "user"] }) // stop the server server.stop() ``` -------------------------------- ### Install reactotron-mst with npm Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/mst.md Add reactotron-mst as a development dependency using npm. ```sh npm i reactotron-mst --save-dev ``` -------------------------------- ### Create a new React App Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-js.md Creates a new React JS project and navigates into its directory. Assumes create-react-app is installed globally. ```bash create-react-app this-better-work cd this-better-work ``` -------------------------------- ### Install ESLint Plugin Reactotron Source: https://github.com/infinitered/reactotron/blob/master/lib/eslint-plugin-reactotron/README.md Install the plugin as a development dependency using npm or yarn. ```bash npm i --save-dev eslint-plugin-reactotron # or yarn add -D eslint-plugin-reactotron ``` -------------------------------- ### Install reactotron-react-native-mmkv with npm Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/react-native-mmkv.md Use npm to install the reactotron-react-native-mmkv package as a development dependency. ```bash npm i --save-dev reactotron-react-native-mmkv ``` -------------------------------- ### Install reactotron-react-native-mmkv with yarn Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/react-native-mmkv.md Use yarn to install the reactotron-react-native-mmkv package as a development dependency. ```bash yarn add -D reactotron-react-native-mmkv ``` -------------------------------- ### Install reactotron-mst with Yarn Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/mst.md Add reactotron-mst as a development dependency using Yarn. ```sh yarn add reactotron-mst --dev ``` -------------------------------- ### Install Reactotron for React JS Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-js.md Installs the Reactotron library as a development dependency for your React JS project. ```bash npm i --save-dev reactotron-react-js ``` -------------------------------- ### Add Reactotron as Dev Dependency (yarn) Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-native.md Install Reactotron for React Native using yarn. ```bash yarn add reactotron-react-native -D ``` -------------------------------- ### Add Reactotron as Dev Dependency (npm) Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-native.md Install Reactotron for React Native using npm. ```bash npm i --save-dev reactotron-react-native ``` -------------------------------- ### Basic Counter Plugin Example Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-client/README.md A simple plugin that increments a counter on each received command and logs a message when the counter reaches 69. ```javascript // counter-plugin.js export default () => (reactotron) => { let commandCounter = 0 return { onCommand: (command) => { commandCounter++ if (commandCounter === 69) console.log("tee hee") }, } } ``` -------------------------------- ### Package JSON Version Example Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/releasing.md This JSON snippet shows the structure of a package.json file, specifically highlighting the 'version' field which determines the git tag for a workspace release. ```json { "name": "reactotron-app", "version": "3.0.0" } ``` -------------------------------- ### Benchmark Plugin Example Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-contract/README.md Plugins import payload types to ensure they send properly structured data, shown here for a benchmark plugin. ```typescript import type { BenchmarkReportPayload } from "reactotron-core-contract" import type { ReactotronCore, Plugin } from "reactotron-core-client" const benchmark = () => (reactotron: ReactotronCore) => { const benchmark = (title: string) => { const steps: BenchmarkReportPayload["steps"] = [] const step = (stepTitle: string) => { steps.push({ title: stepTitle, time: performance.now(), delta: 0, }) } const stop = () => { reactotron.send("benchmark.report", { title, steps }) } return { step, stop } } return { features: { benchmark }, } satisfies Plugin } ``` -------------------------------- ### Build and Link Workspace Packages to Target App Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/index.md Builds all Reactotron packages and installs them into a specified target React Native application. Ensure the target app has already run `yarn`. ```bash npx zx scripts/install-workspace-packages-in-target.mjs ~/Code/PizzaApp ``` -------------------------------- ### Add Networking Plugin to Reactotron Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/networking.md Include the networking plugin in your Reactotron configuration to start tracking requests. ```javascript Reactotron.configure() .use(networking()) // <--- here we go! .connect(); ``` -------------------------------- ### Add trackGlobalErrors Plugin to Reactotron Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/track-global-errors.md Configure Reactotron to use the trackGlobalErrors plugin by adding it during the setup process. ```javascript Reactotron.configure() .use(trackGlobalErrors()) // <--- here we go! .connect(); ``` -------------------------------- ### API Response Plugin Example Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-contract/README.md Plugins import payload types to ensure they send properly structured data, shown here for an API response plugin. ```typescript import type { ApiResponsePayload } from "reactotron-core-contract" import type { ReactotronCore, Plugin } from "reactotron-core-client" const apiResponse = () => (reactotron: ReactotronCore) => { return { features: { apiResponse: ( request: ApiResponsePayload["request"], response: ApiResponsePayload["response"], duration: number ) => { reactotron.send("api.response", { request, response, duration }) }, }, } satisfies Plugin } ``` -------------------------------- ### Import Reactotron Configuration Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-js.md Imports the Reactotron configuration file on application startup. Ensure this is done before any other Reactotron calls. ```javascript import "./ReactotronConfig" ``` -------------------------------- ### Basic Reactotron Initialization Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-native.md Configure and connect Reactotron with default settings and built-in React Native plugins. ```javascript import Reactotron from "reactotron-react-native"; Reactotron.configure() // controls connection & communication settings .useReactNative() // add all built-in react native plugins .connect(); // let's connect! ``` -------------------------------- ### Client Intro Message Format Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-client/README.md Defines the structure of the client.intro message sent to the server upon connection, containing client configuration details. ```json { "host": "localhost", // the server we're connecting to "port": 9090, // the server's port "name": "My Fantastic App", // the name of our app "userAgent": "Internet Explorer 3.0", // the user agent "reactotronVersion": "0.99.1", // the version of reactotron "environment": "development" // our environment } ``` -------------------------------- ### Configure Reactotron with a Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/index.md Import a plugin and pass it to the `use` method when configuring Reactotron to integrate its functionality. ```javascript import Reactotron from "reactotron-react-native" Reactotron.configure() .use(somePlugin()) .connect() ``` -------------------------------- ### Clear Reactotron Logs Source: https://github.com/infinitered/reactotron/blob/master/docs/tips.md Call `Reactotron.clear()` to clear all logs. Useful for resetting logs when an app starts up. ```javascript Reactotron.clear() ``` -------------------------------- ### Server Intro Message Format Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-client/README.md Defines the structure of the server.intro message received from the server after connection, containing server configuration details. ```json { "name": "I Am Server. Roar.", "version": "0.99.1" } ``` -------------------------------- ### Advanced Reactotron Initialization with Custom Plugins Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-native.md Configure Reactotron with custom settings, including specific plugins and options for React Native features like AsyncStorage and networking. ```javascript import Reactotron from "reactotron-react-native"; import AsyncStorage from "@react-native-async-storage/async-storage"; Reactotron.setAsyncStorageHandler(AsyncStorage) .configure({ name: "React Native Demo", }) .useReactNative({ asyncStorage: false, // there are more options to the async storage. networking: { // optionally, you can turn it off with false. ignoreUrls: /symbolicate/, }, editor: false, // there are more options to editor errors: { veto: (stackFrame) => false }, // or turn it off with false overlay: false, // just turning off overlay }) .connect(); ``` -------------------------------- ### Import Storybook Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/storybook.md Import the storybook plugin when setting up Reactotron. This is necessary for manual configuration. ```javascript import Reactotron, { storybook } from "reactotron-react-native" ``` -------------------------------- ### Reactotron Initialization with Custom Middleware Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-native.md Initialize Reactotron with built-in React Native plugins and a custom middleware plugin. ```javascript import Reactotron from "reactotron-react-native"; const middleware = (tron) => { /* plugin definition */ }; Reactotron.setAsyncStorageHandler(AsyncStorage) .configure({ name: "React Native Demo", }) .useReactNative() // add all built-in react native plugins .use(middleware) // plus some custom made plugin. .connect(); ``` -------------------------------- ### Import Reactotron Configuration in App Entry Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-native.md Conditionally require the Reactotron configuration file in the application's entry point for development builds. ```javascript if (__DEV__) { require("./ReactotronConfig"); } ``` -------------------------------- ### Monitor Specific Apisauce Responses with Reactotron Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-apisauce/README.md Conditionally send Apisauce responses to Reactotron, for example, only when a `SERVER_ERROR` problem occurs. This helps in focusing on critical issues. ```javascript // or if you just wanted to track on 500's api.addMonitor((response) => { if (response.problem === "SERVER_ERROR") Reactotron.apisauce(response) }) ``` -------------------------------- ### Selectively Restore Immutable State with Reactotron Redux Source: https://github.com/infinitered/reactotron/blob/master/docs/tips.md When only some reducers are immutable, use `onRestore` to selectively transform state. This example keeps the `nav` state mutable while transforming others. ```javascript .use(reactotronRedux({ // Fires when Reactotron uploads a new copy of the state tree. onRestore: state => { return { ...Immutable(state), nav: state.nav } } })) ``` -------------------------------- ### Configure Overlay Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/overlay.md Enable the overlay plugin within Reactotron's configuration. ```javascript Reactotron.configure() .useReactNative({ overlay: true, // <--- here we go! }) .connect() ``` -------------------------------- ### Filter MST events with a custom function Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/mst.md Configure a filter function within the mst plugin options to selectively send MST events to Reactotron. This example prevents 'postProcessSnapshot' actions from being logged. ```ts import Tron from "reactotron-react-native" import { mst } from "reactotron-mst" const RX = /postProcessSnapshot/ const filter = (event) => RX.test(event.name) === false Tron.use(mst({ filter })) ``` -------------------------------- ### Import AsyncStorage Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/async-storage.md Import the asyncStorage plugin when configuring Reactotron. This is the first step to enable AsyncStorage tracking. ```javascript import Reactotron, { asyncStorage } from "reactotron-react-native" ``` -------------------------------- ### Import MMKV Storage Instance Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/react-native-mmkv.md Import your MMKV storage instance from its defined location. Ensure the path is correct. ```tsx import { MMKV } from "react-native-mmkv" export const storage = new MMKV() ``` -------------------------------- ### Import Overlay Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/overlay.md Import the overlay plugin alongside Reactotron for integration. ```javascript import Reactotron, { overlay } from "reactotron-react-native" ``` -------------------------------- ### Build and Test Local Reactotron Codebase Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/index.md Builds the Reactotron project and runs local tests to ensure code quality before committing. ```bash yarn build-and-test:local ``` -------------------------------- ### Generate a New Reactotron Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/index.md Generates a new plugin workspace in the `./lib` directory with a basic template. ```bash yarn generate:plugin my-plugin ``` -------------------------------- ### Run Nx Version Task for a Project Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/releasing.md This command runs the 'version' task defined in project.json for a specific project using Nx. ```bash npx nx run :version ``` -------------------------------- ### Show Image Overlay on App Source: https://github.com/infinitered/reactotron/blob/master/docs/mcp.md Use the 'show_overlay' tool to display an image on top of your running application for design comparison. Supports local file paths, file URIs, http URLs, and data URIs. Local files are base64 encoded. Supported formats are PNG, JPEG, and GIF. ```text "Show the design mockup from ~/Downloads/design.png as an overlay on the app" ``` -------------------------------- ### Configure Reactotron with Open In Editor Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/open-in-editor.md Add the openInEditor plugin to the Reactotron configuration. This enables the click-to-open functionality within Reactotron. ```javascript Reactotron.configure() .use(openInEditor()) // <--- here we go! .connect() ``` -------------------------------- ### Configure Reactotron with MMKV Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/react-native-mmkv.md Add the mmkvPlugin to your Reactotron configuration, passing your MMKV storage instance. Update the import path for your storage instance. ```tsx import Reactotron from "reactotron-react-native" import type { ReactotronReactNative } from "reactotron-react-native" import mmkvPlugin from "reactotron-react-native-mmkv" import { storage } from "./mmkv/storage/instance/location" // <--- update this to your mmkv instance. Reactotron.configure() .use(mmkvPlugin({ storage })) .connect() ``` -------------------------------- ### Configure Reactotron with MMKV Plugin Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-react-native-mmkv/README.md Add the mmkvPlugin to your Reactotron configuration, passing your MMKV storage instance. Update the import path for your storage instance as needed. ```tsx import Reactotron from "reactotron-react-native" import type { ReactotronReactNative } from "reactotron-react-native" import mmkvPlugin from "reactotron-react-native-mmkv" import { storage } from "./mmkv/storage/instance/location" // <--- update this location ... Reactotron.configure() .use(mmkvPlugin({ storage })) // <--- here we go! .connect() ``` -------------------------------- ### Configure Reactotron with reactotron-redux Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/redux.md Add reactotron-redux as a plugin in your Reactotron configuration file. ```javascript // ReactotronConfig.js import { reactotronRedux } from 'reactotron-redux' // then add it to the plugin list const reactotron = Reactotron .configure({ name: 'React Native Demo' }) .use(reactotronRedux()) // <- here i am! .connect() //Don't forget about me! export default reactotron // also: export me so I can be referenced by Redux store ``` -------------------------------- ### Configure Reactotron with Storybook Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/storybook.md Manually add the storybook plugin to Reactotron's configuration. This is an alternative to using `.useReactNative()` with the storybook option set to true. ```javascript Reactotron.configure() .useReactNative({ storybook: true, }) .connect() ``` -------------------------------- ### Import Apisauce Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/apisauce.md Import the apisauce plugin for use in Reactotron configuration. ```javascript import apisaucePlugin from "reactotron-apisauce" ``` -------------------------------- ### Reactotron Plugin Structure Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-contract/README.md Illustrates the basic structure of a Reactotron plugin, including importing types, handling commands, defining features, and using lifecycle hooks. This serves as a template for extending Reactotron's functionality. ```typescript import type { MyPayloadType } from "reactotron-core-contract" import type { ReactotronCore, Plugin } from "reactotron-core-client" export default (config = {}) => (reactotron: ReactotronCore) => { return { // Handle server commands onCommand: (command) => { // Check command.type and handle accordingly }, // Add features to Reactotron instance features: { myFeature: (data: MyPayloadType) => { reactotron.send("my.command", data) }, }, // Lifecycle hooks onConnect: () => { /* ... */ }, onDisconnect: () => { /* ... */ }, } satisfies Plugin } ``` -------------------------------- ### Configure Reactotron with Apisauce Plugin Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-apisauce/README.md Add the `reactotron-apisauce` plugin to your Reactotron configuration. This enables Reactotron to receive and display Apisauce responses. ```javascript // in your reactotron config (where you setup Reactotron) add this as a plugin. import tronsauce from "reactotron-apisauce" // then plug it in when you configure Reactotron. Reactotron.configure() .use(tronsauce()) // <-- here we go!!! .connect() ``` -------------------------------- ### Custom Command to Go Back Source: https://github.com/infinitered/reactotron/blob/master/docs/custom-commands.md Utilize react-navigation to add a button in Reactotron that navigates to the previous screen. Logs a message before executing the navigation. ```typescript // Utilize react-navigation to put a button in Reactotron to go back to the previous screen: Reactotron.onCustomCommand({ title: "Go Back", description: "Goes back", command: "goBack", handler: () => { Reactotron.log("Going back") goBack() }, }) ``` -------------------------------- ### Configure Reactotron to use mst plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/mst.md Import and use the mst plugin within your Reactotron configuration to enable Mobx State Tree tracking. ```ts // import the plugin import { mst } from "reactotron-mst" // tell Reactotron to use this plugin Reactotron.use(mst()) ``` -------------------------------- ### Configure Reactotron Host for iOS Source: https://github.com/infinitered/reactotron/blob/master/docs/troubleshooting.md When tethered to an iOS device, uncomment and set the 'host' in ReactotronConfig.js to your machine's IP address. Ensure a comma follows this line. ```javascript if (__DEV__) { Reactotron .configure({ host: '', // default is localhost (on android don't forget to `adb reverse tcp:9090 tcp:9090`) name: 'Ignite App' // would you like to see your app's name? }) ``` -------------------------------- ### Import Networking Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/networking.md Import the networking plugin from reactotron-react-native to enable network tracking. ```javascript import Reactotron, { networking } from "reactotron-react-native"; ``` -------------------------------- ### Custom Command to Navigate to a Route Source: https://github.com/infinitered/reactotron/blob/master/docs/custom-commands.md Accept user input from Reactotron to navigate to a specified route. Requires a 'route' argument of type String. Logs the navigation action or an error if no route is provided. ```typescript // Accept user input from Reactotron and navigate to that route: Reactotron.onCustomCommand({ command: "navigateTo", handler: (args) => { const { route } = args if (route) { Reactotron.log(`Navigating to: ${route}`) navigate(route) } else { Reactotron.log("Could not navigate. No route provided.") } }, title: "Navigate To Screen", description: "Navigates to a screen by name.", args: [ { name: "route", type: ArgType.String, }, ], }) ``` -------------------------------- ### Reactotron MCP Architecture Diagram Source: https://github.com/infinitered/reactotron/blob/master/docs/mcp.md Illustrates the flow of data from a React Native app to the Reactotron Desktop, highlighting the roles of the relay server and the MCP server. ```text React Native app | WebSocket (port 9090, unchanged) v Reactotron Desktop ├── relay server (reactotron-core-server) └── MCP server (reactotron-mcp, HTTP on configurable port) ↑ Claude Code ``` -------------------------------- ### Configure and Use Storybook with React Native Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/storybook.md Set up Storybook for React Native, including configuring the Storybook UI and integrating it with Reactotron's storybook switcher. Ensure the 'require' path points to your stories directory. ```javascript import { getStorybookUI, configure } from '@storybook/react-native' {...} configure(() => { require('../../storybook/stories') // This should point to your "root" set of stories }, module) const StorybookUIRoot = getStorybookUI({ port: 7007, onDeviceUI: true }) // This configuration can be changed based upon personal wants class StorybookUIHMRRoot extends Component { render () { return } } // Assuming you have Reactotron on console.tron export default console.tron.storybookSwitcher(StorybookUIHMRRoot)(RootContainer) ``` -------------------------------- ### Configure Reactotron with Apisauce Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/apisauce.md Add the apisauce plugin to your Reactotron configuration to enable network request monitoring. ```javascript Reactotron.configure() .use( apisaucePlugin({ // ignoreContentTypes: /^(image)\/.\*$/i // <--- a way to skip printing the body of some requests (default is any image) }) ) // <-- here we go!!! .connect() ``` -------------------------------- ### Reactotron Plugin Structure Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-client/README.md Defines the available hooks and methods for a Reactotron plugin. Use `onCommand` to handle server commands, `onConnect`/`onDisconnect` for connection events, `onPlugin` for initialization, and `features` to add custom methods to the Reactotron client. ```javascript { // Fires whenever a command is received from the server. // // command is an object with: // .type - String - the name of the command // .payload - anything - maybe null, maybe a string, maybe an object, not a function // its whatever the server sent. onCommand: command => { const { type, payload } = command }, // Fires when we connect to the server. Will only be called if the plugin // is setup before connecting to the server. onConnect: () => {}, // Fires when we disconnect from the server. onDisconnect: () => {}, // fires when the plugin is attached (this only happens once at initialization) onPlugin: reactotron => console.log('I have been attached to ', reactotron), // This is an object (not a function). The keys are strings. The values are functions. // Every entry in here will become a method on the Reactotron client object. // Collisions are handled on a first-come first-serve basis. // // These names are reserved: // connect, configure, send, use, options, connected, plugins, and socket. // // Sorry. // // I went with this mixin approach because the interface feels nice from the // calling code point-of-view. features: { // Reactotron.log('hello!') log: (message) => send('log', { level: 'debug', message } ), // Reactotron.warn('look out! falling rocks!') warn: (message) => send('log', { level: 'warn', message } ), } } ``` -------------------------------- ### Log basic string to Reactotron Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-js.md Logs a simple string message to Reactotron. This can be used for basic debugging during rendering. ```javascript Reactotron.log("hello rendering world") ``` -------------------------------- ### Plugin Handling Server Commands Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-contract/README.md Plugins can handle commands from the server by checking the command type, ensuring type-safe command handling. ```typescript import { CommandType } from "reactotron-core-contract" import type { StateValuesRequestPayload } from "reactotron-core-contract" const myPlugin = () => (reactotron) => { return { onCommand: (command) => { // Type-safe command handling if (command.type === CommandType.StateValuesRequest) { const payload = command.payload as StateValuesRequestPayload const { path } = payload // Handle the request... } }, } } ``` -------------------------------- ### Wrap Root Component with Overlay Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/overlay.md Wrap your application's root UI component with Reactotron.overlay to ensure the overlay remains on top. ```javascript // let's pretend this is your app. class MyApp extends Component { render() { return I may have shipped too early. } } // let's wrap it, so the overlay stays on top! const MyAppWithBenefits = Reactotron.overlay(MyApp) export default MyAppWithBenefits ``` -------------------------------- ### Register a Simple Custom Command Source: https://github.com/infinitered/reactotron/blob/master/docs/custom-commands.md Register a custom command with just a command name and a handler function. This is a concise way to add simple commands. ```javascript Reactotron.onCustomCommand("test", () => console.log("This is an example")) ``` -------------------------------- ### Configure reactotron-redux with 'isActionImportant' option Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/redux.md Use the 'isActionImportant' option to highlight specific actions in Reactotron. ```javascript reactotronRedux({ isActionImportant: (action) => action.type === "repo.receive", }) ``` -------------------------------- ### Advanced Display with Reactotron Source: https://github.com/infinitered/reactotron/blob/master/docs/tips.md Utilize `console.tron.display()` for advanced logging, including custom names, values, previews, and images. The `important: true` flag adds an indicator. ```javascript // or Reactotron.display console.tron.display({ name: "Tacos", value: { a: 1, b: [1, 2, 3] }, preview: "when you click here, it might surprise you!", important: true, image: "http://placekitten.com/g/400/400", }) ``` -------------------------------- ### Register a Custom Command with Options Source: https://github.com/infinitered/reactotron/blob/master/docs/custom-commands.md Register a custom command with a specific command name, handler function, title, and description. The title appears on the button in Reactotron, and the description provides more context. ```javascript Reactotron.onCustomCommand({ command: "test2", handler: () => console.log("This is an example 2"), // Optional settings title: "A thing", // This shows on the button description: "The desc", // This shows below the button }) ``` -------------------------------- ### Configure AsyncStorage Plugin with Ignore Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/async-storage.md Optionally, configure the asyncStorage plugin to ignore specific keys. Provide an array of strings for keys that should not be sent to Reactotron. ```javascript asyncStorage({ ignore: ["secret"], }) ``` -------------------------------- ### Advanced MMKV Plugin Configuration with Ignore Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/react-native-mmkv.md Configure the mmkvPlugin to ignore specific keys, such as sensitive data, from being sent to Reactotron. ```tsx mmkvPlugin({ storage, ignore: ["secret"], }) ``` -------------------------------- ### Reactotron Plugin Structure Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-client/README.md Defines the basic structure for a Reactotron plugin. Plugins are added using the `use` function on the client. ```javascript export default () => (reactotron) => {} ``` -------------------------------- ### Configure Networking Plugin Options Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/networking.md Customize the networking plugin by providing options to ignore specific content types or URLs from being tracked. ```javascript networking({ ignoreContentTypes: /^(image)\/.\*$/i, ignoreUrls: /\/(logs|symbolicate)$/, }); ``` -------------------------------- ### Conditional Overlay for Production Builds Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/overlay.md Conditionally apply the Reactotron overlay only in development environments to avoid including it in production builds. ```javascript const MyAppWithBenefits = __DEV__ ? Reactotron.overlay(MyApp) : MyApp ``` -------------------------------- ### Configure reactotron-redux with 'onBackup' option Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/redux.md The 'onBackup' option allows you to modify the Redux state before it's sent to Reactotron. ```javascript onBackup: (state) => state ``` -------------------------------- ### Port Forwarding for Android Source: https://github.com/infinitered/reactotron/blob/master/docs/troubleshooting.md Use `adb reverse` to forward the Reactotron port from your Android device or emulator to your computer. This is necessary for localhost connections on Android 5.x+. ```sh adb reverse tcp:9090 tcp:9090 ``` -------------------------------- ### Manually Add trackGlobalLogs Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/track-global-logs.md If not using useReactNative, import and add the trackGlobalLogs plugin manually to your Reactotron configuration. ```javascript import Reactotron, { trackGlobalLogs } from "reactotron-react-native"; ``` ```javascript Reactotron.configure().use(trackGlobalLogs()).connect(); ``` -------------------------------- ### Release Artifacts using Yarn and OIDC Token Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/releasing.md This script invokes the release process, exchanging the OIDC token for a publish token and publishing artifacts to npm. ```bash yarn release:artifacts $CIRCLE_TAG ``` -------------------------------- ### Client Sending Log Command Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-contract/README.md Clients use contract types to send properly typed commands to the server, demonstrated here with a log command. ```typescript import { CommandType } from "reactotron-core-contract" import type { LogPayload, ApiResponsePayload, DisplayPayload } from "reactotron-core-contract" // Sending a log command const logPayload: LogPayload = { level: "debug", message: "Hello, Reactotron!", } client.send(CommandType.Log, logPayload) ``` -------------------------------- ### Run CI Trust Script Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/ci.md Use this script to push commits from an untrusted fork to a temporary branch on the main repository, triggering CI tests. Ensure you have write access to the main repository before running. ```bash yarn ci:trust ``` -------------------------------- ### Display custom data with Reactotron Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-js.md Displays custom data in Reactotron with a name, preview, and value. The 'important' flag highlights the entry. ```javascript Reactotron.display({ name: "KNOCK KNOCK", preview: "Who's there?", value: "Orange.", }) Reactotron.display({ name: "ORANGE", preview: "Who?", value: "Orange you glad you don't know me in real life?", important: true, }) ``` -------------------------------- ### Import Open In Editor Plugin Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/open-in-editor.md Import the openInEditor plugin alongside Reactotron for React Native. ```javascript import Reactotron, { openInEditor } from "reactotron-react-native" ``` -------------------------------- ### Attach Reactotron to Console Object Source: https://github.com/infinitered/reactotron/blob/master/docs/tips.md Attach Reactotron to the `console` object as `console.tron` for easier logging. This avoids needing to import Reactotron at the top of every file. ```javascript // horrible, but useful hack.... oh come on, don't look at me like that... it's JavaScript :| console.tron = Reactotron ``` -------------------------------- ### Track Mobx State Tree Node Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/mst.md Provide your root MST tree instance to Reactotron after configuring the plugin to enable tracking. ```ts // bring in Reactotron import * as Reactotron from "reactotron-react-native" // bring in your mst model import { MyModel } from "./my-model" // create an instance of your model const myTree = MyModel.create() // let reactotron-mst know about it Reactotron.trackMstNode(myTree) ``` -------------------------------- ### Performance Benchmark Report Message Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-client/README.md Sent from the client to the server to report performance details, including a title and a series of timed steps. ```json { "title": "My Sorting Algorithm", "steps": [ { "title": "start", "time": 0 }, { "title": "lookup tables", "time": 123 }, { "title": "randomize", "time": 422 } ] } ``` -------------------------------- ### Add Reactotron enhancer with Redux createStore Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/redux.md In development, create the Redux store by passing Reactotron's enhancer to createStore. ```diff import { createStore } from 'redux' import Reactotron from './ReactotronConfig' - const store = createStore(rootReducer) + const store = createStore(rootReducer, Reactotron.createEnhancer()) + // or const store = createStore(rootReducer, preloadedState, Reactotron.createEnhancer()) ``` -------------------------------- ### Payload Types Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-contract/README.md Import payload types to define the structure for each command. ```typescript import type { LogPayload, ApiResponsePayload, BenchmarkReportPayload, DisplayPayload, ImagePayload, StateActionCompletePayload, // ... and more } from "reactotron-core-contract" ``` -------------------------------- ### Watch for Rebuilds and Automatically Link Packages Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/index.md Watches for changes in Reactotron packages, rebuilds them, and automatically links them to the specified target React Native application. Ensure the target app has already run `yarn`. ```bash npx nx watch --all -- "npx zx scripts/install-workspace-packages-in-target.mjs ~/Code/PizzaApp" ``` -------------------------------- ### Add MCP Server to Claude Code Source: https://github.com/infinitered/reactotron/blob/master/docs/mcp.md Use this command to add the Reactotron MCP server to Claude Code, enabling it to connect to your app's debug events. ```bash claude mcp add --transport http reactotron http://localhost:4567/mcp ``` -------------------------------- ### Monitor All Apisauce Requests with Reactotron Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-apisauce/README.md Use `api.addMonitor(Reactotron.apisauce)` to automatically send all Apisauce requests and responses to Reactotron for inspection. ```javascript // Apisauce has a feature where you can attach a handler to watch // all requests/response flowing through your api. You can hook this up: api.addMonitor(Reactotron.apisauce) ``` -------------------------------- ### Conditionally Enable Reactotron in Development (React Native) Source: https://github.com/infinitered/reactotron/blob/master/docs/tips.md Wrap Reactotron calls in `if (__DEV__)` to ensure it only runs in development builds. This prevents battery drain and privacy concerns in production. ```javascript if (__DEV__) { // ZAP! } ``` -------------------------------- ### Warn with Reactotron Source: https://github.com/infinitered/reactotron/blob/master/docs/quick-start/react-js.md Logs a warning message to Reactotron. Displays with a distinct visual indicator in the Reactotron app. ```javascript Reactotron.warn("*glares*") ``` -------------------------------- ### Log Message Format Source: https://github.com/infinitered/reactotron/blob/master/lib/reactotron-core-client/README.md Client sends this to the server to log a message. For warnings and errors, an optional stackTrace array can be passed. ```json { "value": "hello!", "level": "debug" } ``` ```json { "value": "hello!", "level": "warn", "stackTrace": null } ``` ```json { "value": "hello!", "level": "error", "stackTrace": [{ "lineNo": 1, "file": "foo.js" }] } ``` -------------------------------- ### Run Nx Affected Version Task Source: https://github.com/infinitered/reactotron/blob/master/docs/contributing/releasing.md This command runs the 'version' task for projects affected by changes between two Git references, useful for automated releases. ```bash npx nx affected --target version --parallel=1 --base HEAD~1 --head HEAD ``` -------------------------------- ### Import trackGlobalErrors for React JS Source: https://github.com/infinitered/reactotron/blob/master/docs/plugins/track-global-errors.md Import the trackGlobalErrors plugin when using Reactotron with React JS. ```javascript import Reactotron, { trackGlobalErrors } from "reactotron-react-js"; ```