Vibium Cheat Sheet (2026)
The complete Vibium cheat sheet for 2026: install, launch, find, click, type, wait, screenshot, and MCP commands with copy-paste JavaScript and Python.
This Vibium cheat sheet is a one-page quick reference to every command you reach for daily: install, launch a browser, find and act on elements, wait, screenshot, handle dialogs and cookies, and wire up the MCP server — each with copy-paste JavaScript and Python. Vibium is a free, AI-native browser automation tool created by Jason Huggins, co-creator of Selenium and Appium. It ships as a single Go binary that auto-downloads Chrome for Testing, runs on the modern WebDriver BiDi protocol, and auto-waits before every interaction so you skip flaky sleep calls. Install it with pip install vibium or npm install vibium (current version 26.2). Throughout this sheet, JavaScript uses the sync import require('vibium/sync') and Python uses from vibium import browser_sync as browser — the synchronous style you want for scripts and learning. Bookmark this page; every table below is copy-paste ready. This site is an independent learning hub for Vibium, not its vendor.
How do I use this Vibium cheat sheet?
Use this cheat sheet the way you use any reference: find the command category you need, copy the snippet, then adapt the selector or URL. You do not read it top to bottom — you jump to a table, grab a line, and paste it into your script.
Every Vibium script follows that five-stage shape, and this page is organized in the same order. The tables move from setup through finding, acting, waiting, and capturing, then finish with dialogs, cookies, emulation, the AI-native methods, and the MCP server. If you are brand new, start with the Vibium tutorial for beginners first, then return here as your lookup sheet.
What are the install and launch commands?
Install Vibium with one command, then launch a browser in three lines. The first launch() triggers a one-time Chrome for Testing download, so give that first run a moment.
| Task | Command |
|---|---|
| Install (Python) | pip install vibium |
| Install (Node) | npm install vibium |
| Pre-download Chrome (Python) | vibium install |
| Launch browser | browser.launch() |
| Launch headless | browser.launch(headless=True) / browser.launch({ headless: true }) |
| Get default page (JS) | bro.page() |
| Close browser | bro.close() / vibe.quit() |
Here is the minimal launch in both languages. JavaScript gets the tab with bro.page(); the Python sync client puts page methods directly on the object launch() returns.
const { browser } = require("vibium/sync");
const bro = browser.launch();
const page = bro.page();
page.go("https://example.com");
bro.close();from vibium import browser_sync as browser
vibe = browser.launch()
vibe.go("https://example.com")
vibe.quit()For platform-specific setup and fixes, see the full install guide. To understand what lands on disk, read what is Vibium.
What are the navigation commands?
Navigation commands move the browser between URLs and read page-level facts. go() returns when the load event fires, so the next line runs against a loaded page.
| Command | What it does |
|---|---|
page.go(url) | Navigate to a URL, wait for load |
page.back() | Go back one entry in history |
page.forward() | Go forward one entry |
page.reload() | Reload the current page |
page.url() | Return the current URL |
page.title() | Return the document title |
page.content() | Return the full page HTML |
page.wait_for_url(pattern) | Wait until the URL matches |
page.go("https://example.com/login");
console.log(page.url()); // current URL
console.log(page.title()); // page title
page.back();
page.reload();The navigate (go) command reference covers wait-for-load states and redirect handling in depth.
How do I find elements? (selector cheat sheet)
Call page.find() with a CSS string for the common case, or pass an object (Python: keyword arguments) for semantic matching. find() returns one element and auto-waits; find_all() returns a list immediately, empty if nothing matches.
The single biggest ergonomic win over older tools is that Vibium has one find method with two signatures, and you can combine strategies in a single call.
// CSS selectors — the 80% case
page.find("#email"); // by id
page.find(".btn-primary"); // by class
page.find("input[name='q']"); // by attribute
page.find("nav a"); // descendant
// Semantic — pass an object
page.find({ role: "button", text: "Sign in" }); // role + visible text
page.find({ label: "Email" }); // by <label>
page.find({ placeholder: "Search..." }); // by placeholder
page.find({ testid: "submit" }); // by data-testid
// Multiple + chaining
page.findAll(".product"); // list, immediate
page.find(".list").find("a").first(); // scoped, then first match# Python — kwargs read cleanly
vibe.find("#email")
vibe.find(role="button", text="Sign in")
vibe.find(label="Email")
vibe.find(placeholder="Search...")
vibe.find_all(".product")This table maps every selector strategy you can pass as an object key:
| Key | Matches by | Example |
|---|---|---|
| (string) | CSS selector | find("#email") |
role | ARIA role | find({ role: "button" }) |
text | Visible text | find({ text: "Sign in" }) |
label | Form label / accessible name | find({ label: "Email" }) |
placeholder | Input placeholder | find({ placeholder: "Search" }) |
alt | Image alt text | find({ alt: "Logo" }) |
title | title attribute | find({ title: "Close" }) |
testid | data-testid attribute | find({ testid: "cart" }) |
xpath | XPath expression | find({ xpath: "//h1" }) |
Prefer roles, labels, and test IDs over brittle CSS paths — they survive redesigns. For the complete reference, see the find element command and selector best practices.
What are the element action commands?
Action commands click, type, and manipulate an element. Every one runs actionability checks first — the element is scrolled into view and confirmed present, visible, and stable before the action fires.
| Command | What it does |
|---|---|
el.click() | Click the element |
el.dblclick() | Double-click |
el.fill(value) | Clear the field, then set the value |
el.type(text) | Type characters one by one (no clear) |
el.press(key) | Press a single key or combo, e.g. "Enter" |
el.clear() | Empty the field |
el.check() / el.uncheck() | Toggle a checkbox to a known state |
el.select_option(value) | Choose a <select> option |
el.hover() | Hover the pointer over it |
el.set_files(paths) | Set files on a file input |
el.drag_to(target) | Drag onto another element |
Reach for fill() on form fields and type() when a field reacts to each keystroke (autocomplete, live search):
page.find("#email").fill("test@example.com"); // clears, sets value
page.find("#search").type("vibium"); // per-keystroke
page.find("#search").press("Enter"); // submit
page.find({ role: "button", text: "Log in" }).click();vibe.find("#email").fill("test@example.com")
vibe.find("#search").type("vibium")
vibe.find("#search").press("Enter")
vibe.find(role="button", text="Log in").click()Dig deeper in the click, type text, and clear input references. For a full end-to-end sign-in, follow automate a login with Vibium.
How do I read element state?
State methods read text, values, attributes, and visibility without changing anything. Use them for assertions and for scraping data off a page.
| Command | Returns |
|---|---|
el.text() | Text content |
el.inner_text() | Rendered (visible) text only |
el.html() | innerHTML |
el.value() | Current input value |
el.attr(name) | An attribute's value |
el.bounds() | {x, y, width, height} box |
el.is_visible() | True if visible |
el.is_enabled() | True if not disabled |
el.is_checked() | True if a checked checkbox |
const price = page.find(".price").text();
const href = page.find("a.cta").attr("href");
if (page.find("#banner").isVisible()) {
page.find("#banner .close").click();
}price = vibe.find(".price").text()
href = vibe.find("a.cta").attr("href")
if vibe.find("#banner").is_visible():
vibe.find("#banner .close").click()See get text, get attribute, and is visible for edge cases like trimming and hidden-element behavior.
What are the waiting commands?
Because Vibium auto-waits before actions, you reach for explicit waits far less than in Selenium. When you do need one, wait for a state — not a fixed number of seconds.
| Command | Waits for |
|---|---|
page.wait_for(selector) | An element to appear |
el.wait_for(state=...) | visible, hidden, attached, or detached |
page.wait_for_url(pattern) | The URL to match |
page.wait_for_load(state) | A load state (load, domcontentloaded) |
page.wait_for_function(fn) | A JS condition to become true |
page.wait(ms) | A fixed delay (discouraged) |
page.waitFor(".results"); // element appears
page.find(".spinner").waitFor({ state: "hidden" }); // element disappears
page.waitForURL("**/dashboard"); // navigation donevibe.wait_for(".results")
vibe.find(".spinner").wait_for(state="hidden")
vibe.wait_for_url("**/dashboard")Avoid wait(ms) except as a last-resort debugging hack. The wait-for-element command and waiting strategies guide explain why state-based waits beat sleeps for flake-free tests.
What are the screenshot and PDF commands?
page.screenshot() returns PNG bytes — you write them to a file yourself. Add fullPage for the whole scrollable page, or call el.screenshot() to capture just one element.
| Command | Captures |
|---|---|
page.screenshot() | The visible viewport |
page.screenshot({ fullPage: true }) | The full scrollable page |
el.screenshot() | A single element |
page.pdf() | The page as a PDF (Chromium) |
const fs = require("fs");
fs.writeFileSync("view.png", page.screenshot());
fs.writeFileSync("full.png", page.screenshot({ fullPage: true }));
fs.writeFileSync("hero.png", page.find(".hero").screenshot());with open("view.png", "wb") as f:
f.write(vibe.screenshot())
with open("full.png", "wb") as f:
f.write(vibe.screenshot(full_page=True))Screenshots are your fastest debugging tool — capture one at any failing step to see exactly what the browser saw. See the screenshot command and take a full-page screenshot for details.
How do I handle dialogs, cookies, and storage?
Native dialogs (alert, confirm, prompt) are handled through an event callback you register before the action that opens them. Cookies and storage live at the context level.
| Command | Purpose |
|---|---|
page.on_dialog(fn) | Register a dialog handler |
dialog.accept(text?) | Click OK (optionally answer a prompt) |
dialog.dismiss() | Click Cancel |
dialog.message() | Read the dialog text |
context.cookies() | List cookies |
context.set_cookies(list) | Add cookies |
context.clear_cookies() | Delete cookies |
context.add_init_script(js) | Run JS before every page load |
def handle(dialog):
print("dialog says:", dialog.message())
dialog.accept()
vibe.on_dialog(handle) # register FIRST
vibe.find("#delete").click() # then trigger itRegister the handler before the click, or the prompt will block the page unanswered. The handle alert command and get cookies command cover confirm-versus-prompt handling and cookie shapes.
What are the emulation and evaluation commands?
Emulation controls the viewport and device conditions; evaluation runs JavaScript in the page and returns a serialized result. Both are common in testing and scraping.
| Command | Purpose |
|---|---|
page.set_viewport(size) | Set the window/viewport size |
page.emulate_media(opts) | Emulate dark mode, print, etc. |
page.set_geolocation(coords) | Override geolocation |
page.evaluate(js) | Run JS in the page, return the result |
page.add_script(url_or_code) | Inject a <script> |
page.add_style(url_or_code) | Inject CSS |
page.setViewport({ width: 1280, height: 800 });
const count = page.evaluate("document.querySelectorAll('a').length");
console.log("links on page:", count);vibe.set_viewport({"width": 390, "height": 844}) # mobile
count = vibe.evaluate("document.querySelectorAll('a').length")The execute JavaScript command shows how return values are serialized and when evaluate beats a native command.
What are Vibium's AI-native commands?
Vibium's signature differentiators are page.check() and page.do() — plain-English verification and action with no Selenium or Playwright equivalent. They sit on top of the deterministic API and use find, click, and fill under the hood.
| Command | What it does |
|---|---|
page.check(claim) | Verify a plain-English claim, returns a pass/fail result |
page.do(action) | Perform a plain-English action |
// Verification — describe intent, not selectors
const result = page.check("the cart shows 0 items");
// { passed: true, reason: "...", confidence: 0.95 }
// Action — no selectors needed
page.do("close the cookie consent banner");
page.do("add the first product to the cart");result = vibe.check("user is logged in")
if result.passed:
print("logged in:", result.reason)
vibe.do("fill out the shipping form with test data")The deterministic API is for when you know the selector; the AI methods are for when you want to describe intent. They coexist. To see them driven by an assistant, read Vibium MCP with Claude Code.
How do I set up the Vibium MCP server?
Vibium bundles an MCP server, so an AI coding assistant can call it as a tool and automate the browser from plain-English instructions. Adding it is one command.
| Client | Command |
|---|---|
| Claude Code | claude mcp add vibium -- npx -y vibium mcp |
| Run MCP directly | npx -y vibium mcp |
# Claude Code
claude mcp add vibium -- npx -y vibium mcpOnce added, you ask the assistant to open a site, fill a form, or check a page, and it uses Vibium's own deterministic commands to carry it out — AI planning the steps, not blindly puppeteering. The full walkthrough, including Gemini CLI and Cursor, is in Vibium MCP with Claude Code.
Vibium vs Selenium vs Playwright: quick decision
This table is the fast decision aid; each tool has a genuine sweet spot. Vibium's pitch is the smallest first-run setup plus native AI hooks; the incumbents trade setup for broader browser reach and larger ecosystems.
| Aspect | Vibium | Selenium | Playwright |
|---|---|---|---|
| First-run setup | One binary, auto-gets Chrome | Binding + matching driver | Install + npx playwright install |
| Protocol | WebDriver BiDi (native) | WebDriver (+ BiDi) | CDP / patched browsers |
| Auto-waiting | Yes, in the engine | Manual / explicit | Yes |
| AI-native / MCP | Built-in MCP + check/do | No | No (external tooling) |
| Browsers | Chrome today | Chrome, Firefox, Safari, Edge | Chromium, Firefox, WebKit |
| Maturity | New (v1 line, 2025–26) | ~20 years, huge ecosystem | Mature, very popular |
| Languages | Python, JS/TS (more planned) | Java, C#, Python, Ruby, JS | JS/TS, Python, Java, .NET |
Choose Vibium for the fastest path to a working Chrome script or to let an AI agent drive the browser. Choose Selenium for mature, battle-tested cross-browser support across many languages. Choose Playwright for cross-browser coverage today with a large ecosystem and bundled runner.
The honest gotcha: as a young project, Vibium's browser and language coverage is still narrower than the incumbents. Read the full Vibium vs Playwright and Vibium vs Selenium breakdowns before committing a large suite.
The complete one-script reference
Everything above, assembled into one runnable script you can copy as a starting template:
const fs = require("fs");
const { browser } = require("vibium/sync");
const bro = browser.launch(); // 1. launch Chrome
const page = bro.page();
page.go("https://example.com"); // 2. navigate
page.find("#search").fill("vibium"); // 3. act
page.find({ role: "button", text: "Go" }).click();
page.waitFor(".results"); // 4. wait for state
console.log(page.find(".results").text());
fs.writeFileSync("out.png", page.screenshot()); // 5. capture
bro.close();from vibium import browser_sync as browser
vibe = browser.launch() # 1. launch
vibe.go("https://example.com") # 2. navigate
vibe.find("#search").fill("vibium") # 3. act
vibe.find(role="button", text="Go").click()
vibe.wait_for(".results") # 4. wait
print(vibe.find(".results").text())
with open("out.png", "wb") as f: # 5. capture
f.write(vibe.screenshot())
vibe.quit()Unfamiliar with a term like BiDi or actionability? The Vibium glossary defines them in plain language.
Next steps
You now have the full daily command surface in one place. Keep going with these focused guides:
- Vibium tutorial for beginners — the guided walkthrough behind this sheet
- What is Vibium? — the design and background in full
- How to install Vibium — platform-specific setup and fixes
- The find element command — every selector strategy explained
- The screenshot command — capture pages and single elements
- Automate a login with Vibium — your first real end-to-end task
- Vibium MCP with Claude Code — let an AI drive the browser
- The Page Object Model — structure scripts as they grow
- The Vibium roadmap and learning course — a structured path from here
Frequently asked questions
What is the fastest way to start a Vibium script?
Install with pip install vibium or npm install vibium, then launch a browser in three lines. In Python: from vibium import browser_sync as browser; vibe = browser.launch(); vibe.go('https://example.com'). The first launch auto-downloads Chrome for Testing, so no ChromeDriver setup is needed.
How do I find an element in Vibium?
Call page.find() with a CSS selector string for the common case, like vibe.find('#email'), or pass an object for semantic matching, like vibe.find({ role: 'button', text: 'Submit' }). find() returns one element and auto-waits until it is present, so you rarely need explicit waits.
Does Vibium auto-wait, or do I add sleeps?
Vibium auto-waits. Its Go engine runs actionability checks before every click, type, or fill, polling until the element is present, visible, stable, and able to receive the event. You almost never write sleep calls; use page.wait_for() only when you need to wait for a specific state.
What is the difference between el.fill() and el.type() in Vibium?
el.fill(value) clears the field first and sets the whole value at once, which is best for form inputs. el.type(text) sends characters one by one without clearing, which is better when a field reacts to each keystroke, such as an autocomplete or search box that filters as you type.
How do I take a screenshot in Vibium?
Call page.screenshot(), which returns PNG bytes you write to a file. In JavaScript: fs.writeFileSync('shot.png', page.screenshot()). Pass { fullPage: true } for the whole scrollable page, or call el.screenshot() to capture a single element instead of the viewport.
How do I connect Vibium to an AI assistant like Claude Code?
Vibium ships a built-in MCP server. Add it to Claude Code with claude mcp add vibium -- npx -y vibium mcp. The assistant can then open pages, find elements, fill forms, and verify results using Vibium's own deterministic commands under the hood, driven by plain-English instructions.
Vibium is created by Jason Huggins. This is an independent tutorial — see the official Vibium site and GitHub repo for canonical docs.
Related guides
Is Vibium Worth Learning in 2026?
Is Vibium worth learning in 2026? An honest breakdown of who it fits, what it costs to learn, and when to pick it over Playwright or Selenium.
14 min read→Getting StartedLearn Vibium in a Weekend
Learn Vibium in a weekend: a 2-day plan to install it, write real browser scripts, add semantic locators, wire up the MCP server, and ship a project.
14 min read→Getting StartedUnderstanding Vibium's Installed Folder Structure
What npm install vibium actually puts on disk — the package, the bundled Go binary, the auto-downloaded Chrome, and where Vibium caches everything.
1 min read→Getting StartedVibium for AI Engineers and Agent Builders
Vibium for AI engineers and agent builders: a hands-on guide to driving a browser from LLM agents via MCP, semantic finds, and the accessibility tree.
15 min read→