# Build and contribute

Build Nanobrowser from source, load it in Chrome or Edge, learn how it works and send your first pull request.

Nanobrowser is open source under the Apache License 2.0. The code is on [GitHub](https://github.com/nanobrowser/nanobrowser).

## Build from source

You need:

- [Node.js](https://nodejs.org/) 24 LTS, version 24.11.0 or later.
- [pnpm](https://pnpm.io/installation) 10. With `corepack enable`, pnpm switches to the version the project pins (10.34.7).

Clone and build:

```bash
git clone https://github.com/nanobrowser/nanobrowser.git
cd nanobrowser
corepack enable # skip if pnpm 10 is already installed
pnpm install
pnpm build      # builds the extension into dist/
```

### Load it in Chrome or Edge

1. Open `chrome://extensions` (in Edge, `edge://extensions`).
2. Turn on **Developer mode**.
3. Click **Load unpacked** and choose the `dist` folder.

Then set it up and use it as in the [Quickstart](https://nanobrowser.ai/docs/quickstart).

### Update your build

1. Pull the latest source with `git pull`.
2. Run `pnpm install`, then `pnpm build`.
3. On the extensions page, click the reload icon on the Nanobrowser card.

## How does it work?

Nanobrowser has three main parts.

- **The browser control layer** looks at the page, acts on it and reports what happened. It has no AI model in it, so the same input always gives the same result.
  - Each element the agent sees gets an ID tied to that exact element. If the page changes, an old ID stops working instead of pointing at something else.
  - Clicks and typing are real browser input. Before it acts, the layer checks that the element is visible, not moving, enabled and not covered.
  - Each action is sent once. The result says whether it went through, whether the page responded and whether the page reached the expected state.
  - It talks to the page only through Chrome's `chrome.debugger` API, and uses Puppeteer to keep track of the frames on a page.
- **The agent loop** runs on top of the layer. There is one agent per conversation. In each turn it calls the model once, then runs the tools the model asked for, such as a click or a page read. It stops when the task is done, when you click **Stop**, or at the [turn limit](https://nanobrowser.ai/docs/tasks#maximum-turns). Every model gets the same tools, and only vision models get screenshots. What the agent may do on its own is checked in code, outside the model, and no model can change it.
- **The test panel** lets you try the layer by hand, with no model. To open it, bind a key to the `open-test-panel` command in `chrome://extensions/shortcuts`. By default, it asks you before it runs a submit, pay or delete action, or a page script.

### Where is the code?

- `src/browser-control/`: the browser control layer.
- `src/agent/`: the agent loop, its tools and prompts.
- `src/llm/`: model providers.
- `src/side-panel/` and `src/options/`: the side panel and the settings page.
- `src/extension/`: the parts that run in the background and connect everything.

[AGENTS.md](https://github.com/nanobrowser/nanobrowser/blob/HEAD/AGENTS.md) explains the full layout, the design rules and how we work. It is also the guide for AI coding assistants.

## Development commands

```bash
pnpm dev          # development mode: rebuilds and reloads as you edit; load dist/ in Chrome
pnpm build        # release build into dist/
pnpm zip          # release build, packed as a zip file in dist-zip/
pnpm type-check   # check types
pnpm lint         # check code style and import rules
pnpm prettier     # format the code
pnpm test         # run the unit tests
```

## Run the tests

- **Unit tests:** `pnpm test`. They use Vitest and live in `__tests__/` folders under `src/`.
- **Browser tests:** run `pnpm install-chrome` once to install Chrome for Testing. Then run `pnpm autorun scenarios`. It runs the checks on local test pages, without opening a browser window.

Before you open a pull request, make sure `pnpm prettier`, `pnpm lint`, `pnpm type-check` and `pnpm test` pass. CI runs the same checks, plus a build, on every push and pull request.

## How can I contribute?

- **Share prompts and ideas** on [Discord](https://discord.gg/NN3ABHggMK).
- **Give feedback** on Discord or in [GitHub Discussions](https://github.com/nanobrowser/nanobrowser/discussions).
- **Report a bug** in [GitHub Issues](https://github.com/nanobrowser/nanobrowser/issues). Search first. Say what you did, step by step, your operating system, your browser and its version, your Nanobrowser version, and the provider and model you used. Never include API keys or passwords.
- **Send code.** Read [CONTRIBUTING.md](https://github.com/nanobrowser/nanobrowser/blob/HEAD/CONTRIBUTING.md) first. Then:
  1. Fork the repository and create a branch.
  2. Make one change per pull request.
  3. Add unit tests for pure functions, and a test page and scenario for anything that needs a browser.
  4. Open a pull request.

Read [AGENTS.md](https://github.com/nanobrowser/nanobrowser/blob/HEAD/AGENTS.md) before a larger change. Some design rules there are fixed.

## Report a security problem

Don't post it in public issues, pull requests or discussions. Report it through a [GitHub Security Advisory](https://github.com/nanobrowser/nanobrowser/security/advisories/new), so it can be fixed before it is made public. See [SECURITY.md](https://github.com/nanobrowser/nanobrowser/blob/HEAD/SECURITY.md).
