Documentation Index
Fetch the complete documentation index at: https://mintlify.com/cactus-compute/cactus/llms.txt
Use this file to discover all available pages before exploring further.
React Native SDK
Run AI models on-device in React Native apps for iOS and Android.
Installation
Install the npm package:
npm install @cactus-compute/react-native
# or
yarn add @cactus-compute/react-native
The package includes pre-built native libraries for iOS and Android.
Setup
iOS
No additional setup required. The XCFramework is automatically linked.
Android
No additional setup required. The native libraries are automatically included.
Usage
Basic Completion
import Cactus from '@cactus-compute/react-native';
const runInference = async () => {
try {
const model = await Cactus.init('/path/to/model', null, false);
const messages = [
{ role: 'user', content: 'What is the capital of France?' }
];
const result = await Cactus.complete(model, messages);
console.log(result.response);
await Cactus.destroy(model);
} catch (error) {
console.error('Error:', error);
}
};
Completion with Options and Streaming
import Cactus from '@cactus-compute/react-native';
const streamCompletion = async () => {
const model = await Cactus.init('/path/to/model');
const messages = [
{ role: 'user', content: 'Tell me a story' }
];
const options = {
max_tokens: 256,
temperature: 0.7,
};
const result = await Cactus.complete(
model,
messages,
options,
null,
(token, tokenId) => {
console.log('Token:', token);
}
);
console.log('Final result:', result);
await Cactus.destroy(model);
};
Audio Transcription
import Cactus from '@cactus-compute/react-native';
const transcribeAudio = async () => {
const model = await Cactus.init('/path/to/whisper-model');
// From file
const result = await Cactus.transcribe(model, '/path/to/audio.wav');
console.log('Transcription:', result.text);
await Cactus.destroy(model);
};
Embeddings
import Cactus from '@cactus-compute/react-native';
const getEmbeddings = async () => {
const model = await Cactus.init('/path/to/model');
// Text embedding
const embedding = await Cactus.embed(model, 'Hello, world!', true);
console.log('Embedding dimension:', embedding.length);
// Image embedding
const imageEmbedding = await Cactus.imageEmbed(model, '/path/to/image.jpg');
await Cactus.destroy(model);
};
Vector Index
import Cactus from '@cactus-compute/react-native';
const useVectorIndex = async () => {
const index = await Cactus.indexInit('/path/to/index', 384);
// Add documents
await Cactus.indexAdd(
index,
[1, 2],
['First document', 'Second document'],
[[0.1, 0.2, ...], [0.3, 0.4, ...]],
null
);
// Query
const results = await Cactus.indexQuery(
index,
[0.15, 0.25, ...],
null
);
console.log('Search results:', results);
await Cactus.indexDestroy(index);
};
API Reference
Init / Lifecycle
Cactus.init(modelPath: string, corpusDir?: string | null, cacheIndex?: boolean): Promise<number>
Cactus.destroy(model: number): Promise<void>
Cactus.reset(model: number): Promise<void>
Cactus.stop(model: number): Promise<void>
Cactus.getLastError(): Promise<string | null>
Completion
interface Message {
role: 'system' | 'user' | 'assistant';
content: string;
images?: string[];
}
interface CompletionOptions {
max_tokens?: number;
temperature?: number;
top_p?: number;
stop_sequences?: string[];
}
interface CompletionResult {
success: boolean;
response: string;
function_calls: any[];
cloud_handoff: boolean;
confidence: number;
time_to_first_token_ms: number;
total_time_ms: number;
prefill_tps: number;
decode_tps: number;
prefill_tokens: number;
decode_tokens: number;
total_tokens: number;
}
Cactus.complete(
model: number,
messages: Message[],
options?: CompletionOptions | null,
tools?: any[] | null,
callback?: (token: string, tokenId: number) => void
): Promise<CompletionResult>
Transcription
interface TranscriptionResult {
text: string;
segments?: any[];
}
Cactus.transcribe(
model: number,
audioPath?: string | null,
prompt?: string | null,
options?: any | null,
callback?: (token: string, tokenId: number) => void,
pcmData?: Uint8Array | null
): Promise<TranscriptionResult>
Cactus.streamTranscribeStart(model: number, options?: any | null): Promise<number>
Cactus.streamTranscribeProcess(stream: number, pcmData: Uint8Array): Promise<string>
Cactus.streamTranscribeStop(stream: number): Promise<string>
Embeddings
Cactus.embed(model: number, text: string, normalize: boolean): Promise<Float32Array>
Cactus.imageEmbed(model: number, imagePath: string): Promise<Float32Array>
Cactus.audioEmbed(model: number, audioPath: string): Promise<Float32Array>
Tokenization
Cactus.tokenize(model: number, text: string): Promise<number[]>
Cactus.scoreWindow(model: number, tokens: number[], start: number, end: number, context: number): Promise<any>
VAD / RAG
Cactus.vad(model: number, audioPath?: string | null, options?: any | null, pcmData?: Uint8Array | null): Promise<any>
Cactus.ragQuery(model: number, query: string, topK: number): Promise<any>
Vector Index
Cactus.indexInit(indexDir: string, embeddingDim: number): Promise<number>
Cactus.indexDestroy(index: number): Promise<void>
Cactus.indexAdd(
index: number,
ids: number[],
documents: string[],
embeddings: number[][],
metadatas?: string[] | null
): Promise<void>
Cactus.indexDelete(index: number, ids: number[]): Promise<void>
Cactus.indexGet(index: number, ids: number[]): Promise<any>
Cactus.indexQuery(index: number, embedding: number[], options?: any | null): Promise<any>
Cactus.indexCompact(index: number): Promise<void>
Telemetry
Cactus.setTelemetryEnvironment(cacheDir: string): Promise<void>
Cactus.setAppId(appId: string): Promise<void>
Cactus.telemetryFlush(): Promise<void>
Cactus.telemetryShutdown(): Promise<void>
Bundling Models
Models must be accessible at runtime. Here are recommended approaches:
iOS
- Add model files to your Xcode project
- Ensure they’re included in “Copy Bundle Resources”
- Access via bundle path:
import RNFS from 'react-native-fs';
const modelPath = `${RNFS.MainBundlePath}/model`;
const model = await Cactus.init(modelPath);
Android
- Place models in
android/app/src/main/assets/
- Copy to app storage on first launch:
import RNFS from 'react-native-fs';
const copyModel = async () => {
const modelPath = `${RNFS.DocumentDirectoryPath}/model`;
if (!(await RNFS.exists(modelPath))) {
await RNFS.copyFileAssets('model', modelPath);
}
return modelPath;
};
const modelPath = await copyModel();
const model = await Cactus.init(modelPath);
Requirements
- React Native 0.64+
- iOS 14.0+
- Android API 24+ (arm64-v8a)
See Also
C API Reference
Full C API reference underlying the React Native bindings
GitHub Repository
View source code and contribute
Swift SDK
Native Swift alternative for iOS
Kotlin SDK
Native Kotlin alternative for Android