# Install the Web SDK

> Install @runbear-io/react from GitHub Packages, set it up in CI, allow its inline styles in your Content-Security-Policy, and check which features need which version.

Source: https://docs.runbear.io/api/web-sdk/install

Last updated: 2026-09-30

`@runbear-io/react` is published to **GitHub Packages**, not the public npm registry, so your package
manager needs a GitHub token to download it. This page covers that setup, what the package ships,
and the one browser policy it needs.

## What you need

- A GitHub personal access token (classic) with only the **`read:packages`** scope. Create it under
  GitHub **Settings → Developer settings → Personal access tokens → Tokens (classic)**.
- A package manager that reads `.npmrc`, such as npm or pnpm.

## Add the registry

Point the `@runbear-io` scope at GitHub Packages in your project's `.npmrc`, and read the token from
an environment variable so it never lands in your repository:

```
@runbear-io:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
```

Then add the dependency and run your package manager's install command:

```json
{
  "dependencies": {
    "@runbear-io/react": "^0.4.0"
  }
}
```

## Install in CI

In GitHub Actions, store the token as a repository secret (for example `GH_PACKAGES_TOKEN`) and let
`actions/setup-node` write the `.npmrc` for you:

```yaml
steps:
  - uses: actions/checkout@v6

  - uses: actions/setup-node@v6
    with:
      node-version: 24
      registry-url: https://npm.pkg.github.com

  - run: npm install
    env:
      NODE_AUTH_TOKEN: ${{ secrets.GH_PACKAGES_TOKEN }}
```

With `registry-url` set, `setup-node` creates an `.npmrc` that authenticates with
`NODE_AUTH_TOKEN`, so the job needs no `.npmrc` of its own. Other CI systems need the same two
lines as [Add the registry](#add-the-registry), with the token supplied as an environment variable.

## What the package ships

- **ESM only.** The package has a single ES module entry point and no CommonJS build. Import it
  from code your bundler processes.
- **React is bundled.** The widget carries its own copy of React and has no peer dependencies, so
  it works with any host framework, or none, and does not use your app's React version. The widget
  is mounted imperatively with `mount()`; the package exports no React components or hooks.
- **Types included.** The TypeScript declarations ship in the package. See [Types](/api/web-sdk/types.md).
- **Styles included.** The stylesheet is part of the JavaScript and is injected when the module is
  imported. There is no CSS file to import.

## Content-Security-Policy

**The SDK injects its stylesheet as an inline `<style>` element when the module is imported, so
your `style-src` directive must allow `'unsafe-inline'`.** A policy such as `style-src 'self'` drops
the stylesheet, and the widget renders completely unstyled.

A nonce or a hash can't help: the CSS is bundled into the JavaScript and injected at import time, so
there is no element for you to stamp and no hash that stays stable across SDK versions.

From 0.3.0, the SDK logs one console warning when its stylesheet is missing, so an unstyled widget
can be diagnosed from the browser console.

If your policy restricts other directives, also allow:

- `connect-src`: `https://api.runbear.io` in session and direct mode, or your own relay's origin in
  proxy mode;
- `img-src`: the host of `config.assistant.avatarUrl`, if you set one.

## Version support

Features arrived in these releases. The current release is 0.4.0; 0.5.0 is not yet released. The [changelog](/api/web-sdk/changelog.md) has every change.

| Version                  | What it adds                                                                                                                                                                                                                                                                  |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0.2.0                    | Session mode, the `auth` option, `SessionDeclinedError` and `RunbearApiError`                                                                                                                                                                                                 |
| 0.3.0                    | Response components `confirm` and `select`, `config.components.labels`, dark mode, and theming isolation (**breaking**: CSS variables renamed to `--runbear-*`; see [Theming](/api/web-sdk/theming.md#migrating-from-02x))                                                    |
| 0.4.0                    | The `card` response component                                                                                                                                                                                                                                                 |
| 0.5.0 (not yet released) | Mounting into a non-empty element renders the widget; a stale stored resume token no longer blocks every page load; the `Chat`, `CardProps` and chat event payload types are exported (**breaking** for code that reads the stream type: `thread.message.created` is removed) |

## Related

- [Web SDK overview](/api/web-sdk.md) and quick start
- [Authentication](/api/web-sdk/authentication.md)
- [Theming](/api/web-sdk/theming.md)
