Skip to content

Conversation

joshuayoes
Copy link
Collaborator

@joshuayoes joshuayoes commented Oct 8, 2025

What does this PR do?

This PR adds an embedded Reactotron server that runs directly inside the reactotron-macos application. The server automatically starts on port 9292 when the app launches, eliminating the need to run a separate standalone server process. This provides a seamless out-of-the-box experience for users.

Key changes:

  • Added IRReactotronServer native module to bundle and run the standalone Reactotron server
  • Implemented useReactotronServer hook to manage server lifecycle (start on mount, stop on unmount)
  • Enhanced IRRunShellCommand to detect user's default shell for better compatibility
  • Added manual reconnect functionality in the sidebar with connection status display
  • Included network server entitlement for macOS app
  • Added esbuild for bundling the standalone server
  • Server runs on port 9292 by default

What GitHub issues does this PR fix?

Resolves #35

How to verify this code works?

reactotron-macos setup for this PR

  1. gh pr checkout 52
  2. npm install
  3. npm run pod
  4. npm run start
  5. npm run macos

reactotron example app setup for this PR

  1. yarn install
    Add Reactotron standalone server port to example app configuration
diff --git a/apps/example-app/app/devtools/ReactotronConfig.ts b/apps/example-app/app/devtools/ReactotronConfig.ts
index a5c7d5b6..9b9c1dad 100644
--- a/apps/example-app/app/devtools/ReactotronConfig.ts
+++ b/apps/example-app/app/devtools/ReactotronConfig.ts
@@ -18,6 +18,7 @@ import { Reactotron } from "./ReactotronClient"

 const reactotron = Reactotron.configure({
   name: require("../../package.json").name,
+  port: 9292,
   onConnect: () => {
     /** since this file gets hot reloaded, let's clear the past logs every time we connect */
     Reactotron.clear()
  1. yarn workspace example-app start
  2. Start on a different port to avoid conflicting with reactotron-macos
  3. Press i to launch in iOS simulator
  4. Consider Cmd + Shift + R to reload reactotron-macos to get connection

Step by step of how to test this PR

  1. Launch reactotron-macos - the embedded server should start automatically on port 9292
  2. Configure your React Native app to connect to port 9292
  3. Launch your React Native app and verify it connects to reactotron-macos
  4. Test the manual reconnect functionality in the sidebar menu
  5. Verify connection status is displayed correctly
  6. Test that the app properly handles disconnections and reconnections

Screenshot/Video of "How to test this PR?"

Screen.Recording.2025-10-09.at.4.30.05.PM.mov

@joshuayoes joshuayoes self-assigned this Oct 8, 2025
@joshuayoes joshuayoes force-pushed the reactotron-macos-server branch from 467fc16 to 02abeb7 Compare October 8, 2025 21:29
@joshuayoes joshuayoes added the enhancement New feature or request label Oct 8, 2025
@joshuayoes joshuayoes marked this pull request as draft October 8, 2025 22:26
- Introduced a bundled standalone Reactotron server that starts automatically with the macOS app.
- Added a new script to bundle the server code using esbuild.
- Updated package.json to include esbuild as a dependency.
- Enhanced README with instructions for running the server and details about the embedded server functionality.
- Updated Podfile.lock to reflect changes in dependencies.
- Minor adjustments to existing scripts and configurations for better integration.
- Added .eslintignore to exclude bundled files from linting.
- Removed Reactotron server start command from metro.config.js.
- Updated package.json to change the output format of the bundled server.
- Improved connection status handling in SidebarMenu with manual reconnect functionality.
- Enhanced logging in standalone-server.js for better connection tracking and error handling.
- Implemented reconnect logic in connectToServer.ts to manage connection attempts and status updates.
- Updated AppDelegate.mm to use the user's default shell for running commands, improving compatibility with nvm/asdf setups.
- Added new patch for reactotron-core-server to address compatibility issues.
@joshuayoes joshuayoes force-pushed the reactotron-macos-server branch from 02abeb7 to 66253d3 Compare October 8, 2025 23:05
@joshuayoes
Copy link
Collaborator Author

This doesn't work with an xcode production build yet, getting kind of weird error.

Screenshot 2025-10-08 at 4 10 44 PM

I tried npm run macos-release but it hangs forever at the moment.

@@ -0,0 +1,7 @@
diff --git a/node_modules/reactotron-core-server/dist/index.js b/node_modules/reactotron-core-server/dist/index.js
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: Fixed ESM/CJS interop issue in bundled [email protected]. The package's pre-compiled code does var mitt=require("mitt") but mitt v3 exports { default: fn } instead of the function directly. Added mitt=mitt.default||mitt; after the require to handle both cases.

This patch is here for hacking but we can replace with a real upstream fix soon.

Copy link
Member

@jamonholmgren jamonholmgren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some things to consider


#pragma mark - Reactotron Server Management

- (NSString *)findNodeBinary
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider moving this into a TurboModule function so we can call it from JS whenever we want to.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm doing a little research about how to move this logic into IRRunShellCommand.

- Enhanced logging to indicate detected user shell and fallback behavior.
- Added NSLog statements for better visibility during shell detection process.
…logging

- Introduced a constant for the Reactotron server bundle name to enhance code readability.
- Simplified logging logic in the output handler to reduce unnecessary checks.
- Simplified the logging logic in the output and error handlers by removing unnecessary length checks.
- Enhanced readability by using early returns for empty data conditions.
Comment on lines 21 to 23
struct passwd *pw = getpwuid(getuid());
if (pw && pw->pw_shell) {
NSString *detectedShell = [NSString stringWithUTF8String:pw->pw_shell];
Copy link
Collaborator Author

@joshuayoes joshuayoes Oct 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: apparently there is a default shell property on the user password struct? Old OS library code is weird.

- Added a new hook, useReactotronServer, to manage the lifecycle of the Reactotron server, starting it on component mount and stopping it on unmount.
- Introduced IRReactotronServer and NativeIRReactotronServer to handle server interactions.
- Enhanced IRRunShellCommand to support user shell detection and command execution with shell options.
- Updated App.tsx to utilize the new Reactotron server management functionality.
- Improved logging for server output and completion events for better debugging.
/**
* Returns the path to the bundled Reactotron server script.
*/
- (NSString *)getBundlePath {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: since metro doesn't touch the server bundle, unfortunately this needs to be a native module :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Figure out how to make it JustWork™ instead of running a packager and a server

2 participants