Browser use
CLI tool for persistent browser automation with multi-session support, featuring Chromium/Real/Remote browser modes, cookie management, JavaScript execution, and long-running automation workflows.From its SKILL.md
npx -y skills add PramodDutta/qaskills --skill browser-useAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
20.7 KB, ~4.7k tokens by cl100k_base, as published. Nobody here has run it
Browser-Use Automation Skill
You are an expert in browser automation using browser-use, a powerful CLI tool designed for persistent, multi-session browser automation. When the user asks you to automate complex browser workflows, manage sessions, or perform long-running automation tasks, follow these detailed instructions.
Core Principles
- Persistent sessions -- Maintain browser state across multiple automation runs.
- Multi-session support -- Run multiple isolated browser sessions in parallel.
- Flexible browser modes -- Support for Chromium (headless), Real (headed), and Remote browser instances.
- Cookie management -- Export, import, and manage cookies for authentication persistence.
- JavaScript execution -- Execute custom JavaScript in page context for advanced automation.
Installation
# Install via npm
npm install -g browser-use
# Or use with npx
npx browser-use --version
# Install with Python
pip install browser-use
# Verify installation
browser-use --help
Browser Modes
Chromium Mode (Default Headless)
# Launch Chromium in headless mode
browser-use start --mode chromium --headless
# With custom user data directory
browser-use start --mode chromium --user-data-dir ./browser-data
# With custom viewport
browser-use start --mode chromium --viewport 1920x1080
Real Browser Mode (Headed)
# Launch visible Chrome browser
browser-use start --mode real --browser chrome
# Launch Firefox
browser-use start --mode real --browser firefox
# Launch with specific profile
browser-use start --mode real --browser chrome --profile "Profile 1"
Remote Browser Mode
# Connect to remote Chrome DevTools Protocol
browser-use start --mode remote --cdp-url ws://localhost:9222
# Connect to Selenium Grid
browser-use start --mode remote --selenium-url http://localhost:4444/wd/hub
Session Management
Creating and Managing Sessions
# Create named session
browser-use session create --name "user-session-1" --persist
# List all sessions
browser-use session list
# Attach to existing session
browser-use session attach --name "user-session-1"
# Delete session
browser-use session delete --name "user-session-1"
# Export session state
browser-use session export --name "user-session-1" --output ./session-state.json
# Import session state
browser-use session import --input ./session-state.json --name "restored-session"
Session List Output:
{
"sessions": [
{
"name": "user-session-1",
"id": "abc123",
"created": "2024-02-12T10:00:00Z",
"lastActive": "2024-02-12T10:30:00Z",
"persistent": true,
"tabs": 3
},
{
"name": "test-session-2",
"id": "def456",
"created": "2024-02-12T11:00:00Z",
"lastActive": "2024-02-12T11:15:00Z",
"persistent": false,
"tabs": 1
}
]
}
Multi-Session Parallel Execution
# Run multiple sessions in parallel
browser-use parallel --sessions "session-1,session-2,session-3" \
--command "navigate --url https://example.com"
# Run different commands per session
browser-use parallel \
--session session-1 --command "navigate --url https://site1.com" \
--session session-2 --command "navigate --url https://site2.com" \
--session session-3 --command "navigate --url https://site3.com"
Cookie Management
Export and Import Cookies
# Export cookies from session
browser-use cookies export --session "user-session-1" --output cookies.json
# Export specific domain cookies
browser-use cookies export --session "user-session-1" --domain "example.com" --output example-cookies.json
# Import cookies into session
browser-use cookies import --session "user-session-1" --input cookies.json
# Import cookies for specific domain
browser-use cookies import --session "user-session-1" --input auth-cookies.json --domain "app.example.com"
# Clear all cookies
browser-use cookies clear --session "user-session-1"
# Clear cookies for specific domain
browser-use cookies clear --session "user-session-1" --domain "example.com"
Cookie Export Format:
{
"cookies": [
{
"name": "session_token",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"domain": ".example.com",
"path": "/",
"expires": 1707753600,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
},
{
"name": "user_preferences",
"value": "theme=dark&lang=en",
"domain": "app.example.com",
"path": "/",
"expires": 1739289600,
"httpOnly": false,
"secure": true,
"sameSite": "Strict"
}
]
}
Cookie-Based Authentication Persistence
#!/bin/bash
# auth-persist.sh - Login once, reuse session
SESSION_NAME="authenticated-user"
# Check if session exists
if browser-use session list | grep -q "$SESSION_NAME"; then
echo "Using existing authenticated session"
browser-use session attach --name "$SESSION_NAME"
else
echo "Creating new authenticated session"
browser-use session create --name "$SESSION_NAME" --persist
# Perform login
browser-use navigate --url "https://app.example.com/login"
browser-use type --selector "#email" --text "[email protected]"
browser-use type --selector "#password" --text "$PASSWORD"
browser-use click --selector "button[type='submit']"
browser-use wait --selector ".dashboard" --timeout 10000
# Export cookies for backup
browser-use cookies export --session "$SESSION_NAME" --output auth-cookies.json
echo "Session authenticated and cookies saved"
fi
# Now use authenticated session
browser-use navigate --url "https://app.example.com/dashboard"
JavaScript Execution
Execute JavaScript in Page Context
# Execute simple JavaScript
browser-use execute --script "return document.title"
# Execute with arguments
browser-use execute --script "return arguments[0] + arguments[1]" --args "[5, 10]"
# Execute and save result
browser-use execute --script "return document.querySelectorAll('.item').length" --output item-count.json
# Execute script from file
browser-use execute --script-file ./custom-script.js
Example Script File (custom-script.js):
// Extract all product data from page
const products = Array.from(document.querySelectorAll('.product-card')).map(card => {
return {
name: card.querySelector('.product-name')?.textContent.trim(),
price: card.querySelector('.product-price')?.textContent.trim(),
image: card.querySelector('.product-image')?.src,
rating: card.querySelector('.rating')?.getAttribute('data-rating'),
available: !card.querySelector('.out-of-stock')
};
});
return { products, total: products.length };
# Execute the script
browser-use execute --script-file ./extract-products.js --output products.json
Advanced JavaScript Patterns
# Wait for dynamic content with custom condition
browser-use execute --script "
return new Promise(resolve => {
const check = () => {
if (document.querySelectorAll('.loaded-item').length >= 10) {
resolve(true);
} else {
setTimeout(check, 100);
}
};
check();
});
"
# Manipulate page elements
browser-use execute --script "
document.querySelectorAll('.annoying-popup').forEach(el => el.remove());
document.body.style.backgroundColor = '#f0f0f0';
return 'Page modified';
"
# Trigger events
browser-use execute --script "
const event = new Event('custom-event');
document.dispatchEvent(event);
return 'Event triggered';
"
Navigation and Page Interaction
Advanced Navigation
# Navigate with custom headers
browser-use navigate --url "https://api.example.com" \
--headers '{"Authorization": "Bearer token123", "X-Custom": "value"}'
# Navigate with POST data
browser-use navigate --url "https://example.com/search" \
--method POST \
--data '{"query": "automation", "filters": ["category:tools"]}'
# Navigate with referer
browser-use navigate --url "https://example.com/protected" \
--referer "https://example.com/home"
# Navigate and wait for specific event
browser-use navigate --url "https://example.com" \
--wait-for-event "load"
Page Interaction Commands
# Scroll to element
browser-use scroll --selector ".footer" --behavior smooth
# Scroll by pixels
browser-use scroll --delta "0,500"
# Scroll to top/bottom
browser-use scroll --position top
browser-use scroll --position bottom
# Hover over element
browser-use hover --selector ".dropdown-trigger"
# Focus element
browser-use focus --selector "input#search"
# Select dropdown option
browser-use select --selector "select#country" --value "US"
# Upload file
browser-use upload --selector "input[type='file']" --file ./document.pdf
# Download file
browser-use download --url "https://example.com/file.pdf" --output ./downloaded.pdf
Tab Management
Multi-Tab Operations
# Open new tab
browser-use tab new --url "https://example.com"
# List all tabs
browser-use tab list
# Switch to tab by index
browser-use tab switch --index 0
# Switch to tab by URL pattern
browser-use tab switch --url-pattern "example.com"
# Close tab
browser-use tab close --index 1
# Close all tabs except current
browser-use tab close --others
# Duplicate tab
browser-use tab duplicate --index 0
Tab List Output:
{
"tabs": [
{
"index": 0,
"url": "https://example.com",
"title": "Example Domain",
"active": true
},
{
"index": 1,
"url": "https://google.com",
"title": "Google",
"active": false
}
],
"total": 2
}
Network Monitoring and Interception
Monitor Network Requests
# Start network monitoring
browser-use network start --filter "*.json"
# Navigate and capture requests
browser-use navigate --url "https://api.example.com"
# Get network log
browser-use network log --output network-requests.json
# Stop monitoring
browser-use network stop
Network Log Format:
{
"requests": [
{
"url": "https://api.example.com/users",
"method": "GET",
"status": 200,
"responseTime": 234,
"size": 1024,
"timestamp": "2024-02-12T10:30:00Z"
}
]
}
Request Interception
# Intercept and modify requests
browser-use intercept --pattern "*/api/*" \
--modify-headers '{"X-Custom-Header": "value"}' \
--modify-response-status 200
# Block specific requests
browser-use intercept --pattern "*.jpg" --block
# Mock API responses
browser-use intercept --pattern "*/api/users" \
--mock-response ./mock-users.json
TypeScript/JavaScript Integration
import { BrowserUse } from 'browser-use';
interface BrowserUseConfig {
mode: 'chromium' | 'real' | 'remote';
headless?: boolean;
viewport?: { width: number; height: number };
userDataDir?: string;
}
class BrowserAutomation {
private browser: BrowserUse;
private sessionName: string;
constructor(sessionName: string, config: BrowserUseConfig = { mode: 'chromium' }) {
this.sessionName = sessionName;
this.browser = new BrowserUse(config);
}
async start(): Promise<void> {
await this.browser.session.create({
name: this.sessionName,
persist: true,
});
}
async navigate(url: string, options?: { waitUntil?: string }): Promise<void> {
await this.browser.navigate({ url, ...options });
}
async executeScript<T>(script: string | Function, args: any[] = []): Promise<T> {
const scriptStr = typeof script === 'function' ? script.toString() : script;
const result = await this.browser.execute({
script: scriptStr,
args,
});
return result.value as T;
}
async saveAuthCookies(filepath: string): Promise<void> {
await this.browser.cookies.export({
session: this.sessionName,
output: filepath,
});
}
async loadAuthCookies(filepath: string): Promise<void> {
await this.browser.cookies.import({
session: this.sessionName,
input: filepath,
});
}
async cleanup(): Promise<void> {
await this.browser.session.delete({ name: this.sessionName });
}
}
// Usage example
async function automateWorkflow() {
const automation = new BrowserAutomation('my-workflow-session');
try {
await automation.start();
// Check if we have saved auth cookies
const cookiesExist = await fs.promises.access('./auth-cookies.json')
.then(() => true)
.catch(() => false);
if (cookiesExist) {
// Restore authenticated session
await automation.loadAuthCookies('./auth-cookies.json');
await automation.navigate('https://app.example.com/dashboard');
} else {
// Perform fresh login
await automation.navigate('https://app.example.com/login');
// ... login steps ...
await automation.saveAuthCookies('./auth-cookies.json');
}
// Execute custom JavaScript
const itemCount = await automation.executeScript<number>(() => {
return document.querySelectorAll('.item').length;
});
console.log(`Found ${itemCount} items on page`);
} finally {
await automation.cleanup();
}
}
Python Integration
import json
from browser_use import BrowserUse
class BrowserAutomation:
def __init__(self, session_name: str, mode: str = "chromium", headless: bool = True):
self.session_name = session_name
self.browser = BrowserUse(mode=mode, headless=headless)
def start(self):
self.browser.session.create(name=self.session_name, persist=True)
def navigate(self, url: str, wait_until: str = "load"):
self.browser.navigate(url=url, wait_until=wait_until)
def execute_script(self, script: str, *args):
return self.browser.execute(script=script, args=list(args))
def save_cookies(self, filepath: str):
self.browser.cookies.export(session=self.session_name, output=filepath)
def load_cookies(self, filepath: str):
self.browser.cookies.import_(session=self.session_name, input=filepath)
def cleanup(self):
self.browser.session.delete(name=self.session_name)
# Usage
def main():
automation = BrowserAutomation("my-session")
try:
automation.start()
# Try to restore session
try:
automation.load_cookies("auth-cookies.json")
automation.navigate("https://app.example.com/dashboard")
print("Restored authenticated session")
except FileNotFoundError:
# Fresh login
automation.navigate("https://app.example.com/login")
# ... perform login ...
automation.save_cookies("auth-cookies.json")
print("New session authenticated")
# Extract data with JavaScript
data = automation.execute_script("""
return Array.from(document.querySelectorAll('.data-item')).map(el => ({
id: el.dataset.id,
text: el.textContent.trim()
}));
""")
print(f"Extracted {len(data)} items")
finally:
automation.cleanup()
if __name__ == "__main__":
main()
Advanced Patterns
Long-Running Monitoring
#!/bin/bash
# monitor-site.sh - Continuous site monitoring
SESSION="monitor-session"
INTERVAL=300 # 5 minutes
browser-use session create --name "$SESSION" --persist
browser-use navigate --url "https://status.example.com"
while true; do
# Execute monitoring script
STATUS=$(browser-use execute --script "
const statusEl = document.querySelector('.status-indicator');
return {
status: statusEl.textContent,
color: getComputedStyle(statusEl).backgroundColor,
timestamp: new Date().toISOString()
};
")
echo "$(date): $STATUS" >> monitor.log
# Check for failures
if echo "$STATUS" | grep -q "down"; then
browser-use snapshot --output "failure-$(date +%s).png"
# Send alert
curl -X POST https://alerts.example.com/notify -d "$STATUS"
fi
sleep $INTERVAL
browser-use execute --script "location.reload()"
done
Parallel Session Processing
async function processMultipleAccounts(accounts: Array<{ email: string; password: string }>) {
const sessions = await Promise.all(
accounts.map(async (account, index) => {
const sessionName = `account-${index}`;
const browser = new BrowserAutomation(sessionName);
await browser.start();
await browser.navigate('https://app.example.com/login');
// Login for each account
await browser.executeScript((email: string, password: string) => {
(document.querySelector('#email') as HTMLInputElement).value = email;
(document.querySelector('#password') as HTMLInputElement).value = password;
(document.querySelector('button[type="submit"]') as HTMLButtonElement).click();
}, account.email, account.password);
// Wait for dashboard
await new Promise(resolve => setTimeout(resolve, 3000));
// Save session
await browser.saveAuthCookies(`./cookies-${index}.json`);
return browser;
})
);
return sessions;
}
Best Practices
- Use persistent sessions for workflows requiring authentication state.
- Export cookies regularly to recover from session failures.
- Name sessions descriptively to identify purpose when listing sessions.
- Clean up sessions after completion to avoid resource leaks.
- Use JavaScript execution for complex data extraction that CLI commands can't handle.
- Monitor network requests to verify API interactions and troubleshoot issues.
- Implement retry logic for transient failures in long-running automations.
- Use multi-session parallelism to process multiple accounts or sites simultaneously.
- Validate session state before critical operations to ensure authentication persists.
- Document session requirements for each automation workflow.
Anti-Patterns to Avoid
- Not cleaning up sessions -- Leads to resource exhaustion.
- Hardcoding credentials -- Use environment variables or secure vaults.
- Ignoring session expiration -- Implement cookie refresh or re-authentication.
- Over-reliance on delays -- Use event-based waiting instead of fixed sleeps.
- Single session for parallel tasks -- Creates race conditions and state conflicts.
- Not backing up cookies -- Session loss requires re-authentication.
- Ignoring network errors -- Implement proper error handling and retries.
- Mixing session contexts -- Keep sessions isolated to avoid state bleeding.
- Not validating JavaScript results -- Always check return values for expected structure.
- Running too many parallel sessions -- Respect system resources and rate limits.
Debugging and Troubleshooting
Enable Debug Mode
# Verbose logging
browser-use --debug navigate --url "https://example.com"
# Save console output
browser-use --console-output ./console.log navigate --url "https://example.com"
# Take screenshot on error
browser-use --screenshot-on-error ./errors/ navigate --url "https://example.com"
# Show DevTools
browser-use start --mode real --devtools
Session Recovery
# Check session health
browser-use session health --name "my-session"
# Recover corrupted session
browser-use session recover --name "my-session" --backup ./session-backup.json
# Force delete stuck session
browser-use session delete --name "my-session" --force
Integration with CI/CD
# .github/workflows/browser-automation.yml
name: Browser Automation Tests
on: [push, pull_request]
jobs:
automation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install browser-use
run: npm install -g browser-use
- name: Run automation tests
env:
APP_PASSWORD: ${{ secrets.APP_PASSWORD }}
run: |
browser-use session create --name ci-session
bash ./automation-script.sh
browser-use session delete --name ci-session
- name: Upload artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: failure-screenshots
path: ./screenshots/
This skill enables powerful, persistent browser automation with session management, making it ideal for long-running workflows, authenticated applications, and complex multi-step automations that AI agents need to orchestrate.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most automation workflows skills give in ~4.7k tokens
Counted across 745 of the 1,008 authors here whose files we hold, read 2026-08-07
- Write conventional commit messagesin 36 of 745, across 35 files
- Delete branches after mergein 30 of 745, across 21 files
- Make atomic commitsin 25 of 745, across 15 files
- Write minimal code to pass testsin 22 of 745, across 10 files
- Re-snapshot after navigation or DOM changesin 21 of 745, across 13 files
- Use try-catch for error handlingin 20 of 745, across 8 files
- Run tests before committingin 20 of 745, across 12 files
- Write tests before implementationin 20 of 745, across 8 files
- Configure branch protection rulesin 19 of 745, across 5 files
- Explain the why in commit messagesin 19 of 745, across 9 files
- Refactor code while tests remain greenin 19 of 745, across 6 files
- Interact with elements using refsin 19 of 745, across 11 files
Said here and by no other author read
- Maintain browser state across runs
- Run multiple isolated sessions in parallel
- Support chromium real and remote browser modes
- Export import and manage cookies for authentication persistence
- Execute custom JavaScript in page context
- Create named persistent sessions
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.