The FloatingDevTools component is the entry point for React Buoy. It renders a draggable floating button that opens a menu containing all your installed debugging tools.
Not a video — that is <FloatingDevTools /> running in your browser over a mock app. Grab the grip and drag it anywhere; it remembers where you dropped it.
import { FloatingDevTools } from "@buoy-gg/core";
function App() {
return (
<>
<YourApp />
<FloatingDevTools licenseKey="YOUR_LICENSE_KEY" />
</>
);
}
import { FloatingDevTools } from "@buoy-gg/core";
function App() {
return (
<>
<YourApp />
<FloatingDevTools licenseKey="YOUR_LICENSE_KEY" />
</>
);
}
That's it. Pass your license key as a prop and any Buoy tool packages you've installed will automatically appear in the menu. Don't have a key yet? Grab one at buoy.gg/pricing.
The floating button automatically displays your current environment based on NODE_ENV, helping your team instantly know where they are. No configuration needed.
You can override it explicitly if your environment name doesn't match NODE_ENV:
<FloatingDevTools environment="qa" />
<FloatingDevTools environment="qa" />
Supported values: "local", "dev", "staging", "qa", "prod"
When you install a Buoy tool package (like @buoy-gg/network or @buoy-gg/storage), it automatically registers itself with the floating menu. No imports, no configuration, no wiring.
npm install @buoy-gg/network
npm install @buoy-gg/network
The Network tool now appears in your menu. That's the magic of Buoy.
Need something specific to your app? Add your own tools:
import { FloatingDevTools } from "@buoy-gg/core";
const FeatureFlagTool = () => (
<View>
<Text>Toggle feature flags here</Text>
</View>
);
function App() {
return (
<FloatingDevTools
customTools={[
{
name: "Flags",
component: FeatureFlagTool,
icon: "🚩",
},
]}
/>
);
}
import { FloatingDevTools } from "@buoy-gg/core";
const FeatureFlagTool = () => (
<View>
<Text>Toggle feature flags here</Text>
</View>
);
function App() {
return (
<FloatingDevTools
customTools={[
{
name: "Flags",
component: FeatureFlagTool,
icon: "🚩",
},
]}
/>
);
}
See Custom Tools for more details on building your own debugging tools.
The floating button can be dragged anywhere on screen. It remembers its position between sessions, so it stays where your team likes it.
FloatingDevTools is also the source of truth for Buoy's other surfaces. The same tools you see in the menu sync out over a local broker, so once this is set up you can — with no extra code — also:
Just connect either one to your running app. The broker address is derived automatically from the Metro dev server that served the bundle, so physical devices reach your machine with zero config (Android over USB: run adb reverse tcp:42831 tcp:42831 once); pass socketURL in the externalSync prop only for tunnels or a broker on another machine. The current sync target and connection state show up in the menu's Settings tab under DESKTOP SYNC. Each install identifies itself with a per-device id minted on first connect, so a phone and a simulator (or a whole QA team) on the same build show up as separate devices; pass deviceName/deviceId in externalSync only to pin a label, and never the same deviceId on two devices. Sync is dev-only unless you ask for it — see release builds to profile a release build you own.
For builds that ship to non-developers — field or associate builds where the desktop dashboard is the only debugging surface — mount the tools with no on-device UI at all:
<FloatingDevTools headless />
<FloatingDevTools headless />
headless keeps every tool's sync adapter and route tracking running (so Buoy Desktop and the MCP server see the full session) but renders no floating button, dial, or overlays. requireLicense is ignored in headless mode since there is no UI to gate. Sync still follows the same rule as any other build: on in dev, and in a release build only with externalSync.enableInRelease plus a Pro license — which is exactly what a field build wants.