A development tool to explore, inspect, and diagnose your React Native apps.
—
Opens files in your editor directly from Reactotron stack traces and error reports, enabling seamless navigation from debugging information to source code.
Creates a plugin that responds to editor commands from Reactotron to open files in your development editor.
/**
* Create editor integration plugin
* @param options - Configuration options for editor integration
* @returns Plugin creator function
*/
function openInEditor(options?: OpenInEditorOptions): PluginCreator;
/**
* Configuration options for editor integration
*/
interface OpenInEditorOptions {
/** Base URL for the editor server (default: "http://localhost:8081") */
url?: string;
}Usage Examples:
import Reactotron, { openInEditor } from "reactotron-react-native";
// Basic editor integration (uses default localhost:8081)
const reactotron = Reactotron
.configure({ name: "MyApp" })
.use(openInEditor())
.connect();
// Custom editor server URL
const reactotron = Reactotron
.configure({ name: "MyApp" })
.use(openInEditor({
url: "http://localhost:3000"
}))
.connect();
// Via useReactNative
const reactotron = Reactotron
.configure({ name: "MyApp" })
.useReactNative({
editor: {
url: "http://localhost:8081"
}
})
.connect();The plugin responds to editor commands from Reactotron to open specific files at specific line numbers:
/**
* Command to open a file in the editor
*/
interface EditorOpenCommand {
type: "editor.open";
payload: {
file: string; // File path to open
lineNumber?: number; // Line number to navigate to (default: 1)
};
}The editor integration works seamlessly with error tracking:
// When an error occurs with stack trace:
// File: /Users/dev/MyApp/src/components/UserProfile.js:42:15
//
// Clicking the stack frame in Reactotron sends:
{
type: "editor.open",
payload: {
file: "/Users/dev/MyApp/src/components/UserProfile.js",
lineNumber: 42
}
}Works with network monitoring for API-related debugging:
// Network error with stack trace can be opened in editor
// Allows quick navigation to code making the failing API callThe plugin communicates with the editor server using HTTP POST requests:
/**
* HTTP request sent to editor server
*/
interface EditorRequest {
method: "POST";
url: string; // "{baseUrl}/open-stack-frame"
headers: {
"Content-Type": "application/json";
};
body: {
file: string;
lineNumber: number;
};
}// Example request
fetch("http://localhost:8081/open-stack-frame", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
file: "/path/to/source/file.js",
lineNumber: 42
})
});The default URL (http://localhost:8081) corresponds to React Native's development server, which includes built-in editor integration:
# React Native dev server automatically handles editor requests
# No additional setup required for standard React Native projectsFor custom editor server setups:
// Example Express.js editor server
const express = require('express');
const { exec } = require('child_process');
const app = express();
app.use(express.json());
app.post('/open-stack-frame', (req, res) => {
const { file, lineNumber } = req.body;
// Open file in VS Code
exec(`code -g "${file}:${lineNumber}"`, (error) => {
if (error) {
console.error('Failed to open editor:', error);
res.status(500).json({ error: 'Failed to open editor' });
} else {
res.json({ success: true });
}
});
});
app.listen(8081, () => {
console.log('Editor server running on port 8081');
});# Command line integration
code -g "/path/to/file.js:42"# WebStorm command line
webstorm --line 42 /path/to/file.js# Atom command line
atom /path/to/file.js:42# Sublime Text command line
subl /path/to/file.js:42The plugin processes editor commands through the standard Reactotron command interface:
onCommand: (command) => {
if (command.type !== "editor.open") return;
const { file, lineNumber } = command.payload;
const url = `${options.url}/open-stack-frame`;
const body = { file, lineNumber: lineNumber || 1 };
fetch(url, {
method: "POST",
body: JSON.stringify(body)
});
}The plugin includes basic error handling for failed requests:
fetch(url, { method, body: JSON.stringify(body) })
.catch(error => {
console.warn("Failed to open file in editor:", error);
});If no line number is provided, the plugin defaults to line 1:
const lineNumber = payload.lineNumber || 1;// Only enable in development
const editorConfig = __DEV__ ? { url: "http://localhost:8081" } : false;
const reactotron = Reactotron
.useReactNative({
editor: editorConfig
})
.connect();// Use environment variable for team consistency
const editorUrl = process.env.REACTOTRON_EDITOR_URL || "http://localhost:8081";
const reactotron = Reactotron
.use(openInEditor({ url: editorUrl }))
.connect();const getEditorUrl = () => {
if (process.env.NODE_ENV === 'development') {
return "http://localhost:8081";
}
if (process.env.NODE_ENV === 'staging') {
return "http://staging-editor.company.com";
}
return null; // Disable in production
};
const editorUrl = getEditorUrl();
const reactotron = Reactotron
.use(editorUrl ? openInEditor({ url: editorUrl }) : null)
.connect();Usage Best Practices:
// Safe editor integration with fallbacks
const setupEditor = () => {
if (!__DEV__) return false;
try {
return {
url: process.env.REACT_NATIVE_EDITOR_URL || "http://localhost:8081"
};
} catch (error) {
console.warn("Editor integration setup failed:", error);
return false;
}
};
const reactotron = Reactotron
.useReactNative({
editor: setupEditor()
})
.connect();Install with Tessl CLI
npx tessl i tessl/npm-reactotron-react-native