---
name: buoy-install
description: Install Buoy in a React Native or Expo app, configure account access and supported tools, and verify the result.
---

# Install Buoy

Use this guide for React Native and Expo projects. The manual setup is https://buoy.gg/buoy/latest/docs/quick-start. Nothing in this guide needs the contents of an environment file, a browser session, or a native rebuild.

## Rules that do not bend

The user's explicit instructions outrank this section. The target project's own conventions do not.

- Install only packages named in this document. There is no `@buoy-gg/mobx`, `@buoy-gg/graphql`, or any other Buoy package you might expect. A guessed name fails to resolve and the app ends in a red screen. If a tool is not in the tables below, it does not exist.
- Never add a dependency to satisfy a Buoy tool. async-storage, reanimated and expo-image are native modules; adding one changes the user's native build. Skip the tool and say so in the report.
- Keep the diff to the install. The user reviews this as a pull request. Touch only the lines the install needs: no reformatting, no added comments, no refactors of the providers you pass through, no new helper files, no new lint or formatter configuration, no test buttons or sample requests added to the app to try a tool. Capture is confirmed by the user on the device (step 8).
- Do not read or print `.env*` files, `.npmrc`, keys, or credentials, in the project or the home directory. The env tool reads variables at runtime on the device; the package manager reads its own configuration.
- Do not stash, checkout, reset, add worktrees, or discard the user's work. Compare against the starting state with `git diff` and copies of the files you change.
- Do not commit. Leave the changes in the working tree.
- Ask the user only before: adding a native dependency, running anything that opens a browser (`npx buoy login`), changing what a production build does beyond what step 5 specifies, or when more than one app in the repo could be the target. Decide everything else from the repository and report the decision.

## 0. Scope

Check whether `@buoy-gg/core` is a dependency of the app before changing anything.

| `@buoy-gg/core` | Scope | What to do |
|---|---|---|
| absent | fresh install | every step below |
| present, current version, one mount | add tools | keep the mount, options and wiring exactly as they are; do steps 1 to 3 to find matching tools that are missing, install them at the version core is on, do step 6 for any new state tool, then steps 8 and 9 |
| present but stale, mismatched versions, or more than one mount | repair | bring every `@buoy-gg/*` package to one version, collapse to a single mount, keep the existing options and wiring, then continue as add tools |

Never mount a second `<FloatingDevTools />`. Never create a second QueryClient, store, or provider for Buoy.

## 1. Identify the app

Read the repository before deciding anything. Each row is a decision this guide needs and where its answer lives.

| Decision | Where to look | Rule |
|---|---|---|
| which workspace is the app | the `package.json` that depends on `react-native` | in a monorepo that is a workspace, never the root; if several qualify, ask which one; every install command runs against that workspace (`pnpm --filter <name> add`, `yarn workspace <name> add`, or `cd` into it) |
| package manager | the lockfile next to that `package.json` or at the repo root | `pnpm-lock.yaml` is pnpm, `yarn.lock` is yarn, `bun.lock` or `bun.lockb` is bun, `package-lock.json` is npm; `packageManager` in `package.json` wins over all of these |
| Expo or bare React Native | `expo` in dependencies and `app.json` or `app.config.*` | Expo uses `expo start` and `EXPO_PUBLIC_*` variables; bare uses `react-native start` and the app's own configuration mechanism |
| navigator and mount file | `expo-router` or `@react-navigation/native` in dependencies | Expo Router mounts in `app/_layout.tsx` or `src/app/_layout.tsx`; React Navigation and bare apps mount in the registered root component, usually `App.tsx` |
| providers the mount must sit under | the JSX around the navigator in that file | `QueryClientProvider`, Redux `Provider`, Jotai `Provider` and similar; the mount goes inside all of them (step 5) |
| which tools to install | dependencies of the app workspace against the trigger column in step 2 | a trigger dependency in another workspace does not count |
| existing Buoy state | `@buoy-gg/*` versions, existing `<FloatingDevTools` occurrences, existing `Buoy.init` | decides the scope in step 0 |

Requirements: React Native 0.70 or newer and React 18 or newer. Below either, stop and tell the user the floor. Check the selected packages' current peer requirements against the app; React Native and React version support varies by tool.

`pubspec.yaml` and no `package.json` is a Flutter app: follow https://buoy.gg/buoy/latest/docs/flutter/installation. Native Swift uses https://github.com/Buoy-gg/Buoy-Swift. For a React web project, use https://buoy.gg/buoy/latest/docs/web-preview. That guide covers explicit /web module registration, React Native Web, router adapters, and provider placement. Its browser builds are currently available from the source checkout; do not install a published native-only version or add Expo/native dependencies to a web app. The tables below describe native installations.

## 2. Select packages

Always consider this initial inspection set:

| Package | Install when the app depends on | Notes |
|---|---|---|
| `@buoy-gg/core` | always | the floating menu itself |
| `@buoy-gg/network` | always | supported global fetch/XHR capture; timing and body limits apply |
| `@buoy-gg/console` | always | captured JavaScript console messages and supported errors |
| `@buoy-gg/env` | always | runtime environment inspection; Expo static inlining limits enumeration |

Select these tools when the app already has the dependency and a compatible version:

| Package | Install when the app depends on | Notes |
|---|---|---|
| `@buoy-gg/storage` | `@react-native-async-storage/async-storage` | browse and edit persisted keys. Also reads MMKV and SecureStore once loaded, but the package imports async-storage at module top, so async-storage alone is the trigger; an MMKV-only app must skip this tool |
| `@buoy-gg/react-query` | `@tanstack/react-query` | finds the QueryClient through context; the mount must sit below the QueryClientProvider (step 5) |
| `@buoy-gg/zustand` | `zustand` | stores are not discoverable; wiring in step 6 |
| `@buoy-gg/jotai` | `jotai` | atoms are not discoverable; wiring in step 6 |
| `@buoy-gg/redux` | `@reduxjs/toolkit` and `react-redux` | auto-detects the store; requires early import for the store-creation capture path (step 6) |
| `@buoy-gg/route-events` | `expo-router` or `@react-navigation/native` | route inspector; detects the navigator itself |
| `@buoy-gg/sentry` | `@sentry/react-native` | observed Sentry envelopes and diagnostic estimates |
| `@buoy-gg/images` | `expo-image` | image loads, cache hits, sizes |
| `@buoy-gg/assets` | `expo-asset` or `expo-image` | bundled asset audit; optional expo-image enables native SVG previews |

Add these when the requested task needs them and their integration requirements are satisfied:

- `@buoy-gg/perf-monitor`: check Reanimated/Worklets requirements; CPU and memory need additional native modules and a compatible development build
- `@buoy-gg/highlight-updates`, `@buoy-gg/debug-borders`, `@buoy-gg/image-overlay`: render and layout debugging
- `@buoy-gg/events`, `@buoy-gg/time-machine`, `@buoy-gg/impersonate`: check source registration, app callbacks, and build limits
- `@buoy-gg/js-top`: inspect measured JavaScript callback time
- `@buoy-gg/ask-buoy`: Pro access and an authenticated model endpoint
- `@buoy-gg/tv-remote`, `@buoy-gg/focus-inspector`: use the TV setup guide and host requirements
- `@buoy-gg/external-sync`: only for Buoy Desktop or the MCP server (step 7)

Choose only from the packages named above; do not invent names. Do not add an unrequested native dependency merely to make a tool install. Explain skipped tools and their missing prerequisites.

## 3. Install compatible versions

Install selected packages together in the app workspace using its package manager. For an existing Buoy setup, match compatible versions and exact peer requirements, particularly @buoy-gg/license. Do not assume independent latest tags always resolve to a valid combination. Check peer warnings and the resulting dependency graph before declaring success.

Compare the manifest and lockfile with the pre-install state for newly introduced native dependencies. Preserve pre-existing dependencies when undoing an unintended addition. Do not remove packages simply because they were not direct dependencies; another workspace or transitive consumer may need them.

If the package manager blocks a build script, inspect the named script and its purpose before recommending approval. Do not approve unrelated scripts as part of the install.

## 4. Configure the account

A Free or Pro Buoy account key is required. Reuse an existing valid configuration without printing its value. Sign-in opens a browser on the user's machine, so do not run it unless the user asked for it in their prompt. Complete the code integration, then give the user this command to run from the app workspace:

```bash
npx --package=@buoy-gg/core buoy login
```

Mark account activation as pending in the report. Never report a working install before account access is verified.

For Expo, login writes EXPO_PUBLIC_BUOY_KEY to .env.local. Initialize core before rendering the menu:

```tsx
import { Buoy, FloatingDevTools } from '@buoy-gg/core';

Buoy.init({ licenseKey: process.env.EXPO_PUBLIC_BUOY_KEY });
```

For React Native CLI, login writes BUOY_KEY, but React Native does not load .env.local automatically. If the app already reads environment variables (react-native-config, a babel env plugin, a generated config module), pass the value through that. If it does not, call `Buoy.init()` with no key; the user enters the key from the menu's account screen after login prints it. Do not add a babel plugin, an env library, `@types/node`, or a hardcoded key to make `process.env` work. Do not dump environment files, keys, or credentials into logs or the final report.

## 5. Mount inside the app's providers

Keep the navigator and FloatingDevTools inside the same QueryClientProvider, Redux Provider, and other required contexts. For Expo Router, use app/_layout.tsx or src/app/_layout.tsx. For React Native CLI, use the registered app root.

This fragment uses the app's existing client and navigator. A fresh install mounts inside `__DEV__`:

```tsx
<QueryClientProvider client={queryClient}>
  <YourNavigatorOrStack />
  {__DEV__ && <FloatingDevTools />}
</QueryClientProvider>
```

Buoy also runs in TestFlight and production builds for QA and support on Pro. A team that wants that removes the `__DEV__` guard and wraps the mount in its own role check; do not make that change unless the user asked for it. In an existing setup, keep whatever production access is already configured. A user-role badge is not an authorization check.

## 6. Wire the selected tools

- Zustand: pass the same named store instances used by the app through zustandStores.
- Jotai: call watchAtoms with named atoms and the app's actual store. Use the Provider's store when the app has a custom one.
- Redux: import @buoy-gg/redux before the module that creates the store and keep Redux DevTools integration enabled. Otherwise use the documented middleware integration and understand its capture limits.
- React Query: use the app's existing QueryClientProvider, not a second QueryClient created for Buoy.
- Storage: register the app's MMKV instances and SecureStore key descriptors when needed. Do not assume all secure keys can be discovered or automatically read.
- Images: nothing to wire. Core loads the package and capture installs on import. Do not add an `@buoy-gg/images/register` import, a new entry file, or a `main` change for it.
- Env: runtime enumeration cannot recover all statically inlined Expo variables. Do not describe an empty inspector as proof the app lacks configuration.
- Impersonate, Time Machine, and Ask Buoy: follow their specific setup, permissions, and restore limits before claiming them ready.

The tables in step 2 and the list above are complete for the tools they name; do not fetch other Buoy or Expo documentation to install them. Installed packages can appear in the menu before their data source is connected.

## 7. Connect Desktop or MCP when requested

Install @buoy-gg/external-sync in the app. Desktop requires its own sign-in. MCP requires a process account and Pro access; the connected device's key does not sign that process in.

```bash
npx -y @buoy-gg/mcp@latest init
```

Run MCP initialization from the app directory and review the generated configuration. Other server entries are preserved, but the Buoy entry and generated skill can be updated. Restart or reconnect the editor's MCP client afterward.

Development address discovery depends on Metro and network reachability. Set externalSync.socketURL when needed. Release sync requires explicit enableInRelease configuration and Pro; do not enable it without authorization. Follow https://buoy.gg/buoy/latest/docs/desktop and https://buoy.gg/buoy/latest/docs/mcp.

## 8. Restart and verify

Use the existing development-server session. Restart it after installation and environment changes; do not silently launch a second server:

```bash
npx expo start --clear
```

For React Native CLI:

```bash
npx react-native start --reset-cache
```

Packages installing and files compiling is not a working install. Verification has three tiers; report each one separately, including the ones you did not perform.

Static, which you can do: run the app's existing typecheck script, or `tsc --noEmit` with the app's tsconfig when there is no script. Run lint only if a lint configuration file already exists (`expo lint` on a project without one scaffolds `eslint.config.js` and devDependencies; do not run it there). Do not add a lint or TypeScript configuration to run these; if the project has none, say so. Confirm every `@buoy-gg/*` package resolves from the app workspace and shares one version, and inspect dependency warnings. Compare `package.json` and the lockfile with the starting state for native dependencies that appeared without being asked for.

Device, which the user does: complete account setup, open Network, trigger a fresh supported HTTP request, and inspect its URL, status, and captured body. If it is absent, check cached app data, hook timing, and unsupported transports. A body can be unavailable or truncated.

Remote, only when MCP is connected and authorized: list devices and read the known request from the selected device. Do not assume a particular UI inspection capability exists on every platform or build.

## 9. Report the result

List the target workspace, installed versions, skipped tools and reasons, changed files, account-setup status, checks performed, and any exact blocking errors. Give the user the remaining device steps. Do not print keys or claim that compilation proves capture.

Account validation makes network requests. Optional development telemetry is described at https://buoy.gg/buoy/latest/docs/telemetry; disabling telemetry does not disable account validation or configured Desktop, MCP, and model-endpoint connections.
