Quickstart
Install Cactus and run your first on-device AI model
Installation
Clone and set up the Cactus repository:
git clone https://github.com/cactus-compute/cactus && cd cactus && git checkout v1.6.0 && source ./setupBuild the Flutter bindings:
cactus build --flutterOutput files:
| File | Platform |
|---|---|
libcactus.so | Android (arm64-v8a) |
cactus-ios.xcframework | iOS |
cactus-macos.xcframework | macOS |
cactus.dart | Dart FFI bindings |
Clone and set up the Cactus repository:
git clone https://github.com/cactus-compute/cactus && cd cactus && git checkout v1.6.0 && source ./setupBuild the Android bindings:
cactus build --androidBuild output: android/build/lib/libcactus.so
git clone https://github.com/cactus-compute/cactus && cd cactus && source ./setupsudo apt-get install python3 python3-venv python3-pip cmake build-essential libcurl4-openssl-dev
git clone https://github.com/cactus-compute/cactus && cd cactus && source ./setupInclude the Cactus header in your project:
#include <cactus.h>Build instructions are available in the Cactus repository.
Platform Integration
Android
Copy libcactus.so to android/app/src/main/jniLibs/arm64-v8a/
Copy cactus.dart to your lib/ folder
iOS
Copy cactus-ios.xcframework to your ios/ folder
Open ios/Runner.xcworkspace in Xcode
Drag the xcframework into the project
In Runner target > General > "Frameworks, Libraries, and Embedded Content", set to "Embed & Sign"
Copy cactus.dart to your lib/ folder
macOS
Copy cactus-macos.xcframework to your macos/ folder
Open macos/Runner.xcworkspace in Xcode
Drag the xcframework into the project
In Runner target > General > "Frameworks, Libraries, and Embedded Content", set to "Embed & Sign"
Copy cactus.dart to your lib/ folder
- Copy
libcactus.sotoapp/src/main/jniLibs/arm64-v8a/ - Copy
Cactus.kttoapp/src/main/java/com/cactus/
Source files:
| File | Copy to |
|---|---|
Cactus.common.kt | shared/src/commonMain/kotlin/com/cactus/ |
Cactus.android.kt | shared/src/androidMain/kotlin/com/cactus/ |
Cactus.ios.kt | shared/src/iosMain/kotlin/com/cactus/ |
cactus.def | shared/src/nativeInterop/cinterop/ |
Binary files:
| Platform | Location |
|---|---|
| Android | libcactus.so → app/src/main/jniLibs/arm64-v8a/ |
| iOS | libcactus-device.a → link via cinterop |
Configure build.gradle.kts:
kotlin {
androidTarget()
listOf(iosArm64(), iosSimulatorArm64()).forEach {
it.compilations.getByName("main") {
cinterops {
create("cactus") {
defFile("src/nativeInterop/cinterop/cactus.def")
includeDirs("/path/to/cactus/ffi")
}
}
}
it.binaries.framework {
linkerOpts("-L/path/to/apple", "-lcactus-device")
}
}
sourceSets {
commonMain.dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
}
}Your First Completion
import 'cactus.dart';
final model = Cactus.create('/path/to/model.gguf');
final result = model.complete('What is the capital of France?');
print(result.text);
model.dispose();import com.cactus.*
val model = Cactus.create("/path/to/model")
val result = model.complete("What is the capital of France?")
println(result.text)
model.close()# Download and run LiquidAI's LFM2-350M
cactus run LiquidAI/LFM2-350M
# Or use a specific model
cactus run google/gemma-3-270m-it#include <cactus.h>
cactus_model_t model = cactus_init("path/to/weight/folder", nullptr);
const char* messages = R"([
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"}
])";
char response[4096];
int result = cactus_complete(
model, messages, response, sizeof(response),
nullptr, nullptr, nullptr, nullptr
);Supported Models
v1.6 includes support for:
- LLMs: Gemma-3, LiquidAI LFM2/LFM2.5, Qwen3 (with completion, tools, embeddings)
- Vision: LFM2-VL, LFM2.5-VL (with Apple NPU support)
- Transcription: Whisper (Small/Medium with Apple NPU), Moonshine-Base
- Embeddings: Nomic-Embed, Qwen3-Embedding
See the Models dashboard for the complete list.
Requirements
Flutter 3.0+, Dart 2.17+, iOS 14.0+ / macOS 13.0+, Android API 24+ / arm64-v8a
Android API 24+ / arm64-v8a, iOS 14+ / arm64 (KMP only), Kotlin 1.9+