4 min read

browser-use: Let an AI Agent Drive a Real Browser (GitHub, Scanned)

Give an agent a real browser and let it finish the task: forms, logins, searches and multi-step flows.

browser-use repository on GitHub

browser-use is a Python library that lets a language model operate a web browser the way a person does: read the page, decide, click, type, scroll, and keep going until the task is done. It drives Chromium through Playwright, turns the page into a compact representation the model can reason about, and handles the loop of observing, acting and checking. Booking, scraping behind logins, filling in forms and comparing prices across sites are the everyday uses.

It became the default open library for browser agents within a year of release, and the code base shows it: a small core with many model integrations, examples for most tasks people ask about, and an active community. The company behind it sells a hosted browser and cloud runs; the library, MIT-licensed, runs entirely on your machine with your own model key.

🔍
Scan: clean, read the notes. Nothing malicious. The notes are about what you hand the agent: a browser session, and by default a hosted model. Dependencies are unpinned in the repository, so the vulnerability check has nothing to read.

Who it is for

Developers automating tasks that only exist behind a website, researchers who need data from pages without an API, and anyone building an assistant that has to act on the web rather than talk about it.

Getting started

1. Install the library (Python 3.11 or newer; in a uv project, uv add browser-use)

pip install browser-use

2. Put a model key in .env (a Browser Use key is optional, for their BU2 model or cloud browser)

echo 'OPENAI_API_KEY=sk-...' >> .env

3. Save this as agent.py and run it

import asyncio
from browser_use import Agent, ChatOpenAI
from dotenv import load_dotenv

load_dotenv()

async def main():
    agent = Agent(task='Find the number of stars of the browser-use repo', llm=ChatOpenAI(model='gpt-5.6-luna'))
    history = await agent.run()
    print(history.final_result())

asyncio.run(main())

Safety scan

We cloned browser-use/browser-use at commit d8110c5 on Sep 15, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • No secrets, no self-decoding code, no committed binaries.
  • Three pattern hits: bin/setup.sh installs uv from astral.sh for contributors, a constant in the beta module holds the install command for the company's separate terminal product, and one 19,000-character line in demo_mode.py is an inline SVG logo.
  • The bare-IP URLs are test cases: 8.8.8.8, 1.1.1.1, TEST-NET addresses and a 999.999.999.999 that exists to fail.
  • No lockfile is committed (uv.lock is gitignored), so pip or uv resolves current versions of playwright and the rest at install time. There is nothing for OSV to check, and nothing pinning you to an old version either.
  • Nine workflows, none using pull_request_target; 1 of 19 third-party actions pinned to a commit. Security policy, licence and contributing guide present.
  • The library can drive a browser you are logged in to. Give it its own profile and its own accounts.

What the scanner counted

CheckResult
SecretsNone found.
Suspicious code3 pattern hits found and read; every one is listed under the raw findings.
Install-time code1 installer script (one fetches and runs a remote script)
Committed binariesNone.
CI workflows9 workflows. None use pull_request_target. 18 of 19 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often github.com, cloud.browser-use.com, www.google.com, test.com. 20 URLs to a bare IP address, listed under the raw findings.
Known vulnerabilitiesNo lockfile to check: dependencies are declared as ranges, so what gets installed is whatever is current on the day.
Project hygieneHas security policy, licence file, contributing guide. Missing automated dependency updates, CodeQL.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Pattern hits (3)
WhereRuleMatch
bin/setup.sh:31download-piped-to-shellcurl -LsSf https://astral.sh/uv/install.sh | sh
browser_use/beta/service.py:91download-piped-to-shellTERMINAL_INSTALL_COMMAND = 'curl -fsSL https://browser-use.com/terminal/install.sh | sh'
browser_use/browser/demo_mode.py:485very-long-line19359 chars
URLs to bare IP addresses (20)
WhereRuleMatch
tests/ci/security/test_ip_blocking.py:25ip-literal-urlassert watchdog._is_url_allowed('http://180.1.1.1/supersafe.txt') is False
tests/ci/security/test_ip_blocking.py:26ip-literal-urlassert watchdog._is_url_allowed('https://8.8.8.8/') is False
tests/ci/security/test_ip_blocking.py:27ip-literal-urlassert watchdog._is_url_allowed('http://1.1.1.1:8080/api') is False
tests/ci/security/test_ip_blocking.py:28ip-literal-urlassert watchdog._is_url_allowed('https://142.250.185.46/search') is False
tests/ci/security/test_ip_blocking.py:29ip-literal-urlassert watchdog._is_url_allowed('http://93.184.216.34/') is False
tests/ci/security/test_ip_blocking.py:67ip-literal-urlassert watchdog._is_url_allowed('http://8.8.8.8:80/') is False
tests/ci/security/test_ip_blocking.py:68ip-literal-urlassert watchdog._is_url_allowed('https://8.8.8.8:443/') is False
tests/ci/security/test_ip_blocking.py:73ip-literal-urlassert watchdog._is_url_allowed('http://1.2.3.4/path/to/resource') is False
tests/ci/security/test_ip_blocking.py:74ip-literal-urlassert watchdog._is_url_allowed('http://5.6.7.8/api?key=value') is False
tests/ci/security/test_ip_blocking.py:75ip-literal-urlassert watchdog._is_url_allowed('https://9.10.11.12/path/to/file.html#anchor') is False
tests/ci/security/test_ip_blocking.py:85ip-literal-urlassert watchdog._is_url_allowed('http://180.1.1.1/supersafe.txt') is True
tests/ci/security/test_ip_blocking.py:88ip-literal-urlassert watchdog._is_url_allowed('http://8.8.8.8/') is True
tests/ci/security/test_ip_blocking.py:224ip-literal-urlassert watchdog._is_url_allowed('http://8.8.8.8/') is False
tests/ci/security/test_ip_blocking.py:242ip-literal-urlassert watchdog._is_url_allowed('http://8.8.8.8/') is False
tests/ci/security/test_ip_blocking.py:263ip-literal-urlassert watchdog._is_url_allowed('http://8.8.8.8/') is False
tests/ci/security/test_ip_blocking.py:316ip-literal-urlassert watchdog._is_url_allowed('http://999.999.999.999/') is True
tests/ci/security/test_ip_blocking.py:413ip-literal-urlassert watchdog._is_url_allowed('http://180.1.1.1/supersafe.txt') is True
tests/ci/security/test_ip_blocking.py:417ip-literal-urlassert watchdog._is_url_allowed('https://8.8.8.8/') is True
tests/ci/security/test_ip_blocking.py:442ip-literal-urlassert watchdog._is_url_allowed('http://8.8.8.8/') is False
tests/ci/security/test_ip_blocking.py:471ip-literal-urlassert watchdog._is_url_allowed('http://8.8.8.8/') is False
Installer scripts (1)
  • bin/setup.sh, 53 lines, fetches and runs a remote script; talks to astral.sh, github.com, redsymbol.net, www.gnu.org

By the numbers

Stars114.8K
Forks12.6K
Contributors381
Commits10.3K
Open issues133
Open pull requests297
Releases137
Latest release0.13.10
LicenceMIT
Main languagePython
Project age1 year
Last pushSep 15, 2026
Tracked files518
Lines of code142.8K
Checkout size9 MB

Lines by language: Python 110.9K, JSON 17.1K, Markdown 12.3K, YAML 1,559, Shell 374, HTML 271.

Questions

Is browser-use free?

The library is MIT-licensed and free. You pay for the model you connect, and browser agents are token-hungry because every step sends the page state to the model. The hosted Browser Use Cloud is optional and paid.

Can browser-use log in to sites for me?

Yes, and that is where care is needed. It can use a browser profile you are already logged in to, or fill in credentials you give it. Treat the agent as someone you have handed your session to: use a separate browser profile, scope the accounts it can reach, and keep an eye on what it does.

Which models work best with browser-use?

Models with strong tool use and vision do best. The maintainers' benchmarks favour the current frontier models from OpenAI, Anthropic and Google; smaller and local models work for simple tasks but lose the thread on long ones. The model is a constructor argument, so switching is one line.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.