← Blog

BLOG

CDP Firefox: What Works, What Doesn't, and How to Connect

CDP Firefox support is limited. Learn how Playwright and Selenium connect to Firefox, and when to use hosted Chromium instead.

September 6, 20267 min readRemote Browser

# CDP Firefox: What Works, What Doesn't, and How to Connect

If you're searching for "CDP Firefox," you've likely hit a wall: you want to drive Firefox programmatically, but the Chrome DevTools Protocol (CDP) wasn't designed for it. This guide explains the current state of CDP Firefox support, how Playwright and Selenium handle Firefox connections, and why most production automation stacks—including AI agents—end up on hosted Chromium instead.

The Short Answer: Firefox Doesn't Speak CDP Natively

CDP is a Chromium-specific protocol. Firefox does not implement it. When you see references to "Firefox CDP," they usually mean one of three things:

  1. Playwright's Firefox support — which uses the Marionette protocol under the hood, not CDP.
  2. Selenium's GeckoDriver — which also uses Marionette.
  3. A compatibility layer — like the now-deprecated Firefox CDP extension that Mozilla briefly experimented with.

The practical implication: if your tooling expects a CDP endpoint (e.g., connectOverCDP in Playwright), it will not work with Firefox out of the box.

Playwright and Firefox: What the Docs Actually Say

Playwright's browserType.connectOverCDP() method is explicitly documented as Chromium-only. The official Playwright documentation states that this method connects to an existing browser instance that was launched with a CDP endpoint. Firefox does not expose such an endpoint.

Here's what happens when you try to connect to Firefox via CDP in Playwright:

import { chromium, firefox } from 'playwright';

// This works — Chromium exposes CDP
const chromiumBrowser = await chromium.connectOverCDP('http://localhost:9222');

// This will NOT work — Firefox has no CDP endpoint
// const firefoxBrowser = await firefox.connectOverCDP('http://localhost:9222');

// Correct approach for Firefox: use the native protocol
const firefoxBrowser = await firefox.launch({
  headless: true
});

The TypeScript example above highlights the core issue: connectOverCDP is a Chromium-only feature. If you need to attach to an already-running Firefox instance, you're limited to Marionette-based tooling or WebDriver BiDi.

Selenium and Firefox: The Marionette Path

Selenium's Firefox support runs through GeckoDriver, which communicates with Firefox via the Marionette protocol. This works well for standard WebDriver commands but does not give you CDP-level access to features like:

  • Network interception at the protocol level
  • Detailed performance tracing
  • Direct JavaScript runtime inspection
  • Chrome DevTools panel features

If your automation depends on CDP-specific capabilities—like Network.setBlockedURLs or Performance.getMetrics—you won't find equivalents in Firefox's Marionette.

WebDriver BiDi: The Cross-Browser Future

The WebDriver BiDi (Bidirectional) protocol is the W3C standard effort to unify browser automation. It aims to provide CDP-like capabilities across browsers, including Firefox. As of 2026, WebDriver BiDi support in Firefox has matured significantly, but it's still not a drop-in replacement for CDP in most existing tooling.

For teams evaluating browser automation stacks, the question isn't "which protocol is better?" It's "which protocol does my tooling support today?"

Why Production Stacks Default to Chromium

Given the CDP Firefox limitations, most production browser automation—especially for AI agents—runs on Chromium. Here's why:

CapabilityFirefox (Marionette)Chromium (CDP)
connectOverCDP supportNoYes
Network interceptionLimitedFull
Performance tracingLimitedFull
Existing tooling ecosystemSmallerExtensive (Playwright, Puppeteer, Selenium)
AI agent frameworksEmergingMature
Session persistenceVia profileVia profile + CDP

The table above isn't a knock on Firefox—it's a reflection of where the automation ecosystem has invested. Chromium's CDP became the de facto standard because it was first to expose deep browser internals programmatically.

The Real Problem: Keeping Sessions Alive Across Workers

Once you've chosen your browser engine, the next challenge is infrastructure. Running browser automation locally works for testing, but production workloads—especially AI agents—need something more.

Consider this scenario: you're running a fleet of cloud workers that each spin up a browser session. A user starts a task on Worker A, but the next interaction lands on Worker B. Without a shared browser session, you lose state, cookies, and context.

This is where a remote browser runtime becomes necessary. Instead of each worker launching its own local browser, they connect to a centralized browser session that persists independently of any single worker.

How Remote Browser Solves the Session Problem

Remote Browser provides hosted Chromium sessions that your code connects to via CDP. This means:

  • Sessions outlive workers — a browser session isn't tied to a specific cloud function or container.
  • Multiple workers can share a session — connect from different processes without losing state.
  • Profiles persist — cookies, local storage, and login states survive across connections.
  • Live debugging — watch sessions in real time through a viewer.

For AI agents that need to maintain context across multiple steps or retries, this architecture is critical. A local browser dies when the process dies. A remote browser session persists until you explicitly close it.

Practical Example: Connecting Playwright to a Remote Browser

Here's how you'd connect Playwright to a hosted Chromium session using CDP:

import { chromium } from 'playwright';

// Connect to a remote browser session via CDP
const browser = await chromium.connectOverCDP('wss://remote-browser.dev/cdp/session_abc123');

// Get the default context
const context = browser.contexts()[0];
const page = await context.newPage();

// Run your automation
await page.goto('https://example.com');
await page.fill('#search', 'CDP Firefox');
await page.click('button[type="submit"]');

// The session persists — other workers can connect to it too
console.log(await page.title());

// Don't close the browser if you want to reuse the session
// await browser.close();

The key difference from local automation: you're connecting to a session that exists in the cloud, not launching a new browser instance. This pattern enables the multi-worker, persistent-session architecture that production AI agents require.

Scaling Browser Workloads: What Breaks Locally

Teams that start with local browser automation hit predictable walls as they scale:

  1. Resource contention — each Chromium instance consumes 300-500MB of RAM. Running 50 concurrent sessions on one machine is impractical.
  2. Session loss — when a worker crashes or restarts, all browser state is lost.
  3. IP blocking — cloud provider IPs are frequently blocked by target sites.
  4. No observability — you can't see what the browser is doing unless you're physically at the machine.

A hosted browser API addresses all four. Sessions run on dedicated infrastructure, persist independently, and can be configured with proxy settings to avoid IP-based blocking.

Firefox CDP Alternatives for Specific Use Cases

If you genuinely need Firefox—perhaps for testing Firefox-specific behavior—here are your options:

  1. Use Playwright's native Firefox support — launch Firefox directly with firefox.launch(). You lose CDP features but gain Firefox rendering.
  2. Use Selenium with GeckoDriver — standard WebDriver commands work fine for most functional testing.
  3. Run Firefox in a container — if you need persistent Firefox sessions, containerize Firefox and manage the lifecycle yourself.
  4. Use WebDriver BiDi — for new projects, BiDi offers a path toward cross-browser automation without CDP.

None of these give you CDP-level access to Firefox. If your workload depends on CDP features, Chromium is the pragmatic choice.

What About AI Agents and Browser Access?

AI agents that browse the web have different requirements than traditional test suites. They need to:

  • Maintain context over long conversations
  • Handle dynamic page states
  • Navigate authentication flows
  • Recover from errors without losing progress

These requirements map directly to persistent browser sessions. A browser agent that loses its session mid-task fails. One that connects to a persistent remote session can retry, recover, and complete.

The Agent Browser pattern—where an AI model controls a browser through natural language or structured commands—depends on reliable browser infrastructure. CDP provides the control channel; a hosted runtime provides the reliability.

Production Checklist for Browser Automation

Whether you're using Playwright, Selenium, or an AI agent framework, evaluate your setup against these criteria:

  • Session persistence — can you reconnect to a browser session after a worker restart?
  • Resource isolation — does each session have dedicated resources, or do they contend?
  • Observability — can you watch a session live to debug failures?
  • IP diversity — can you route sessions through different IPs to avoid blocking?
  • Scaling model — does adding concurrency require manual infrastructure work?

If you're answering "no" to any of these, a hosted browser runtime is worth evaluating.

The Bottom Line on CDP Firefox

CDP Firefox support doesn't exist in the way most developers expect. Playwright's connectOverCDP is Chromium-only, and Selenium's Firefox path uses Marionette, not CDP. For production workloads that need deep browser control, persistent sessions, and multi-worker access, hosted Chromium via CDP is the practical standard.

If you're building AI agents or scaling browser automation, Remote Browser provides the hosted Chromium runtime that makes these patterns work. You get CDP access, persistent sessions, and the ability to connect from anywhere—without managing browser infrastructure yourself.

For teams that need Firefox specifically, plan for Marionette or WebDriver BiDi, and accept that you won't have CDP-level features. For everyone else, Chromium via CDP remains the most capable and well-supported path forward.