Skip to main content
For AI Coding Agents: This document provides everything needed to integrate on-device AI (LLM, STT, TTS) into a React Native app using the RunAnywhere SDK.

Working Starter Project

Check out the RunAnywhere Expo Demo on GitHub for a working Expo starter template with pre-built Android APK available for download.

RunAnywhere AI Studio App

You MUST use the “RunAnywhere AI Studio” app to run your React Native app. This is a custom fork of Expo Go that includes the native libraries required for the RunAnywhere SDK.
  • Standard Expo Go does NOT include RunAnywhere native modules
  • The AI Studio app contains: LlamaCPP (LLM), ONNX Runtime (STT/TTS), NativeAudioModule
  • Your JS bundle connects to Metro, but runs inside AI Studio which provides the native layer

Quick Start

Package Version Compatibility: Since your app runs inside AI Studio (not a standalone build), native libraries must match pre-installed versions. Most critically: use react-native-reanimated@^3.16.0, not 4.x. See Package Compatibility section for details.

1. Install Dependencies

react-native-nitro-modules is the only hard native peer dependency. Model downloads go through the SDK’s own native download bridge; react-native-fs is optional and only clears oversize partial files when a resumed download plan is rejected.

2. Initialize SDK (App.tsx)

register() is async on every backend package and returns a boolean. Initialization is two-phase: initialize() resolves once the native core is up, and Phase 2 continues in the background while every capability API waits on it internally.

3. Register Models

Model registration lives on RunAnywhere, not on the backend packages. There is no LlamaCPP.addModel or ONNX.addModel. registerModel returns the resolved ModelInfo, which is what downloadModel takes.

API Reference

Model management

loadModel and unloadModel take a proto request, not a file path, and return a result rather than throwing. Check result.success. There is no getModelInfo, loadSTTModel, loadTTSModel, unloadSTTModel, or unloadTTSModel.

LLM streaming

generateStream is synchronous and returns an AsyncIterable<LLMStreamEvent>.
To drive the iterator yourself, use manual next() calls. Hermes does not support for await...of over NitroModules iterables.
await RunAnywhere.cancelGeneration() cancels without an iterator reference.

Speech to text

transcribe takes a Uint8Array of audio bytes, not base64.
For live partials, feed transcribeStream from a pushable stream.

Text to speech

Or let the SDK synthesize and play in one call:
The option is speakingRate, not rate. There is no RunAnywhere.Audio namespace; the PCM helpers are RunAnywhere.pcm16ToFloat32 and RunAnywhere.pcm16ToWav.

Voice agent

Load STT, LLM, and TTS into their category slots first, then compose the pipeline and start the microphone driver.
There is no startVoiceSession. The C ABI owns no microphone, so VoiceAgentMicDriver is what supplies audio; subscribing to streamVoiceAgent() alone is dead air.

Complete package.json

react-native-nitro-modules is the SDK’s only required native peer dependency. react-native-fs is optional. react-native-reanimated must be ^3.16.0, not 4.x, to match the native code in AI Studio.

Project Structure


ModelService pattern (React Context)

One provider that registers the catalog, tracks per-modality download and load state, and exposes a single prepare(kind) call. The three modalities differ only by category, so they share one code path.
Put MODEL_IDS and registerModels in their own module, as shown in Register Models above.

ChatScreen example


STT screen example

AudioCaptureManager handles the microphone permission and emits 16 kHz mono Int16 chunks, which is exactly what transcribe expects.

TTS screen example

speak synthesizes and plays through the SDK’s internal AudioPlaybackManager. Use synthesize instead when you need the raw Uint8Array audio.

Theme Colors



Model URLs Reference


API quick reference

Enums and request messages come from @runanywhere/proto-ts. SDKEnvironment, ErrorCode, ErrorCategory, SDKException, isSDKException, EventBus, AudioCaptureManager, AudioPlaybackManager, VoiceAgentMicDriver, and createPushableAudioStream come from @runanywhere/core.

Audio

The SDK ships its own capture and playback. Use these rather than a third-party recorder, which tends to break on iOS New Architecture, and note that the Web Audio AudioContext does not exist in React Native at all.
Audio crosses the bridge as binary, not base64. Capture defaults to 16000 Hz mono; playback assumes 22050 Hz when a TTS backend reports no rate.

Package Compatibility

Since your app runs inside the RunAnywhere AI Studio app (a custom Expo fork), any native libraries you use must match the versions pre-installed in AI Studio. Version mismatches will cause runtime errors.

react-native-reanimated

The RunAnywhere AI Studio app includes Reanimated 3.x. You CANNOT use Reanimated 4.x as it has breaking native changes.
If you see errors like:
  • ReanimatedUIManager native module not found
  • _ReanimatedModule or ReanimatedCommitHook errors
  • NativeReanimated undefined errors
  • "Reanimated 2 failed to create a worklet" or worklet-related crashes
Solution: Downgrade to Reanimated 3.x:

Other Native Libraries

The same principle applies to any library with native code. If a library requires native compilation (has iOS/Android native code), you must use the version that matches what’s bundled in AI Studio.Libraries bundled in AI Studio (use these versions):Pure JS libraries (any version is fine):
  • @react-navigation/* packages
  • UI libraries without native code (tailwind, styling)
  • State management (zustand, redux, mobx)
  • API clients, utilities

Troubleshooting