---
title: Development Setup
description: Set up the OpenBrowse development environment.
---

## Prerequisites

- Node.js 22.13+ (required by pnpm 11)
- pnpm 11+ (the workspace uses `strictDepBuilds`, which requires pnpm 11)
- Chrome or Chromium-based browser

## Setup

```bash
git clone https://github.com/openbrowse-ai/openbrowse.git
cd openbrowse
pnpm install
```

Install runs at the root and bootstraps every workspace (`apps/extension`, `apps/docs`, `packages/connectors`).

## Running the extension

```bash
pnpm dev
```

This starts WXT in development mode for `apps/extension/` with hot reload. Load the unpacked extension from `apps/extension/.output/chrome-mv3-dev` in `chrome://extensions`.

For Firefox: `pnpm dev:firefox`.

## Running the docs site

```bash
pnpm dev:docs
```

Runs the documentation site (this site) at `http://localhost:3000`.

## Useful scripts

- `pnpm compile` — typecheck every workspace package in parallel.
- `pnpm test` — run the extension's vitest suite.
- `pnpm build` — production build for every workspace.
- `pnpm refresh:models` — re-vendor the [models.dev](https://models.dev) snapshot at `apps/extension/src/registry/models-dev/snapshot.json`. Run this when you want to pick up newly added providers/models.

## Workspace layout

```
apps/
├── extension/   — WXT Chrome extension (the product)
└── docs/        — Next.js + Fumadocs site (this site)
packages/
└── connectors/  — @openbrowse/connectors registry, shared between the two
```

## Cutting a release

Releases are driven by [Changesets](https://github.com/changesets/changesets).

1. If a PR changes user-facing behavior, run `pnpm changeset` and commit the generated `.changeset/*.md` file. See [`.changeset/README.md`](https://github.com/openbrowse-ai/openbrowse/blob/main/.changeset/README.md).
2. On every push to `main`, the **Changesets** workflow automatically opens or updates a "Version Packages" PR that bumps `apps/extension/package.json`, regenerates `apps/extension/CHANGELOG.md`, and consumes the changeset files.
3. Merging the Version Packages PR creates an `openbrowse@X.Y.Z` git tag (Changesets' workspace tag format for private packages, enabled via `privatePackages.tag` in `.changeset/config.json`).
4. After tagging, the **Changesets** workflow invokes the **Release extension** workflow (via `workflow_call`), which builds `apps/extension/.output/openbrowse-<version>-chrome.zip`, asserts the pinned manifest `key`, and updates the GitHub Release that Changesets created — renaming it to `vX.Y.Z` and attaching the zip. The docs' [Install page](/docs/overview#manual-install-current) links to `releases/latest`, so the new zip becomes the recommended manual download automatically.
5. The Chrome Web Store upload is intentionally a manual step — log into the developer dashboard and upload the exact same zip from the GitHub release as a new version of the listing.

If the build/upload step fails for an already-tagged release (e.g. flaky CI, transient outage), re-trigger via Actions → **Release extension** → Run workflow → enter the tag (e.g. `openbrowse@0.3.0`). An existing release is updated in place — name, body, and zip are refreshed.

import { Callout } from "fumadocs-ui/components/callout";

<Callout type="warn" title="Never change the manifest `key`">
  `apps/extension/wxt.config.ts` pins the extension's public key so that
  manual installs share an extension ID with the Chrome Web Store
  listing. Rotating or removing this value would orphan every existing
  user's storage (`chrome.storage`, IndexedDB, OPFS) and the Web Store
  would reject the upload anyway. Treat the field as immutable.
</Callout>
