We recommend developing inside a VM to limit the blast radius of AI-assisted tools like Claude Code. See the setup guide for your platform:
If you prefer to develop directly on your host machine, follow the steps below.
- Go 1.21+
- Node.js 18+
git clone https://github.com/VibiumDev/vibium.git
cd vibium
make
make install-browserThis installs npm dependencies, builds clicker and the JS client, and downloads Chrome for Testing.
make # Build everything (default)
make build-go # Build clicker binary
make build-js # Build JS client
make deps # Install npm dependencies
make serve # Start proxy server on :9515
make test # Run all tests (CLI + JS + MCP)
make test-cli # Run CLI tests only
make test-js # Run JS library tests only
make test-mcp # Run MCP server tests only
make double-tap # Kill zombie Chrome/chromedriver processes
make install-browser # Download Chrome for Testing
make package # Build npm packages for publishing
make clean # Clean binaries and JS dist
make clean-packages # Clean built npm packages
make clean-cache # Clean cached Chrome for Testing
make clean-all # Clean everything
make help # Show this helpAfter building, you can test the JS client in a Node REPL:
cd clients/javascript && node --experimental-repl-await// Option 1: require (REPL-friendly)
const { browserSync } = require('./dist')
// Option 2: dynamic import (REPL with --experimental-repl-await)
const { browser } = await import('./dist/index.mjs')
// Option 3: static import (in .mjs files)
import { browser } from './dist/index.mjs'Sync example:
const { browserSync } = require('./dist')
const vibe = browserSync.launch()
vibe.go('https://example.com')
const el = vibe.find('h1')
console.log(el.text())
const shot = vibe.screenshot()
require('fs').writeFileSync('test.png', shot)
vibe.quit()Async example:
const { browser } = await import('./dist/index.mjs')
const vibe = await browser.launch()
await vibe.go('https://example.com')
const el = await vibe.find('h1')
console.log(await el.text())
const shot = await vibe.screenshot()
require('fs').writeFileSync('test.png', shot)
await vibe.quit()Clicker is the Go binary at the heart of Vibium. It handles browser lifecycle, WebDriver BiDi protocol, and will eventually expose an MCP server for AI agents.
Long-term, clicker runs silently in the background — called by JS/TS, Python, or Java client libraries. Most users won't interact with it directly.
For now, the CLI is a development and testing aid. It lets you verify browser automation works before the client libraries are built on top.
After building, the binary is at ./clicker/bin/clicker.
./clicker/bin/clicker install # Download Chrome for Testing + chromedriver
./clicker/bin/clicker paths # Show browser and cache paths
./clicker/bin/clicker version # Show version# Navigate to a URL
./clicker/bin/clicker navigate https://example.com
# Take a screenshot
./clicker/bin/clicker screenshot https://example.com -o shot.png
# Evaluate JavaScript
./clicker/bin/clicker eval https://example.com "document.title"
# Find an element
./clicker/bin/clicker find https://example.com "a"
# Click an element
./clicker/bin/clicker click https://example.com "a"
# Type into an element
./clicker/bin/clicker type https://the-internet.herokuapp.com/inputs "input" "12345"--headless # Hide the browser window (visible by default)
--wait-open 5 # Wait 5 seconds after navigation for page to load
--wait-close 3 # Keep browser open 3 seconds before closingExample:
./clicker/bin/clicker screenshot https://example.com --wait-close 5 -o shot.png- Team members: push directly to
VibiumDev/vibium - External contributors: fork the repo, push to your fork, then open a PR to
VibiumDev/vibium
See docs/local-dev-setup-mac.md for details on the fork-based workflow.