# Installation

This guide covers installing nokap and setting up Chrome on your system. You'll find instructions for installing from PyPI or from source, along with details on how nokap discovers Chrome automatically. If you're running in a container or CI environment, the platform-specific notes at the end will help you get things working smoothly.

## Requirements

nokap requires:

- **Python ≥ 3.10**
- **Chrome or Chromium** installed on the system, or `chrome-headless-shell` installed with `nokap install-chrome`

## Installing from PyPI

``` bash
pip install nokap
```

This installs nokap and its two runtime dependencies (`websockets` and `click`).

## Installing from Source

``` bash
git clone https://github.com/posit-dev/nokap.git
cd nokap
pip install -e ".[dev]"
```

The `[dev]` extra includes testing and linting tools (pytest, ruff, pyright).

## Chrome Setup

nokap uses a system-installed Chrome or Chromium browser. It doesn't bundle a browser, and it only downloads one if you ask it to with `nokap install-chrome` (see [chrome-headless-shell](#chrome-headless-shell)).

### Automatic Discovery

nokap looks for a browser in this order:

1.  The `CHROME_PATH` environment variable
2.  `chrome-headless-shell` installed by `nokap install-chrome` (the newest version, if there are several)
3.  `chrome-headless-shell` on `PATH`
4.  Platform-specific locations for Chrome, Chromium, and other Chromium-based browsers:

> **Note: Platform search paths**
>
> **macOS**
>
> - `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
> - `/Applications/Chromium.app/Contents/MacOS/Chromium`
> - `/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary`
> - `/Applications/Brave Browser.app/Contents/MacOS/Brave Browser`
> - `/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge`
>
> **Linux**
>
> Searches `PATH` for: `google-chrome`, `google-chrome-stable`, `chromium-browser`, `chromium`, `microsoft-edge`
>
> **Windows**
>
> Searches `Program Files`, `Program Files (x86)`, and `LOCALAPPDATA` for:
>
> - `Google\Chrome\Application\chrome.exe`
> - `Microsoft\Edge\Application\msedge.exe`
> - `Chromium\Application\chrome.exe`

### Manual Override

Set the `CHROME_PATH` environment variable to use a specific browser:

``` bash
export CHROME_PATH="/usr/bin/chromium-browser"
```

### chrome-headless-shell

`chrome-headless-shell` is Chrome's standalone headless build, published by the [Chrome for Testing](https://googlechromelabs.github.io/chrome-for-testing/) project. It starts faster than full Chrome and runs in places where full Chrome can't, such as the macOS sandboxes used by coding agents. Install it with:

``` bash
nokap install-chrome                 # latest stable
nokap install-chrome --version 156   # latest release of a milestone
nokap install-chrome --version 156.0.8078.80
```

Or from Python:

``` python
import nokap

path = nokap.install_chrome()
```

The browser goes into nokap's cache directory: `~/Library/Caches/nokap` on macOS, `$XDG_CACHE_HOME/nokap` (or `~/.cache/nokap`) on Linux, and `%LOCALAPPDATA%\nokap\Cache` on Windows. Set `NOKAP_CACHE_DIR` to use a different location. Once installed, nokap uses it automatically unless `CHROME_PATH` is set.

### Extra Chrome Arguments

To pass extra command-line flags to every Chrome launch (including the one behind `GT.gtsave()`, which doesn't take browser options), set `NOKAP_CHROME_ARGS`. The value is split like a shell command line:

``` bash
export NOKAP_CHROME_ARGS="--no-sandbox --lang=de"
```

These come after nokap's default flags and before any `extra_args` passed to [Chrome()](../reference/Chrome.md#nokap.Chrome).

### Sandboxed Environments

Agent sandboxes on macOS (Seatbelt-based tools such as mcp-console or the Claude Code sandbox) block things Chrome normally relies on. To render inside one:

- **Use chrome-headless-shell.** Full Chrome registers itself with LaunchServices at startup; the sandbox denies that and Chrome aborts (exit code -6, no error output). `chrome-headless-shell` doesn't register, so run `nokap install-chrome` outside the sandbox first.
- **Allow binding to localhost.** nokap talks to Chrome over a local DevTools port. In mcp-console, set `sandbox.network.allow_local_binding: true`.
- **Single-process mode is automatic.** The sandbox also denies the mach service registration that multi-process Chrome uses (`bootstrap_check_in ... Permission denied`). When nokap sees that error, it relaunches Chrome once with `--single-process`.

If a launch still fails, `nokap doctor` shows the error along with a hint about what the sandbox blocked.

### CI Environments

On Ubuntu CI runners (GitHub Actions), install Chrome with:

``` yaml
- name: Install Chrome
  uses: browser-actions/setup-chrome@v1
  with:
    chrome-version: stable
```

Or install `chrome-headless-shell` with nokap itself:

``` yaml
- name: Install chrome-headless-shell
  run: nokap install-chrome
```

## Verifying the Installation

``` python
import nokap

# Check that Chrome can be found
path = nokap.find_chrome()
print(f"Chrome found at: {path}")
```

## Dependencies

| Package | Role | Required? |
|----|----|----|
| `websockets` | Async WebSocket client for CDP | Yes (runtime) |
| `click` | CLI framework | Yes (runtime) |
| `Pillow` | Image post-processing (expand/crop) | Optional (`pip install nokap[extra]`) |

## Next Steps

nokap is now installed and Chrome is discoverable on your system. The setup is intentionally lightweight: two small runtime dependencies and a Chrome installation. Everything else (browser launch, WebSocket connection, tab management) is handled internally.

- [Quick Start](quick-start.md): Take your first screenshot

With installation complete, you're ready to capture your first screenshot. The Quick Start guide walks you through the three main input modes in under a minute.
