browser-use with a local model: let Ollama drive a web browser (Linux, Windows, Mac)
Before you start
- 19 min read
- 16 to run in terminal
Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#
browser-use is an open-source Python library that lets an AI model open a web browser, look at the page, then click, type and scroll to finish a task you describe in plain words, and with Ollama the model can run on your own computer instead of a paid cloud service.

Logo: the official Browser Use project (github.com/browser-use/browser-use)
This guide uses the local route: your script, the model (through Ollama) and a fresh Chromium browser all run on one machine. It suits small, supervised jobs such as reading a page or filling a form on a site you choose. It is not a safe way to hand an AI your logged-in browser: a web page can contain text that tries to give the model orders, and a small local model is easy to fool. The guide shows how to keep the browser in a small box.
| Current version | browser-use 0.13.14 (PyPI, released 26 October 2026; needs Python 3.11 or newer) |
| Licence | MIT (library). The hosted Browser Use Cloud is a separate, paid service that this guide does not use |
| Time needed | About 30 minutes plus the model download (our estimate) |
| Size on disk | Model files: 3.3 GB to 8.2 GB for the models in this guide (Ollama library). Chromium and Python packages: not documented |
| Ports | None for browser-use. Ollama listens on 11434, on 127.0.0.1 by default |
| Official docs | docs.browser-use.com and github.com/browser-use/browser-use |
At a glance:
- What it is: a Python library. You write a short script, run it, and watch a browser window work.
- Local model: through Ollama, with
ChatOllama. The model must understand screenshots (a vision model), or you must turn screenshots off. - The settings that matter: a bigger context window, a longer model timeout,
allowed_domains, and telemetry off. - Logins: a fresh browser has none. Keep it that way unless you really need them.
- Status: alive. Version 0.13.14 came out on 26 October 2026 and issues are active. The maintainers also build a separate TypeScript project; the Python library is still released.
- Honest limit: the project publishes no ranking of local models. Expect slower and less reliable runs than with a cloud model.
How it fits together#
Your script gives the task to the browser-use Agent. The Agent shows the page to the model in Ollama and carries out the answer in the browser.
Drawn from the browser-use docs (Supported Models, Browser parameters, Telemetry) and the 0.13.14 source, October 2026. Green stays on your machine; red is untrusted or leaves it.
Before you start#
You need Python 3.11 or newer (the uv tool in Step 2 can fetch it for you), Ollama, and enough memory for a model plus a browser. The docs publish no RAM or GPU minimum; the model decides most of it.
| Item | What to have | Check |
|---|---|---|
| System | Linux, Windows or macOS with a screen (the browser window opens on your desktop) | - |
| Memory | Enough for the model you pick (see the model table) plus Chromium. Not documented by the project | ollama ps after the first run |
| Ollama | Installed; port 11434 free | ollama --version |
| Python | 3.11 or newer; uv installs 3.12 if missing | uv --version after Step 2 |
Checklist:
- [ ] Ollama installed, and you know what model size your computer can hold
- [ ] A throwaway folder for this project (no secrets in it)
- [ ] No important browser sessions you expect the agent to use. It starts with an empty browser
- [ ] Ollama bound to
127.0.0.1(its default). Do not changeOLLAMA_HOSTfor this guide
Not run by DIY Lab Hub. Every command and value comes from the official docs, source files and issues listed at the end, read on 2026-10-31. Our other guides cover Ollama and which model fits your GPU.
Step 1: Install Ollama and pull a vision model#
Skip the install if Ollama already runs. The pull is the same everywhere. qwen3-vl:8b is a 6.2 GB model that accepts images (Ollama library page); pick a smaller or larger one from the model table below.
Linux#
curl -fsSL https://ollama.com/install.sh | sh ollama pull qwen3-vl:8b
Windows (PowerShell)#
Download the installer from ollama.com/download and run it. Then, in PowerShell:
ollama pull qwen3-vl:8b
Mac (Terminal)#
Download the Mac app from ollama.com/download and open it once. Then:
ollama pull qwen3-vl:8b
Check it worked. Run ollama list. The model qwen3-vl:8b is in the list. Ollama is running when ollama ps prints its column headings without an error.
Step 2: Install uv#
The browser-use README starts from uv, a fast Python project tool. It also installs a matching Python for you.
Linux#
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell)#
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Mac (Terminal)#
brew install uv
The curl command from the Linux step also works on Mac if you do not use Homebrew.
Check it worked. Open a new terminal and run uv --version. It prints a version number.
Tip: The uv installer for Windows runs a script from the internet with a relaxed execution policy for that one command. Read what you run; uv's installation page shows the exact line and also lists WinGet (
winget install --id=astral-sh.uv -e) as another way.
Step 3: Create the project, install browser-use and Chromium#
Linux#
mkdir -p ~/browser-use-lab && cd ~/browser-use-lab uv init --python 3.12 uv add browser-use uvx browser-use install
Windows (PowerShell)#
New-Item -ItemType Directory -Force $HOME\browser-use-lab | Out-Null Set-Location $HOME\browser-use-lab uv init --python 3.12 uv add browser-use uvx browser-use install
Mac (Terminal)#
Same commands as Linux:
mkdir -p ~/browser-use-lab && cd ~/browser-use-lab uv init --python 3.12 uv add browser-use uvx browser-use install
The last command installs Chromium. In the 0.13.14 source it runs Playwright's Chromium installer, and on Linux it adds --with-deps, which installs system libraries, so it can ask for your administrator password.
Check it worked. Run:
uv pip show browser-use
The output lists Name: browser-use and a Version: line (0.13.14 or newer). The same command works in PowerShell.
Step 4: Write a locked-down first agent#
One small script does the whole job. Read the settings before you run it, because each one closes a known problem (the reasons follow in the sections below).
The script is the same on every system. Only the way you create the file differs.
Linux#
cat > agent.py <<'EOF'
import os
os.environ["ANONYMIZED_TELEMETRY"] = "false" # must come BEFORE the browser_use import
import asyncio
from browser_use import Agent, Browser, BrowserProfile, ChatOllama
llm = ChatOllama(
model="qwen3-vl:8b",
ollama_options={"num_ctx": 32768}, # Ollama's default context is too small for this
timeout=600,
)
profile = BrowserProfile(
allowed_domains=["*.wikipedia.org"], # the only sites the agent may open
block_ip_addresses=True, # no raw IP addresses, no localhost
)
browser = Browser(browser_profile=profile)
async def main():
agent = Agent(
task="Open en.wikipedia.org, find the article about the Python programming language and tell me in which year it first appeared.",
llm=llm,
browser=browser,
llm_timeout=300, # default for an Ollama model is 75 seconds
max_failures=3,
)
history = await agent.run(max_steps=15)
print(history.final_result())
if __name__ == "__main__":
asyncio.run(main())
EOF
Windows (PowerShell)#
Set-Content -Path agent.py -Encoding utf8 -Value @'
import os
os.environ["ANONYMIZED_TELEMETRY"] = "false" # must come BEFORE the browser_use import
import asyncio
from browser_use import Agent, Browser, BrowserProfile, ChatOllama
llm = ChatOllama(
model="qwen3-vl:8b",
ollama_options={"num_ctx": 32768}, # Ollama's default context is too small for this
timeout=600,
)
profile = BrowserProfile(
allowed_domains=["*.wikipedia.org"], # the only sites the agent may open
block_ip_addresses=True, # no raw IP addresses, no localhost
)
browser = Browser(browser_profile=profile)
async def main():
agent = Agent(
task="Open en.wikipedia.org, find the article about the Python programming language and tell me in which year it first appeared.",
llm=llm,
browser=browser,
llm_timeout=300, # default for an Ollama model is 75 seconds
max_failures=3,
)
history = await agent.run(max_steps=15)
print(history.final_result())
if __name__ == "__main__":
asyncio.run(main())
'@
Mac (Terminal)#
Same command as Linux (create agent.py with the heredoc above).
Check it worked. Run uv run python -c "import browser_use". It prints nothing and returns to the prompt. A ModuleNotFoundError means you are outside the project folder.
Step 5: Run it and watch#
Linux#
uv run agent.py
Windows (PowerShell)#
uv run agent.py
Mac (Terminal)#
Same command as Linux:
uv run agent.py
Check it worked. A Chromium window opens, the agent works through numbered steps in the terminal, and the script prints its final answer. This is the documented behaviour (the README's own example says "The agent opens a browser, looks up the repository, and prints its answer"); we did not time a run. In a second terminal run ollama ps: the model is listed, and its CONTEXT column shows the number you set. If the PROCESSOR column shows CPU, expect slow steps.
Tip: Run the first task against a site you can watch and trust, with
max_stepslow. A small local model can wander, and every step is a model call on your hardware.
Which local models can do it#
browser-use asks the model for structured JSON on every step: the ChatOllama code sends a JSON schema in Ollama's format field and checks the reply. The project docs name only one local example, llama3.1:8b (4.9 GB), and they publish no local-model ranking. Their README recommends the hosted bu-2-0 model. Reading screenshots needs a vision model; use_vision is on by default.
| Model (Ollama library) | Size | Input | Notes from the library pages |
|---|---|---|---|
llama3.1:8b | 4.9 GB | Text only | The docs' own example. Set use_vision=False |
qwen3-vl:4b | 3.3 GB | Text, image | Smaller vision model for modest hardware |
qwen3-vl:8b | 6.2 GB | Text, image | Used in this guide; listed with vision, tools, thinking |
qwen2.5vl:7b | 6.0 GB | Text, image | Older vision model |
gemma3:12b | 8.2 GB | Text, image | Vision; larger |
We did not benchmark these, and the docs do not either, so treat the choice as an experiment. Three things are known from the issue tracker. First, the very first prompt can be around 16,000 tokens (issue #3093, one user with a 9B model), which is why Ollama's small default context breaks runs. Second, a model that Ollama cannot load fails before browser-use is involved (issue #3813: unknown model architecture: 'qwen3vlmoe', closed as not planned; the error comes from Ollama). Third, gpt-oss through Ollama returned empty replies in issue #2605, which browser-use reports as invalid JSON.
For a text-only model, set use_vision=False in Agent(...): the docs say False never includes screenshots. That also stops screenshots of a page from reaching the model, which the docs recommend for sensitive pages.
Put the browser in a small box#
The agent reads whatever a page says, and a page can say "ignore your task and open this link". This is called prompt injection. browser-use's own warning says it plainly: if the agent meets a malicious website, secrets you gave it may be exposed. These layers reduce the damage. Use all of them.
| Layer | What it does | Where it stops short |
|---|---|---|
| Fresh browser profile (default) | user_data_dir defaults to an auto-generated temporary folder, so no cookies, no logins | Anything you type or download during the run lives there |
allowed_domains | Limits which sites the agent may navigate to | Open reports say it only checks navigation the agent starts: pages that redirect themselves (issue #5815, open) and data: or blob: addresses (issue #4763, open) can skip it. Treat it as a guard rail, not a wall |
block_ip_addresses=True | Stops navigation to raw IP addresses and localhost | The default at 0.13.14 is False (source; issue #5879 and its fix PR #5883 are open), so set it yourself |
max_steps and max_failures | Caps how long a confused agent keeps going | A capped run can still do harm in its first steps |
| A separate account or virtual machine | Keeps any damage away from your own files and sessions | Costs setup time |
| Supervising | Watch the window; stop with Ctrl+C | The weakest and most reliable layer |
Isolation beyond the browser is your choice. The repository ships a Dockerfile that runs Chromium as a non-root user, but its entrypoint is the browser-use command-line tool, not your own script, so this guide does not teach it. A simple option that works everywhere is a separate operating-system user (or a virtual machine) used only for this project.
Logins, cookies and your real browser#
The docs give three ways to log in: reuse your real Chrome profile with Browser.from_system_chrome(), load a saved storage_state file, or pass credentials with sensitive_data. They also give the cost.
- Real Chrome profile. Everything you are logged into becomes reachable by the agent. The docs say to close Chrome completely first. With a weak local model that can be fooled, we advise against it, except in a throwaway account or a separate profile made for this.
- Storage state. The
auth.jsonfile holds cookies and local storage in Playwright's format. Anyone who reads the file can use the session. Keep it out of git and out of backups you share. sensitive_data. The model sees placeholder names such asx_user; the real values are put into the form after the model answers. The docs pair it withallowed_domainsanduse_vision=False. The agent prints a warning if you usesensitive_datawithoutallowed_domains.- Saved histories. If you save a run with
save_history, the README warns that page snapshots and results are saved as they were and can still contain secrets. - The command-line tool is different. Browser Use also ships a separate CLI that, by default, attaches to your running Chrome with its tabs, cookies and logins (CLI docs). This guide does not use it. If you install it for another tool, know what it can see.
Tip: If a task needs a login, make a new account with little power (read-only, no payment details) just for the agent. Never hand it your main email, bank or work account.
Security and testing#
- Telemetry. browser-use sends usage data to PostHog by default. The Telemetry docs say it may include task instructions, URLs visited, action traces, errors and final results. A local model does not change that. The script above turns it off with
ANONYMIZED_TELEMETRY=false, set before the import (issues #1584 and #1912: setting it afterwards is ignored). You can also put the variable in a.envfile and load it first withpython-dotenv. - Keep Ollama local. It binds to
127.0.0.1:11434by default (Ollama FAQ). Do not open it to your network for this project. - Secrets. A local setup needs no API key. If you add a cloud model later, keep keys in a
.envfile outside git. On Linux and Mac restrict it withchmod 600 .env. - Browser extensions. The default
enable_default_extensions=Trueloads uBlock Origin, cookie handlers and ClearURLs (docs). It is not a security setting; read the docs before changing it. - Functional test. Run Step 5. A pass means: the model answered, the browser opened only the allowed site, and
ollama psshowed the model loaded. - Block test. Change the task to ask for a site outside
allowed_domainsand confirm the agent is refused. Given the open reports above, do not rely on this for hostile pages.
Tip: Check the network side too: while a run is going, your firewall or router log is the honest record of what leaves the machine. Do not rely only on what the settings say.
Common mistakes#
Each row comes from the browser-use docs or a real GitHub issue (state as read on 2026-10-31). The AI-assistant rows are about what coding chatbots commonly get wrong with this tool.
| Mistake | Why it happens | Do this instead |
|---|---|---|
Putting "format": "json" and "stream": False into ollama_options | Copied from an Ollama example. Issue #5017 (closed) shows Invalid JSON: EOF while parsing and a model that never answers; release 0.13.9 stopped passing them through | Leave them out. ChatOllama already asks for structured output. Use num_ctx only |
| Leaving Ollama at its default context size | Ollama's default is small (4k below 24 GiB VRAM), and browser-use's first prompt can reach about 16k tokens (issue #3093) | Set ollama_options={"num_ctx": 32768} (or more) and check ollama ps |
| Leaving the model timeout at its default | The default for an Ollama model is 75 seconds in the source. Issues #3093 and #5017 show "LLM call timed out after 75/90/60 seconds" on slow hardware | Set llm_timeout (for example 300), use a smaller model, and confirm the model runs on the GPU |
Pointing ChatOllama at a custom address or an unpulled model | Issue #1819 (closed): "Failed to connect to Ollama"; the default is http://localhost:11434 | Keep the default host, run ollama pull <model>, and check ollama list |
Setting ANONYMIZED_TELEMETRY after importing browser_use | The telemetry object is created at import time (issues #1584, #1912, closed) | Set the variable before the first browser_use import, or load .env first |
Trusting allowed_domains as a hard wall | Open issues #5815 and #4763 describe page redirects and data:/blob: addresses that skip it | Combine it with a fresh profile, block_ip_addresses=True, a separate account and supervision |
Using from browser_use.llm import ChatOllama or from langchain_ollama import ChatOllama | Old examples. Issue #2734 ("invalid llm, must be from browser_use.llm") and #2242 ("ChatOllama" object has no field "ainvoke") came from this | Use from browser_use import Agent, ChatOllama as the docs show |
| AI assistants inventing settings and commands | Assistants copy older LangChain-era examples, or invent flags such as --local or a model_name= argument. The docs use ChatOllama(model=...), Browser(...), uv add browser-use and uvx browser-use install. This is our assessment from the docs and issues, not a measured test of any assistant | Check each name against the docs page or the 0.13.14 source before you run it; if the assistant cannot point to a page, treat it as a guess |
| Running a text-only model with screenshots on | use_vision defaults to True | Use a vision model, or set use_vision=False |
Tip: Make the first session boring: one trusted site,
max_steps=15, the browser window visible, and a model that fits in memory. Add complexity only after that works.
Tip: If a run wastes minutes, press Ctrl+C and read the last step in the terminal. The agent explains what it saw and what it plans; that is usually enough to see whether the model, the page or your prompt is the problem.
Troubleshooting#
| Problem | Solution |
|---|---|
Invalid JSON: EOF while parsing on every step | Remove format and stream from ollama_options; try a different model (issues #5017, #2605); update browser-use |
LLM call timed out after 75 seconds | Raise llm_timeout; use a smaller model; check ollama ps for CPU use (issue #3093) |
| The agent forgets the page or repeats itself | Context too small: raise num_ctx and confirm it in ollama ps |
Failed to connect to Ollama | Start Ollama, run ollama pull <model>, keep the default http://localhost:11434 (issue #1819) |
unknown model architecture | Ollama or llama.cpp cannot load that model; update Ollama or choose another (issue #3813) |
| Chromium does not start on Linux | Run uvx browser-use install again; it installs system libraries on Linux |
| Chrome profile will not open | Close Chrome fully before using Browser.from_system_chrome() (docs warning) |
| Telemetry message still appears | Move the os.environ line above the browser_use import |
Exact error texts#
LLM call timed out after 75 seconds. Keep your thinking and output short. This is the Agent's own message when the model takes longer than llm_timeout (issues #3093, #5017). The advice to keep thinking short is aimed at the model; for you the fix is a longer timeout or a faster model.
❌ Fatal error occurred: invalid llm, must be from browser_use.llm is the message from issue #2734. Import ChatOllama from browser_use.
1 validation error for AgentOutput Invalid JSON: EOF while parsing means the model returned empty or cut-off JSON (issues #5017, #2605).
Known bugs (open on 2026-10-31)#
- #5815:
allowed_domainsandprohibited_domainsare not checked on page-initiated navigation. - #4763:
data:andblob:addresses bypassallowed_domains. - #5879:
block_ip_addressesdefaults toFalse; fix PR #5883 is open. - #5931: the Ollama message serializer rejects remote image URLs.
Updates and backups#
Update. The release notes install a pinned version with uv add browser-use==<version>. To move to the newest version and keep everything else, uv documents:
uv lock --upgrade-package browser-use uv sync
uv lock --upgrade-package browser-use uv sync
Browser-use ships often (five releases between 4 September and 26 October 2026), and the issue tracker has open security reports. Update on a day you can test, and re-run Step 5 after.
Back up. There is no server or Docker volume. Your work is the project folder: agent.py, pyproject.toml and uv.lock. Leave out .venv (uv rebuilds it), model files (Ollama downloads them again) and any auth.json or saved history that may contain session data. On Linux and Mac:
mkdir -p ~/backups tar -czf ~/backups/browser-use-lab-$(date +%F).tar.gz -C ~ --exclude=browser-use-lab/.venv browser-use-lab
On Windows PowerShell:
New-Item -ItemType Directory -Force $HOME\backups | Out-Null Compress-Archive -Path "$HOME\browser-use-lab\agent.py","$HOME\browser-use-lab\pyproject.toml","$HOME\browser-use-lab\uv.lock" -DestinationPath "$HOME\backups\browser-use-lab-$(Get-Date -Format yyyy-MM-dd).zip"
Schedule it with cron at 03:00 on Linux and Mac, or Windows Task Scheduler. Restore test: extract into an empty folder, run uv sync, then uv run agent.py.
Performance and resources#
- Context memory. A larger
num_ctxuses more memory (Ollama's context page). Ollama's FAQ says memory scales withOLLAMA_NUM_PARALLELtimes the context length. Lower the number if the model moves to the CPU. - Many model calls. Each step sends the page text, and with vision on, a screenshot. A local model on modest hardware makes each step slow. The docs'
flash_mode=Trueskips evaluation, next goal and thinking to speed up runs, at the cost of care. - Fewer actions per step.
max_actions_per_stepdefaults to 5;max_failuresdefaults to 5. - Monitoring.
ollama psshows model size, the CPU/GPU split and the context in use. Your system's task manager shows Chromium's memory. - No figures here. The project publishes no RAM or speed numbers for local models and we took no timings.
FAQ#
Is it free? The library is free and MIT-licensed. With a local model and a local browser you pay nothing for inference; hosted browsers and cloud models are separate paid services, which this guide does not use.
Can it work without internet? The browser needs the sites you ask it to visit, so no. Model and agent run on your machine; telemetry is off in our script.
Which model should I pick? Start with the biggest vision model your memory holds comfortably. The project has no local ranking. Test one model at a time on the same simple task.
Can I give it my password? Technically yes through sensitive_data, but see the login section first. Use a low-power account on one allowed site, never your main accounts.
Is browser-use still maintained? Yes. Release 0.13.14 is from 26 October 2026. The same notes mention a separate TypeScript project built on Pi, so keep an eye on where the maintainers focus.
Can coding agents use it? The project also ships a command-line tool and a server mode for other agent tools. They are different products with different access (the CLI can attach to your running Chrome), and this guide does not cover them.
Sources#
- browser-use on GitHub (README, MIT licence, 0.13.14 source files, release 0.13.14) - read 2026-10-31
- browser-use on PyPI - read 2026-10-31
- Supported Models (Ollama) and Quickstart - read 2026-10-31
- Agent parameters and Browser parameters - read 2026-10-31
- Real Browser, Authentication and Sensitive Data - read 2026-10-31
- Telemetry and Browser Use CLI - read 2026-10-31
- Ollama context length, Ollama FAQ and the Ollama library pages for llama3.1, qwen3-vl, qwen2.5vl and gemma3 - read 2026-10-31
- uv installation and uv project sync and upgrade - read 2026-10-31
- GitHub issues in browser-use/browser-use: #5017, #3093, #3813, #2605, #1819, #2734, #2242, #1584, #1912, #5815, #4763, #5879, #5931 - read 2026-10-31
Checked against the official docs on 2026-10-31.