Why CEF Beats CDP for Anti-Detection
April 2, 2026
Every major browser automation tool — Playwright, Puppeteer, Selenium, Browserbase, Browserless — controls Chrome through the Chrome DevTools Protocol (CDP). It's the same protocol that powers Chrome's developer tools. You open a WebSocket connection to the browser, send commands, read responses.
The problem: CDP is detectable. And anti-bot systems are very good at detecting it.
How sites detect CDP
When a browser is being controlled via CDP, it leaves fingerprints that JavaScript running on the page can observe:
navigator.webdriveris set totrue. Playwright and Puppeteer try to override this, but the override itself is detectable — the property descriptor changes.- Runtime artifacts. CDP injects a JavaScript runtime context for its own use. Tools like CreepJS specifically check for these extra contexts.
- Console API differences. When CDP is connected,
console.debugbehaves differently than in a normal browser. This is a known detection vector. - Notification permissions. Headless Chrome controlled via CDP reports different default permission states than a real browser.
- WebSocket connection pattern. The CDP debug WebSocket is visible at the OS level. Sophisticated detection can look for this.
- Missing browser features. Headless Chrome historically lacked certain APIs (like WebGL extensions or Bluetooth) that real Chrome exposes. The gap has narrowed but hasn't fully closed.
The stealth arms race around CDP is well-documented. Projects like puppeteer-extra-plugin-stealth patch over 10+ detection vectors. Browserbase and Browserless do similar patching. But they're playing whack-a-mole — for every artifact they hide, detection services find new ones.
This is fundamentally a losing architecture. You're using a debug protocol and then trying to hide the fact that you're using a debug protocol.
CEF: a different architecture
CEF (Chromium Embedded Framework) takes the opposite approach. Instead of controlling Chrome from the outside via a debug protocol, CEF embeds Chrome's rendering engine directly into your application's process.
There's no CDP. No WebSocket connection. No remote debugger. No navigator.webdriver. The page renders in a real Chromium instance that happens to be hosted inside Wick's process rather than in a standalone browser window.
From the perspective of JavaScript running on the page, it's a normal browser. Because it is a normal browser — just embedded.
| CDP (Playwright, etc.) | CEF (Wick Pro) | |
|---|---|---|
| Architecture | Remote control via WebSocket | Engine embedded in process |
| navigator.webdriver | Must be patched/hidden | Not set (not automated) |
| Runtime injection | Yes (CDP contexts) | None |
| Debug protocol | Always active | Not present |
| Detection surface | Large, well-documented | Minimal |
| Stealth approach | Patch over artifacts | No artifacts to patch |
The censorship circumvention parallel
This is the same lesson we learned building Lantern. National censors in China, Iran, and Russia use deep packet inspection to detect circumvention tools. Early tools tried to disguise their traffic — making VPN packets look like HTTPS, adding fake headers, randomizing packet timing.
It didn't work well. The censors kept finding new detection vectors in the disguise. The approach that worked was not disguising traffic at all, but instead using actual standard protocols. If your TLS handshake is real Chrome because you're using Chrome's actual code, there's nothing to detect.
Same principle with CEF vs CDP. Don't try to make automation look like a real browser. Use a real browser engine and remove the automation layer entirely.
What Wick does with CEF
Wick Pro embeds CEF for pages that need JavaScript rendering. The request flow:
- Wick receives a fetch request
- Cronet makes the initial HTTP request (Chrome TLS fingerprint)
- If JS rendering is needed, CEF loads the page in an embedded Chromium instance
- The rendered DOM is extracted and converted to clean markdown
- The result is returned to the agent
No CDP at any point. The page sees a normal Chromium browser with a normal TLS fingerprint, normal JavaScript environment, and no automation artifacts.
When you still need CDP
CEF is better for content extraction — fetching and rendering pages. But CDP has legitimate advantages for interactive automation: clicking buttons, filling forms, navigating multi-step workflows. If you need to drive a browser through a complex UI flow, Playwright + CDP is the right tool.
The distinction: reading the web vs acting on the web. For reading, you don't need a debug protocol. For acting, you do.
Most AI agent use cases today are reading — fetching pages, extracting content, researching. That's where CEF shines and CDP is overkill.
Try it
The free version of Wick uses Cronet (Chrome's network stack without rendering) and handles most sites. For JS-heavy sites that need rendering, Wick Pro adds CEF at $20/month.
brew tap wickproject/wick && brew install wick && wick setup
Further reading
- Why Your AI Agent Can't Read the Web — TLS fingerprinting explained
- Wick is Now on Apify — run it in the cloud without installing
- Wick 0.7: Local HTTP API — use Wick from any language