> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native SDK

> The React Native renderer SDK renders processes configured in the FlowX Designer inside a React Native app, using an imperative API.

## React Native project requirements

<Info>
  The library requires React Native **0.85.3+** with a `react` version that satisfies React Native's declared peer dependency (`^19.2.3` for `react-native@0.85.3`). Also requires Node **≥ 24.0.0** and npm **≥ 11.0.0**.
</Info>

| Platform                                         | Minimum                        | Notes                                                                                                            |
| ------------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| iOS deployment target                            | **16.4**                       | Required by Expo SDK 56 (raised from 15.1 in 55). Set in `ios/Podfile` (`platform :ios, '16.4'`).                |
| Android `minSdkVersion`                          | **24** (Android 7.0)           | Set in `android/build.gradle`. Required by RN 0.85.                                                              |
| Android `compileSdkVersion` / `targetSdkVersion` | RN 0.85 + Expo SDK 56 defaults | Don't override unless required. Set by `react-native-gradle-plugin` / `expo-root-project` after `expo prebuild`. |

<Check>
  To install the npm libraries provided by FlowX.AI you will need access to the private FlowX.AI Nexus registry. Consult your project DevOps.
</Check>

<Warning>
  `react` must satisfy React Native's published peer dependency. For `react-native@0.85.3` this is `^19.2.3`; newer RN 0.85.x patches may shift it — check with `npm view react-native@<your-version> peerDependencies`. Installing React Native via the official template (Bare CLI) or Expo SDK 56 picks a compatible `react` automatically — don't override it with a manual pin unless you have a reason.
</Warning>

## Installation

<Tabs>
  <Tab title="Bare React Native CLI">
    For new projects, bootstrap with the official React Native template so `react` and `react-native` ship as a matched pair that satisfies the peer dependency in the Warning above:

    ```bash theme={"system"}
    npx @react-native-community/cli@latest init MyApp
    cd MyApp
    ```

    For existing projects, ensure `react` already satisfies your installed `react-native`'s declared peer (`npm view react-native@<your-version> peerDependencies`) before installing the FlowX SDK.

    Then install the FlowX SDK and peers:

    ```bash theme={"system"}
    npm install \
      @flowx/react-native-sdk@<version> \
      @flowx/react-native-ui-toolkit@<version> \
      @flowx/react-native-theme@<version> \
      @flowx/core-sdk@<version> \
      @flowx/core-theme@<version> \
      @react-navigation/native \
      @react-navigation/native-stack \
      @react-navigation/elements \
      react-native-screens \
      react-native-safe-area-context \
      react-native-svg \
      react-native-enriched-markdown \
      react-native-keyboard-controller \
      react-native-reanimated \
      react-native-worklets \
      @react-native-community/datetimepicker \
      @react-native-community/slider \
      @react-native-segmented-control/segmented-control
    ```

    <Warning>
      Replace `<version>` with the correct version corresponding to your platform version.

      To find the right version, navigate to: **Release Notes → Choose your platform version → Deployment guidelines → Component versions**.
    </Warning>

    Then install iOS pods:

    ```bash theme={"system"}
    cd ios && pod install && cd ..
    ```
  </Tab>

  <Tab title="Expo (SDK 56)">
    <Info>
      Expo Go is **not** supported. `react-native-keyboard-controller`, `react-native-reanimated@4`, and `react-native-worklets` require a custom native build. Use `expo-dev-client` with EAS builds or `expo prebuild`.
    </Info>

    This SDK release targets **Expo SDK 56** (stable). Older Expo SDKs are not supported.

    | Expo SDK | Status          | React Native | React                                            | Notes                                                          |
    | -------- | --------------- | ------------ | ------------------------------------------------ | -------------------------------------------------------------- |
    | **56**   | **Recommended** | 0.85.x       | 19.2.3 (Expo SDK 56 pin; satisfies RN `^19.2.3`) | Current target. New architecture is default. iOS 16.4 minimum. |
    | 55       | Not supported   | 0.83.x       | 19.2.x                                           | Use the previous `@flowx/react-native-sdk` tag.                |
    | ≤54      | Not supported   | -            | -                                                | Missing required peers (worklets autolink, React 19 baseline). |

    Align the project to Expo SDK 56:

    ```bash theme={"system"}
    npx expo install expo --fix
    ```

    `--fix` aligns `react`, `react-native`, `react-native-reanimated`, `react-native-worklets`, `react-native-safe-area-context`, `react-native-screens`, and other Expo-tracked peers to the versions validated for the installed Expo SDK. Re-run after every Expo bump.

    Install the FlowX SDK and peers with `npx expo install` (it picks Expo-validated versions and warns on incompatibilities; use it instead of `npm install`):

    ```bash theme={"system"}
    npx expo install \
      @flowx/react-native-sdk@<version> \
      @flowx/react-native-ui-toolkit@<version> \
      @flowx/react-native-theme@<version> \
      @flowx/core-sdk@<version> \
      @flowx/core-theme@<version> \
      @react-navigation/native \
      @react-navigation/native-stack \
      @react-navigation/elements \
      react-native-screens \
      react-native-safe-area-context \
      react-native-svg \
      react-native-enriched-markdown \
      react-native-keyboard-controller \
      react-native-reanimated \
      react-native-worklets \
      @react-native-community/datetimepicker \
      @react-native-community/slider \
      @react-native-segmented-control/segmented-control \
      expo-dev-client
    ```

    <Warning>
      Replace `<version>` with the correct version corresponding to your platform version.

      To find the right version, navigate to: **Release Notes → Choose your platform version → Deployment guidelines → Component versions**.
    </Warning>

    `react`, `react-native`, `expo`, and Expo built-ins are already in a fresh Expo project - don't reinstall them. They are pinned by Expo SDK 56's compatibility matrix; let `npx expo install --fix` resolve drift instead of pinning manually.

    ### Expo SDK 56 reference versions

    These are the versions Expo SDK 56 validates. Use `npx expo install <pkg>` to install at the right pin; do not pin manually unless you must.

    | Package                                             | Expo SDK 56 expected                                                       |
    | --------------------------------------------------- | -------------------------------------------------------------------------- |
    | `expo`                                              | `~56.0.3`                                                                  |
    | `expo-dev-client`                                   | `~56.0.14`                                                                 |
    | `expo-splash-screen`                                | `~56.0.9`                                                                  |
    | `expo-status-bar`                                   | `~56.0.4`                                                                  |
    | `babel-preset-expo`                                 | `~56.0.6`                                                                  |
    | `@expo/cli`                                         | `56.1.2`                                                                   |
    | `react`                                             | `19.2.3` (Expo SDK 56 pin; satisfies `react-native@0.85.3` peer `^19.2.3`) |
    | `react-native`                                      | `0.85.3`                                                                   |
    | `react-native-reanimated`                           | `4.3.1`                                                                    |
    | `react-native-worklets`                             | `0.8.3`                                                                    |
    | `react-native-safe-area-context`                    | `~5.7.0`                                                                   |
    | `react-native-screens`                              | `4.25.1`                                                                   |
    | `react-native-svg`                                  | `15.15.4`                                                                  |
    | `react-native-enriched-markdown`                    | `0.5.0`                                                                    |
    | `react-native-keyboard-controller`                  | `1.21.6`                                                                   |
    | `@react-native-community/datetimepicker`            | `9.1.0`                                                                    |
    | `@react-native-community/slider`                    | `5.2.0`                                                                    |
    | `@react-native-segmented-control/segmented-control` | `2.5.7`                                                                    |

    Generate native projects if your Expo project does not yet have `ios/` and `android/`:

    ```bash theme={"system"}
    npx expo prebuild --clean
    ```

    Then install iOS pods:

    ```bash theme={"system"}
    cd ios && pod install && cd ..
    ```

    `pod install` is also run automatically by `npx expo run:ios` on first launch.

    ### `app.json` plugins

    Most listed native modules autolink without an Expo config plugin. The ones that benefit from one:

    ```json theme={"system"}
    {
      "expo": {
        "plugins": [
          "expo-dev-client",
          ["react-native-keyboard-controller", {}]
        ]
      }
    }
    ```

    `react-native-reanimated` and `react-native-worklets` do not need a config plugin - the Babel plugin handles them. The `@flowx/react-native-ui-toolkit` plugin is covered in the Android Material 3 section below.

    ### Local build (no EAS)

    For development on your own machine without EAS:

    ```bash theme={"system"}
    npx expo run:ios       # builds + runs on iOS simulator or device
    npx expo run:android   # builds + runs on Android emulator or device
    ```

    First invocation runs `expo prebuild` if `ios/` or `android/` are absent, then builds via Xcode / Gradle. Requires local Xcode (iOS) and Android SDK / JDK (Android).

    Useful flags:

    ```bash theme={"system"}
    npx expo run:ios --device                 # pick a connected physical device
    npx expo run:ios --configuration Release  # release build
    npx expo run:android --variant release    # release build
    npx expo run:android --device <id>        # pick device
    ```

    After the first install, start Metro separately with the dev client:

    ```bash theme={"system"}
    npx expo start --dev-client
    ```

    The installed app on the simulator or device connects to Metro automatically.

    ### EAS Build

    Add a development profile to `eas.json` with `developmentClient: true` so the artifact ships with the dev client:

    ```json theme={"system"}
    {
      "build": {
        "development": {
          "developmentClient": true,
          "distribution": "internal"
        }
      }
    }
    ```

    Then build:

    ```bash theme={"system"}
    eas build --profile development --platform ios
    eas build --profile development --platform android
    ```

    Install the resulting artifact on device. Run `npx expo start --dev-client` to connect Metro.

    ### Metro config (monorepo)

    The default Expo Metro config works in standard projects. For monorepos with symlinked workspaces, enable symlink resolution:

    ```js theme={"system"}
    // metro.config.js
    const { getDefaultConfig } = require('expo/metro-config');
    const config = getDefaultConfig(__dirname);
    config.resolver.unstable_enableSymlinks = true;
    module.exports = config;
    ```
  </Tab>
</Tabs>

<Warning>
  Some peer dependencies require additional setup beyond `npm install`: Babel plugins, Expo config plugins, native project edits (Podfile, `styles.xml`, `AndroidManifest.xml`), or app-root providers. Check each library's install guide and apply its setup steps. Examples: `react-native-worklets` needs a Babel plugin (see below), `react-native-keyboard-controller` needs an Expo config plugin in managed projects, and `react-native-screens` / `react-native-safe-area-context` rely on autolinking plus the providers shown later in this page.
</Warning>

### Babel plugin

`react-native-worklets/plugin` **must be the last plugin** in your Babel config.

<Tabs>
  <Tab title="Expo">
    No manual config needed. `babel-preset-expo` (SDK 54+) auto-adds the worklets plugin when `react-native-worklets` is in `node_modules`.

    ```js theme={"system"}
    // babel.config.js
    module.exports = function (api) {
      api.cache(true);
      return {
        presets: ['babel-preset-expo'],
      };
    };
    ```
  </Tab>

  <Tab title="Bare RN CLI">
    ```js theme={"system"}
    // babel.config.js
    module.exports = {
      presets: ['module:@react-native/babel-preset'],
      plugins: [
        'react-native-worklets/plugin',
      ],
    };
    ```
  </Tab>
</Tabs>

### Android Material 3 date picker (opt-in)

`FlxDatePicker` on Android renders the legacy AppCompat calendar by default. To use the Material 3 picker, the host app's `AppTheme` must inherit from a Material 3 parent **and** the toolkit runtime flag `material3` must be `true`. With the flag off, the legacy calendar renders and the theme change is irrelevant.

<Tabs>
  <Tab title="Expo (managed / prebuild)">
    Register the `@flowx/react-native-ui-toolkit` config plugin. It rewrites `AppTheme` to a Material 3 parent and injects `extra.flxUiToolkit.material3 = true` into the app config, so no JS opt-in is needed:

    ```json theme={"system"}
    {
      "expo": {
        "plugins": [
          "@flowx/react-native-ui-toolkit"
        ]
      }
    }
    ```

    Then run `npx expo prebuild --clean --platform android`.
  </Tab>

  <Tab title="Bare React Native CLI">
    Two steps.

    **Step 1.** Edit `android/app/src/main/res/values/styles.xml`:

    ```xml theme={"system"}
    <!-- Before -->
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
      <!-- ... -->
    </style>

    <!-- After -->
    <style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar">
      <!-- ... -->
    </style>
    ```

    **Step 2.** Opt in from JS. Pick one:

    Option A. `FlxThemeProvider` prop:

    ```tsx theme={"system"}
    import { FlxThemeProvider } from '@flowx/react-native-ui-toolkit'

    export default function App() {
      return (
        <FlxThemeProvider material3>
          {/* ... */}
        </FlxThemeProvider>
      )
    }
    ```

    Option B. Explicit call at app bootstrap (top of `index.js`):

    ```ts theme={"system"}
    import { configureFlxUiToolkit } from '@flowx/react-native-ui-toolkit'

    configureFlxUiToolkit({ material3: true })
    ```
  </Tab>
</Tabs>

<Info>
  No Gradle changes required. `com.google.android.material:material` is already on the classpath via `androidx.appcompat`. Skip both steps and `FlxDatePicker` keeps rendering the legacy calendar with no crash.
</Info>

## App-root providers

The renderer expects safe-area and keyboard providers above it in the tree:

```tsx theme={"system"}
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { KeyboardProvider } from 'react-native-keyboard-controller'

export default function App() {
  return (
    <SafeAreaProvider>
      <KeyboardProvider>
        {/* FlowX process view goes here */}
      </KeyboardProvider>
    </SafeAreaProvider>
  )
}
```

<Info>
  The SDK mounts its own `NavigationContainer` internally, wrapped in `NavigationIndependentTree`. A host `NavigationContainer` is **not** required. If your app already uses `@react-navigation/native`, keep its `NavigationContainer` at the root. The SDK's internal navigator stays isolated from it.
</Info>

## Authorization

<Info>
  The client app implements the authorization flow (using the **OpenID Connect** standard). The SDK expects a bearer token to be set via `FlowX.setAccessToken(token)` before starting a process.
</Info>

```ts theme={"system"}
import { FlowX } from '@flowx/react-native-sdk'

FlowX.setAccessToken(accessToken)
```

Call `setAccessToken` again whenever the token is refreshed.

## Configuring the SDK

`FlowX.configure(cfg)` sets global SDK config. Call it once at app bootstrap, before starting any process.

```ts theme={"system"}
import { FlowX } from '@flowx/react-native-sdk'

FlowX.configure({
  baseURL: 'https://yourDomain.dev',
  processApiPath: 'onboarding',
  organizationId: '10000001-0001-0001-8001-100000000001',
  language: 'en',
  locale: 'en-US',
  staticAssetsPath: 'https://yourDomain.dev/static',
  isDraft: false,
})
```

### `FlxConfig` parameters

| Name               | Description                                                                                                                                                                                                                            | Type      | Mandatory | Default |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | --------- | ------- |
| `baseURL`          | Base API URL                                                                                                                                                                                                                           | `string`  | true      | -       |
| `processApiPath`   | Process subpath                                                                                                                                                                                                                        | `string`  | true      | -       |
| `organizationId`   | FlowX-issued organization UUID. On self-hosted deployments it matches the `ORGANIZATION_ID` configured during the backend upgrade — see [License and organization configuration](/5.9/migrating-from-5.1-lts/organization-deployment). | `string`  | true      | -       |
| `language`         | Language used to localize enumerations                                                                                                                                                                                                 | `string`  | false     | -       |
| `locale`           | Locale used to format dates, currency, numbers                                                                                                                                                                                         | `string`  | false     | -       |
| `staticAssetsPath` | Base path for static resources (icons, media). The SDK logs a warning if not set.                                                                                                                                                      | `string`  | false     | -       |
| `themeId`          | Theme identifier (reserved, not consumed by the RN renderer yet)                                                                                                                                                                       | `string`  | false     | -       |
| `isDraft`          | Start the process in draft state                                                                                                                                                                                                       | `boolean` | false     | `false` |

## Starting a process

`FlowX.startProcess(opts)` starts a new process instance and returns a `FlxProcessHandle`. The handle exposes a `ProcessView` component that you mount inside a screen.

```tsx theme={"system"}
import { FlowX, type FlxProcessHandle } from '@flowx/react-native-sdk'
import { useEffect, useState } from 'react'

export function OnboardingScreen() {
  const [handle, setHandle] = useState<FlxProcessHandle | null>(null)

  useEffect(() => {
    let active = true
    let pending: FlxProcessHandle | null = null

    FlowX.startProcess({
      workspaceId: '8f52744-8403-4e8d-...',
      projectId: '111111-222222-333333-44444',
      processName: 'client_identification',
      params: { firstName: 'John', lastName: 'Smith' },
    }).then((h) => {
      if (!active) {
        h.dispose()
        return
      }
      pending = h
      setHandle(h)
    })

    return () => {
      active = false
      pending?.dispose()
    }
  }, [])

  if (!handle) return null
  const { ProcessView } = handle
  return <ProcessView />
}
```

### `StartProcessOptions`

| Name               | Description                                                                                                  | Type                                    | Mandatory | Example                   |
| ------------------ | ------------------------------------------------------------------------------------------------------------ | --------------------------------------- | --------- | ------------------------- |
| `workspaceId`      | Workspace identifier                                                                                         | `string`                                | true      | `'8f52744-8403-4e8d-...'` |
| `projectId`        | FlowX Project UUID. Get it from **FlowX Dashboard → Projects → copy UUID from the project actions popover**. | `string`                                | true      | `'111111-222222-...'`     |
| `appVersionId`     | Pin to a specific app version                                                                                | `string`                                | false     | -                         |
| `processName`      | Identifies the process to start                                                                              | `string`                                | true      | `'client_identification'` |
| `params`           | Data passed when starting the process                                                                        | `Record<string, unknown>`               | false     | `{ firstName: 'John' }`   |
| `resourceId`       | Resource identifier                                                                                          | `string`                                | false     | -                         |
| `buildId`          | Pinned build identifier                                                                                      | `string`                                | false     | -                         |
| `isModal`          | Render the process as a modal screen                                                                         | `boolean`                               | false     | `false`                   |
| `onClose`          | Called when the process view is closed                                                                       | `() => void`                            | false     | -                         |
| `onProcessStarted` | Called when the main process instance is started. Receives the new `processInstanceUuid`.                    | `(processInstanceUuid: string) => void` | false     | -                         |

### Getting the process identifier

Open the FlowX Designer, navigate to the process, and copy the process name from the breadcrumbs. Use this value as `processName`.

## Continuing a process

`FlowX.continueProcess(opts)` resumes an existing process instance by its UUID.

```tsx theme={"system"}
import { FlowX } from '@flowx/react-native-sdk'

const handle = await FlowX.continueProcess({
  processInstanceUuid: 'a3f1c2d4-...',
})
```

### `ContinueProcessOptions`

| Name                  | Description                            | Type         | Mandatory |
| --------------------- | -------------------------------------- | ------------ | --------- |
| `processInstanceUuid` | UUID of the process instance to resume | `string`     | true      |
| `isModal`             | Render the process as a modal screen   | `boolean`    | false     |
| `onClose`             | Called when the process view is closed | `() => void` | false     |

## The process handle

Both `startProcess` and `continueProcess` resolve to a `FlxProcessHandle`:

```typescript theme={"system"}
interface FlxProcessHandle {
  processInstanceUuid: string
  ProcessView: ComponentType
  dispose(): void
}
```

| Member                | Description                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------- |
| `processInstanceUuid` | UUID of the running process instance                                                                |
| `ProcessView`         | React component that renders the process screens. Mount it inside a screen in your navigation tree. |
| `dispose()`           | Tears down the running process and resets SDK stores. Call when the screen unmounts.                |

<Warning>
  Always call `handle.dispose()` when the host screen unmounts. Skipping it leaks SDK store state into the next process.
</Warning>

## Full example

```tsx theme={"system"}
import { useEffect, useState } from 'react'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { KeyboardProvider } from 'react-native-keyboard-controller'
import { FlowX, type FlxProcessHandle } from '@flowx/react-native-sdk'

FlowX.configure({
  baseURL: 'https://yourDomain.dev',
  processApiPath: 'onboarding',
  organizationId: '10000001-0001-0001-8001-100000000001',
  language: 'en',
  locale: 'en-US',
  staticAssetsPath: 'https://yourDomain.dev/static',
})

function OnboardingScreen({ authToken }: { authToken: string }) {
  const [handle, setHandle] = useState<FlxProcessHandle | null>(null)

  useEffect(() => {
    FlowX.setAccessToken(authToken)

    let active = true
    let pending: FlxProcessHandle | null = null

    FlowX.startProcess({
      workspaceId: '8f52744-8403-4e8d-...',
      projectId: '111111-222222-333333-44444',
      processName: 'client_identification',
      params: { firstName: 'John' },
    }).then((h) => {
      if (!active) {
        h.dispose()
        return
      }
      pending = h
      setHandle(h)
    })

    return () => {
      active = false
      pending?.dispose()
    }
  }, [authToken])

  if (!handle) return null
  const { ProcessView } = handle
  return <ProcessView />
}

export default function App({ authToken }: { authToken: string }) {
  return (
    <SafeAreaProvider>
      <KeyboardProvider>
        <OnboardingScreen authToken={authToken} />
      </KeyboardProvider>
    </SafeAreaProvider>
  )
}
```
