Skip to main content

React Native project requirements

The FlowX packages declare react-native β‰₯ 0.83.0 and react β‰₯ 19.2.0 as peer dependencies. The validated target is React Native 0.85.3 with Expo SDK 56, which is what FlowX builds and tests against. Your react must also satisfy the peer dependency of your own React Native version (^19.2.3 for react-native@0.85.3). React Native 0.85.3 requires Node ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0.
To install the npm libraries provided by FlowX.AI you will need access to the private FlowX.AI Nexus registry. Consult your project DevOps.
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.

Installation

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:
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:
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.
Then install iOS pods:
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), @flowx/react-native-ui-toolkit ships an Expo config plugin for the Android Material 3 date picker (see below), and react-native-keyboard-controller / react-native-screens / react-native-safe-area-context rely on autolinking plus the providers shown later in this page.

Babel plugin

react-native-worklets/plugin must be the last plugin in your Babel config.
No manual config needed. babel-preset-expo (SDK 54+) auto-adds the worklets plugin when react-native-worklets is in node_modules.

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.
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:
Then run npx expo prebuild --clean --platform android.
The toolkit reads the injected extra.flxUiToolkit.material3 value at runtime through expo-constants, which is already present in every Expo project. No JS opt-in call is needed.
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.

App-root providers

The renderer expects safe-area and keyboard providers above it in the tree:
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.

Authorization

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.
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.

FlxConfig parameters

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.

StartProcessOptions

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.

The process handle

startProcess resolves to a FlxProcessHandle:
To capture the running instance UUID, pass an onProcessStarted callback to startProcess; it receives the new processInstanceUuid. The handle itself does not expose it.
Always call handle.dispose() when the host screen unmounts. Skipping it leaks SDK store state into the next process.

Resuming a process

FlowX.continueProcess(opts) resumes an existing process instance instead of starting a new one. Pass the processInstanceUuid of the instance you want to reattach to. Like startProcess, it resolves to a FlxProcessHandle you mount through its ProcessView.

ContinueProcessOptions

continueProcess reattaches to an already-started instance, so it takes no processName, params, or onProcessStarted. Those apply only when starting a new process. Configure the SDK with FlowX.configure(...) and set the access token before calling it, exactly as for startProcess.

Starting a UI Flow

UI Flows are lightweight, screen-driven flows defined in the FlowX Designer. They run client-side on top of a data model, without requiring a BPMN process instance on the engine.
Prior starting a UI Flow, make sure the authorization and the SDK configuration were correctly set up.
FlowX.startUiFlow(opts) starts a UI Flow and returns a FlxUiFlowHandle. The handle exposes a UiFlowView component that you mount inside a screen.

StartUiFlowOptions

Getting the UI Flow name

Open the FlowX Designer and navigate to UI Flows. The flow name displayed in the list is the value to pass as uiFlowName.

The UI Flow handle

startUiFlow resolves to a FlxUiFlowHandle:
Always call handle.dispose() when the host screen unmounts. Skipping it leaks SDK store state into the next session.

Custom components

Register host-authored custom components through the components field of FlowX.configure(...). Each key is the component identifier defined in the FlowX process; the value is the React Native component that renders it. The registration is read when the process view mounts, so configure the SDK before starting or continuing a process.
The keys in the components object MUST match the custom component identifiers defined in the FlowX process.
React Native supports self-managed custom components only: components you author in your app and register by identifier. Bundled custom components (source compiled from the backend at runtime) are browser-only; on React Native they are skipped and a warning is logged in development. Re-author any bundled component as a self-managed one.

Component contract

Each custom component receives the same contract as the React SDK:
Process data mapped through inputKeys is available on input.data. Process actions are available on input.actionsFn, keyed by action name; calling one triggers the process action and returns a Promise that resolves when it completes.

Example

Make sure any action names you call through input.actionsFn match the process action names bound to the component in the FlowX Designer.

Custom validators

Define custom validators on your form fields in the FlowX Designer, then pass their implementations through the validators field of FlowX.configure(...). The SDK honors the error messages configured on each field in the process. Each key in the validators object is the validator name referenced in the Designer; the value is a factory that receives the validator’s configured params and returns the predicate the SDK runs against the field value. Return true to pass or false to fail. When it fails, the message configured on that validator in the Designer is shown.
The keys in the validators object MUST match the custom validator names defined in the FlowX process. If a field references a validator name that is not registered, the SDK logs Custom validator <name> not found and skips it.

Example

Full example

Custom loader

The SDK provides a mechanism for container applications to customize the loader UI displayed during process execution. This allows you to replace the default FlowX loader with your own custom implementation based on different loading scenarios.

Configuration

To configure custom loaders, pass them through the customLoader prop of the <FlxProcessRenderer /> component:
If you drive the SDK through the FlowX config (FlowX.startProcess() / FlowX.continueProcess()) instead of rendering <FlxProcessRenderer /> yourself, pass the same object through FlowX.configure():

API specification

The customLoader prop accepts an object of type FlxCustomLoader:

Loader types

  • startProcess - Displayed when starting or resuming a process
  • reloadProcess - Displayed when reloading a process
  • defaultAction - Default loader for actions when loaderType is 'action'. Used when no specific action loader is found in the actions record
  • defaultUpload - Default loader for file uploads when loaderType is 'upload'
  • actions - Record mapping specific action identifiers to custom loaders. When an action is executed, the SDK will first check for a matching entry in this record before falling back to defaultAction

Rendering behavior

Custom loaders on React Native differ from the web SDK in a few important ways:
  • The host owns every pixel. Your loader node is rendered full-screen with no SDK scrim, card, or spinner behind it. If you want a dimmed backdrop or a centered card, paint them yourself (see the scrim style in the example above).
  • Size your root with absolute fill. The SDK centers your node inside the overlay, so a plain flex: 1 root collapses to its content size. Use StyleSheet.absoluteFillObject on the outermost view to cover the whole screen.
  • The loader lives in a native modal. While visible it blocks all touch input, renders above native iOS page-sheet modals and Android dialogs, and swallows the Android hardware back button β€” the user cannot dismiss it.
  • Android debounces the loader. On Android the loader appears only after ~250 ms, so fast responses never flash a loader; on iOS it appears immediately.
  • Theming gate. Until the SDK finishes loading its theme resources (right after startup), an opaque placeholder is shown instead of any loader β€” default or custom β€” to avoid an unthemed flash.

Fallback behavior

If no custom loader is provided for a specific type, the SDK will automatically fall back to the built-in FlowX loader, themed with the active FlowX theme. This ensures your app continues to function even with partial custom loader configuration.
You can use any React Native components β€” including Reanimated animations, Lottie views, or your own design-system components β€” to create rich loading experiences that match your app’s design.

Public API methods

The SDK exposes a set of imperative helpers for reading CMS resources β€” enumerations, substitution tags, and media library items β€” from your own code, for example inside a custom component. Import them from @flowx/core-sdk:
These methods read the configuration of the active process session (API URL, language, project and build identifiers), so they can only be called after a process has been started β€” for example from a custom component rendered by the SDK. Results are resolved in the language the SDK was configured with and are cached for the duration of the session.

getEnumeration

Fetches the values of an enumeration by name.
  • name - The name of the enumeration to fetch
  • parentName - Optional name of the parent enumeration, used for hierarchical (parent–child) enumerations
Returns the enumeration values sorted by their configured order. Each value contains the localized display text in label and the enumeration code in id / value; for hierarchical enumerations, nomenclatorId holds the name of the child enumeration linked to that value.

getTag

Resolves a substitution tag β€” a localized UI string managed in the CMS β€” by its key.
  • tag - The substitution tag key, with or without the @@ localization prefix
Returns the tag’s value in the current SDK language, or undefined if the key does not exist.

getMediaItemURL

Resolves the download URL of a media library item by its key.
  • mediaItemId - The media item key, as defined in the project’s media library
Returns the item’s URL, or undefined if no media item matches the key. Both the bare media item key and the fully qualified key (prefixed with the owning application’s UUID) are accepted.

Document caching

Documents downloaded by the SDK (for example when a process screen previews a generated file) are cached on disk, keyed by their URL, so re-renders and app relaunches skip the network round-trip. Caching is enabled by default.
  • The URL β†’ file path index is persisted to AsyncStorage; the files themselves live in the OS cache directory, so the operating system may evict them at any time β€” the SDK simply re-downloads on a cache miss.
  • Set cacheDocuments: false if your documents can change behind the same URL and must always be fetched fresh.
  • The flag can be toggled with a later configure() call and applies to document loads performed after the change.
  • Mirrors cacheDocuments on the iOS SDK and documentsCacheEnabled on the Android SDK.

Foreground state sync

When the app returns from background to foreground, the SDK re-fetches the root process status and rebuilds the process UI, catching up on anything that changed while the app was backgrounded. This is enabled by default.
  • Set updateStateEnabled: false to skip the state catch-up. SSE reconnection is unaffected β€” the SDK still re-establishes the event stream and continues to receive live updates.
  • Unlike language / locale, this flag also applies to the live session: it is read on each background β†’ foreground return, so calling configure() with a new value takes effect immediately β€” no process restart needed.
  • Mirrors FXConfig.updateStateEnabled on the iOS SDK and Config.updateStateEnabled on the Android SDK.

Custom headers

customHeaders lets the container app attach its own HTTP headers β€” correlation IDs, API-gateway keys, WAF cookies β€” to the requests the SDK sends to the FlowX backend: REST calls, SSE event streams, and document downloads from the FlowX download endpoint. They are sent in both authenticated and anonymous mode.
  • Requests to public or external hosts never carry the custom headers: image and icon fetches, native font downloads, and image/document URLs outside the FlowX download endpoint. Those requests carry no SDK auth either β€” custom headers travel exactly where the SDK’s own auth headers travel, so a secret placed here cannot leak to third-party hosts referenced by process content.
  • Custom headers are applied before the SDK-managed headers, so on a name collision the SDK wins β€” you cannot override Authorization, flowx-platform, and the other headers the SDK manages itself.
  • The headers are live-updatable via configure(): REST requests and document downloads read them per request; SSE applies them to connections opened after the change.
  • Each configure() call replaces the whole header set β€” pass the complete record every time, not just the headers that changed.

Custom interceptors

requestInterceptors and responseInterceptors attach your own axios interceptors to the SDK’s REST layer β€” for request/response logging, timing, custom error reporting, or per-request headers.
  • Interceptors apply to every REST call the SDK makes through its shared axios instance. They do not cover SSE event streams or the SDK’s non-axios fetches (images, icons, documents, native fonts) β€” use Custom headers to reach those.
  • Like language / locale, they take effect on the next startProcess() / continueProcess() β€” interceptors are registered per session and cleared when the session is disposed; the live session keeps the ones it started with.
  • Ordering relative to the SDK’s built-in interceptors (auth and platform headers, logging, error toasts) is not guaranteed β€” don’t rely on reading or overriding SDK-managed headers such as Authorization.
  • Mirrors requestInterceptors / responseInterceptors on the web SDK’s <FlxProcessRenderer />.

Flowx callbacks and logging

The FlowX config exposes hooks for observing what happens inside a process session: analytics events, process swaps triggered by the backend, and a structured log stream. All three are config-level and session-independent β€” registrations survive dispose() and process restarts, so you can register them once at app startup.

Analytics collector

FlowX.analyticsCollector() subscribes to analytics events. An event fires whenever an executed action has analytics defined in its params, with the resolved payload:
The method returns an unsubscribe function. Multiple collectors may be registered β€” each one receives every event.

New process started

Assign a callback to FlowX.newProcessStarted to be notified when the backend starts a new process out of the live session β€” a START_PROJECT action, signaled by the newProcessStarted SSE event β€” with the new process instance UUID. This is a notification only: the SDK swaps the session to the new process on its own, inside the already-mounted ProcessView β€” the host does not need to (and should not) restart anything. Use the callback for bookkeeping, e.g. persisting the new instance UUID so the process can be resumed later with continueProcess().

Logging

FlowX.logSink() subscribes to the SDK’s structured log-event stream β€” useful for debugging and for feeding your own telemetry. Events cover four categories:
  • rest - API traffic, including the SDK’s image, icon, and document fetches
  • sse - SSE connection lifecycle and received events
  • expression - expression evaluations (hide, disabled, computed, conditional, validator, local script)
  • cms - CMS font registration
It accepts a single logger or an array of loggers, plus an optional categories filter, and returns an unsubscribe function. Secrets in headers (Authorization & co.) are redacted before events are emitted. Pass the exported formattedLogger to pretty-print events to the console.

Chat component

To use the FlxChatRenderer component, import it from the React Native SDK:

Usage

The chat fills its parent, so give it a flexed container and let your screen own the safe area:
Parameters:

chatConfig parameters

The chatConfig object accepts the following properties:

Voice input

Voice messages need a recorder engine and a microphone declaration in the app, which a library cannot add on its own:
  1. Install the optional peer dependencies react-native-nitro-sound and react-native-nitro-modules. Without them the SDK installs no recorder and the microphone button is not drawn.
  2. Add the toolkit’s Expo config plugin, which declares RECORD_AUDIO on Android and fills NSMicrophoneUsageDescription on iOS (your own copy is kept if you already wrote one):
Set voiceInputEnabled={false} to hide the microphone even where an engine is installed. Voice messages recorded on other clients still play back either way.
Last modified on August 27, 2026