Skip to Content

WebDriver BiDi Backend

Foxbridge supports WebDriver BiDi as an alternative backend to Juggler. BiDi is the W3C standard cross-browser automation protocol β€” it’s the future, and Firefox is the most complete implementation.

Why BiDi?

  • W3C standard β€” not a proprietary protocol like Juggler or CDP
  • Cross-browser β€” same protocol for Firefox, Chrome, Safari (eventually)
  • Future-proof β€” Playwright is expected to deprecate Juggler in favor of BiDi (~2027)
  • Built into Firefox β€” no custom patches required

How It Works

The BiDi client implements the same Backend interface as the Juggler client. It translates Juggler-style method calls to BiDi equivalents internally, so the bridge layer works unchanged:

CDP Client β†’ Bridge (speaks Juggler methods) β†’ BiDi Client β†’ BiDi WebSocket β†’ Firefox

The BiDi client handles:

Juggler MethodBiDi Equivalent
Browser.newPagebrowsingContext.create({type:"tab"})
Browser.closebrowser.close
Page.navigatebrowsingContext.navigate({context, url, wait:"complete"})
Page.reloadbrowsingContext.reload({context})
Page.screenshotbrowsingContext.captureScreenshot({context})
Page.printToPDFbrowsingContext.print({context})
Page.handleDialogbrowsingContext.handleUserPrompt({context})
Runtime.evaluatescript.evaluate({expression, target:{context}})
Runtime.callFunctionscript.callFunction({functionDeclaration, target:{context}})
Runtime.disposeObjectscript.disown({handles})
Page.dispatchMouseEventinput.performActions({actions:[pointer]})
Page.dispatchKeyEventinput.performActions({actions:[key]})

Event Translation (BiDi β†’ Juggler)

BiDi EventJuggler Event
browsingContext.contextCreatedBrowser.attachedToTarget
browsingContext.contextDestroyedBrowser.detachedFromTarget
browsingContext.loadPage.eventFired(load)
browsingContext.domContentLoadedPage.eventFired(DOMContentLoaded)
browsingContext.navigationStartedPage.navigationCommitted
browsingContext.userPromptOpenedPage.dialogOpened
script.realmCreatedRuntime.executionContextCreated
script.realmDestroyedRuntime.executionContextDestroyed
script.messageRuntime.console
network.beforeRequestSentNetwork.requestWillBeSent
network.responseCompletedNetwork.requestFinished

Usage

# Auto-launch Firefox with BiDi foxbridge --backend bidi --binary /path/to/firefox # Connect to an existing BiDi WebSocket foxbridge --backend bidi --bidi-url ws://localhost:9223/session # Custom BiDi port foxbridge --backend bidi --binary /path/to/firefox --bidi-port 9225

Key Differences from Juggler

JugglerBiDi
TransportPipe FD 3/4 (null-byte JSON)WebSocket (standard JSON)
Session modelsessionId in every messagecontext embedded in params
Execution contextsString IDsRealm IDs (string UUIDs)
EventsAlways streamingExplicit subscription required
InputImperative eventsW3C Actions API (action chains)
MaturityBattle-tested (Playwright)Maturing (W3C spec)

State Tracking

The BiDi client maintains:

  • contextMap: Juggler session ID β†’ BiDi browsing context ID
  • realmMap: BiDi realm ID β†’ browsing context ID (for session resolution)
  • subscriptions: auto-subscribe to all relevant events on Browser.enable
Last updated on