# Expo and React Native (https://docs.vitrinka.ai/qa/recorder/expo)



## Install [#install]

```bash
npx expo install @vitrinka/expo react-native-view-shot react-native-keyboard-controller
```

## Add the config plugin [#plugin]

Allowlist the build profiles that are permitted to carry the recorder.

```json
{
  "expo": {
    "plugins": [
      ["@vitrinka/expo", { "allowedProfiles": ["development"] }]
    ]
  }
}
```

## Wire Metro [#metro]

One required line. The config plugin verifies it is present, so a missing wrapper fails the build rather than silently shipping the recorder.

```js
// metro.config.js
const { withRecorderStrip } = require('@vitrinka/expo/recorder/metro');
module.exports = withRecorderStrip(config);
```

## Mount it [#mount]

The recorder mounts only on builds that explicitly set `EXPO_PUBLIC_VITRINKA_URL`. On every other build the entire recorder is stripped from the bundle at compile time.

```js
import { VitrinkaRecorderRoot } from '@vitrinka/expo/recorder';
```

## Link the device [#link]

No token is baked into a dev or TestFlight build. Tap the recorder's dot (**Link recorder**) for a short code and an **Open vitrinka** button; approve the code in vitrinka (pick the workspace when you belong to several) and the app receives a token that can only create and append to sessions there. It expires 30 days after its last use and is listed and revocable under **Settings → tokens**.

Unattended builds (a prod-backed test lane) can still carry an admin-minted **recorder key** as `EXPO_PUBLIC_VITRINKA_TOKEN` — project-pinned, session ingest only. Never a workspace token.

<Callout type="warn">
  Source-available under the Elastic License 2.0: read, use, modify and redistribute it — you may not offer it to third parties as a managed service.
</Callout>
