frame-bridge
@mhanzelka/react-frame-bridge-devtools

DevTools

A floating debug panel for React apps. Discovers all bridges registered via BridgeProvider automatically.

Peer dependencies: react ≥ 19, @headlessui/react ≥ 2, @heroicons/react ≥ 2, clsx ≥ 2.

Setup

// 1. Import styles once in your app entry point
import "@mhanzelka/react-frame-bridge-devtools/styles.css";

// 2. Add the panel anywhere in the component tree
import { BridgeConsoleDevTool } from "@mhanzelka/react-frame-bridge-devtools";

function App() {
    return (
        <>
            {/* your app */}
            {process.env.NODE_ENV === "development" && (
                <BridgeConsoleDevTool buttonPosition="bottom-right" />
            )}
        </>
    );
}

What the panel shows

Bridge Console
my-channelopen
broadcast-channel ✓48 messages0 pending
12:03:01.442→ ping{ value: 1 }
12:03:01.451← pong{ value: 2 }
12:03:08.220→ ping{ value: 3 }

BridgeConsoleDevTool props

Prop / MethodTypeDefaultDescription
buttonPosition"top-left" | "top-right" | "bottom-left" | "bottom-right"Where to place the toggle button.
offsetnumber | string | [x, y]Distance from the edge in px or CSS value.

useBridgeRegistry()

Used internally by BridgeProvider. Use this only if you create a bridge manually and want it to appear in the debug panel.

import { useBridgeRegistry } from "@mhanzelka/react-frame-bridge-devtools";

// Register a manually created bridge so it appears in the debug panel
function ManualBridgeSetup() {
    const { registerBridge } = useBridgeRegistry();

    useEffect(() => {
        const bridge = createBridge({ ... });
        const unregister = registerBridge(bridge);
        return unregister;
    }, []);
}

useBridgeRegistryState()

Returns reactive registry state. Re-renders when any registered bridge changes. Useful for building custom monitoring UIs.

import { useBridgeRegistryState } from "@mhanzelka/react-frame-bridge-devtools";

function BridgeMonitor() {
    const { bridges, clear } = useBridgeRegistryState();

    return (
        <ul>
            {bridges.map(b => (
                <li key={b.id}>
                    {b.channelName}{b.state.state}
                    <button onClick={() => clear(b.id)}>Clear log</button>
                </li>
            ))}
        </ul>
    );
}

// BridgeRegistrySnapshot shape:
// b.id            → bridge instance ID
// b.channelName   → channel name
// b.state         → BridgeStatus (same as useBridgeState())
// b.eventHistory  → BridgeObserverEvent[]