Event-Driven Browser Automation with Vibium
Event-driven browser automation with Vibium uses WebDriver BiDi's pushed events for auto-waiting, console capture, and reliable scripts without sleeps.
Event-driven browser automation with Vibium means the browser pushes events to your automation in real time, and Vibium reacts to them — instead of repeatedly polling and guessing. Built on the WebDriver BiDi standard, Vibium holds an open WebSocket to the browser, which streams console logs, network activity, navigation, and DOM changes as they happen. Vibium's single Go binary consumes that stream to power auto-waiting: when you call click(), it knows the moment an element becomes actionable instead of sleeping for a fixed time. You write ordinary, linear code — find(), type(), click() — while the event loop runs underneath. The payoff is reliability: scripts stop failing on slow renders and stop wasting seconds on padded sleeps. This same event foundation is what makes Vibium a natural fit for AI agents, which need to observe a page as it changes and decide what to do next.
What does "event-driven" actually mean here?
Event-driven means the browser is a source of events, and your automation responds to them rather than constantly asking "are you done yet?". Classic WebDriver was request/response: the client sent an HTTP command and waited for a single answer. There was no channel for the browser to volunteer information, so tools had to poll — fetch the DOM, check, sleep, repeat.
WebDriver BiDi changed the shape of the conversation. The client and browser keep a WebSocket open and exchange JSON in both directions. The browser can send a message nobody requested:
{"method": "log.entryAdded", "params": {"level": "error", "text": "Uncaught TypeError..."}}That single pushed message — arriving the instant a console error occurs — is the heart of the model. Vibium subscribes to events like this and uses them to drive its behavior.
How does Vibium turn events into auto-waiting?
Vibium uses the live state of the page to decide when an action is safe, so you don't write retry loops. When you ask it to click, it runs actionability checks — is the element visible, stable, enabled, and actually receiving clicks? — and only proceeds once they pass, up to a default 30-second timeout.
from vibium import browser_sync as browser
vibe = browser.launch()
vibe.go("https://example.com/dashboard")
# No sleep, no "wait for #save to appear" boilerplate.
# Vibium waits for the button to become actionable, then clicks.
vibe.find("#save").click()
vibe.quit()The contrast with fixed waits is stark. A sleep(3) is a guess: too short and the script flakes when the network is slow; too long and every run pays the tax even when the page was ready in 200ms. Reacting to the browser's actual state removes the guesswork. Learn more about the lookup side in How to find elements.
What events does the browser stream to Vibium?
Over the BiDi WebSocket, a Chromium browser can push a rich set of events. The ones that matter most for automation include:
| Event category | Examples | Why it's useful |
|---|---|---|
| Logging | log.entryAdded | Catch console errors as they happen |
| Network | request sent, response received | Know when an API call finishes |
| Navigation | navigation started/completed | Wait for real page transitions |
| Script | realm created, exceptions thrown | Detect uncaught page errors |
Because these arrive in real time, Vibium doesn't have to re-scrape the page on a timer to notice that something changed. The browser tells it.
Why does event-driven design matter for AI agents?
An AI agent driving a browser needs to observe, then act, then observe again — exactly the loop an event stream supports. A pushed console error or a completed network response gives the agent immediate, factual signal about what the page just did, instead of stale snapshots taken on a polling interval. That tight observe-act loop is part of why Vibium ships a built-in MCP server so tools like Claude Code can drive the browser and reason about live page state.
It also pairs naturally with semantic finding: an agent can read the page's structure, act on it, and let the event-driven engine handle timing. See finding elements with the accessibility tree for that side of the story.
How is this different from CDP-based tools?
Puppeteer and Playwright are also event-driven, but they ride on the Chrome DevTools Protocol — a Chrome-specific, internal protocol that changes without notice. Vibium gets the same real-time, bidirectional model from WebDriver BiDi, a W3C standard with buy-in from every major browser vendor. You get the reliability benefits of event-driven automation on a foundation that's standardized and cross-browser by design rather than tied to one vendor's internals. For a fuller side-by-side, see Vibium vs Playwright.
Next steps
Frequently asked questions
What is event-driven browser automation in Vibium?
Event-driven automation means the browser pushes events — console logs, network activity, DOM and navigation changes — to Vibium in real time over a WebDriver BiDi WebSocket, instead of Vibium repeatedly asking. Vibium reacts to those events, which is what powers reliable auto-waiting.
Does event-driven automation mean I write event listeners myself?
No. In day-to-day scripts you call simple methods like find() and click(), and Vibium's Go binary consumes browser events internally to decide when an element is ready. The event stream is the engine under the hood, not boilerplate you have to wire up by hand.
Why is an event-driven model more reliable than fixed waits?
Fixed sleeps guess how long a page needs and are either too short, causing flaky failures, or too long, wasting time. An event-driven model reacts to what the browser actually reports, so Vibium proceeds the moment an element is genuinely actionable rather than after an arbitrary delay.
Vibium is created by Jason Huggins. This is an independent tutorial — see the official Vibium site and GitHub repo for canonical docs.
Related guides
WebDriver BiDi vs CDP: What's the Difference?
WebDriver BiDi vs CDP: both are bidirectional protocols, but BiDi is a cross-browser W3C standard while CDP is Chrome-specific and vendor-controlled.
4 min read→Concepts & InternalsHow Vibium's Actionability (Auto-Wait) Works
Vibium's actionability auto-wait runs checks (visible, stable, receives events, enabled, editable) server-side in Go before each action — skip sleeps.
4 min read→Concepts & InternalsSelf-Healing Locators in Vibium, Explained
Vibium has no bolt-on self-healing locator engine — it earns resilience via semantic selectors, accessibility-tree finding, pickBest, and auto-wait.
4 min read→Concepts & InternalsSync vs Async in Vibium: How It Works Under the Hood
Sync vs async in Vibium under the hood: both clients call the same Go binary over a local WebSocket, so blocking and awaiting share one automation engine.
4 min read→