Bridge Flutter apps to the rwkv-mobile inference runtime.
A Flutter FFI plugin and runtime orchestration layer for on-device RWKV, multimodal, and speech workloads.
rwkv_mobile_flutter sits between a Flutter app and the native rwkv-mobile C++ inference engine. It is not just a thin FFI binding: it also owns the isolate boundary, request/response protocol, model lifecycle, native library loading, and part of the runtime coordination needed by apps such as RWKV_APP.
- Built for Flutter-native integration: Expose the native runtime to Dart without forcing app code to manage raw FFI calls directly.
- Designed for real device workloads: Keep inference work off the UI isolate and coordinate model loading, generation, vision, audio, and TTS flows in one place.
- One bridge for multiple backends: Reuse the same Dart-side protocol across CPU, GPU, and NPU-backed runtimes provided by
rwkv-mobile. - Production-oriented packaging: Ship prebuilt native libraries for Android, iOS, macOS, Windows, and Linux as part of the plugin.
- Cross-platform Flutter FFI plugin: Android, iOS, macOS, Windows, and Linux.
- Isolate-based runtime bridge: Run the native inference runtime behind a dedicated Dart isolate.
- Structured request/response protocol:
ToRWKVandFromRWKVsealed classes for app-to-runtime messaging. - Model lifecycle management: Load, unload, switch, and inspect multiple models from Flutter.
- Text generation APIs: Completion, chat with history, batch inference, stop/resume-style polling, and token counting.
- Multimodal support: Vision encoder, adapter-based vision flow, and Whisper-style audio prompt support.
- Speech support: SparkTTS model loading, streaming TTS buffers, global tokens, and property-driven speech generation.
- Runtime diagnostics: Load progress, prefill/decode speed, logs, SoC/platform detection, and state cache inspection.
This repository is best understood as the middle layer in a three-part stack:
flowchart LR
A["Flutter App (for example RWKV_APP)"] -->|"ToRWKV messages via SendPort"| B["rwkv_mobile_flutter isolate"]
B -->|"Dart FFI"| C["rwkv-mobile C API"]
C --> D["Native runtime and backends"]
D --> E["ncnn / llama.cpp / QNN / MLX / CoreML / WebRWKV / MNN / MTK NP7"]
B -->|"FromRWKV messages"| A
- App layer: product UI, state management, downloads, business logic.
- This layer: isolate boundary, protocol, platform library loading, runtime orchestration, Dart-facing API surface.
- Engine layer: C++ runtime, backend implementations, native inference, and low-level C API.
For local development, RWKV_APP uses this repository as a path dependency:
dependencies:
rwkv_mobile_flutter:
path: ../rwkv_mobile_flutterYou can do the same in your own Flutter app, or point to the Git repository you maintain internally.
import 'dart:isolate';
import 'dart:ui';
import 'package:rwkv_mobile_flutter/rwkv.dart';
final receivePort = ReceivePort();
receivePort.listen((message) {
if (message is SendPort) {
// Save this SendPort and use it to send ToRWKV requests.
} else {
// Handle FromRWKV responses here.
}
});
await RWKVMobile().runIsolate(
StartOptions(
sendPort: receivePort.sendPort,
rootIsolateToken: RootIsolateToken.instance!,
),
);Frontend isolate and RWKV isolate communicate through SendPort:
- Requests:
lib/to_rwkv.dart - Responses:
lib/from_rwkv.dart - Runtime bridge:
lib/rwkv_mobile_flutter.dart
Typical app flow:
- Start the RWKV isolate.
- Receive the isolate
SendPort. - Send typed requests such as
LoadRWKVModel,ChatAsync,GenerateAsync, orStartTTS. - Consume typed responses such as
LoadModelSteps,ResponseBufferContent,Speed, orTTSStreamingBuffer.
The public Dart-side contract is centered on two sealed hierarchies:
sealed class ToRWKV {}Representative request types include:
LoadRWKVModelReleaseRWKVModelChatAsyncChatBatchAsyncGenerateAsyncGetResponseBufferContentLoadVisionEncoderLoadVisionEncoderAndAdapterLoadWhisperEncoderStartTTSSaveRuntimeStateByHistory
sealed class FromRWKV {}Representative response types include:
LoadModelStepsGenerateStartGenerateStopResponseBufferContentResponseBatchBufferContentSpeedEvaluationResultsRuntimeLogStateInfoTTSStreamingBuffer
This plugin wraps runtime features exposed by rwkv-mobile, including:
- Multiple backend selection through the
Backendenum - Chat/completion inference
- Batch inference
- Sampling and penalty controls
- Seed and prompt management
- Response buffer polling
- Vision encoder loading
- Whisper/audio prompt support
- SparkTTS loading and streaming
- Runtime state save/load
- Platform and SoC inspection
Backends currently represented in Dart include:
ncnnllama.cppweb-rwkvqnnmnncoremlmlxmtk_np7
Actual availability depends on the bundled native binaries you ship for each platform.
This repository includes prebuilt native artifacts for supported platforms, for example:
- Android:
android/src/main/jniLibs/arm64-v8a/librwkv_mobile.so - iOS:
ios/librwkv_mobile.a - macOS:
macos/librwkv_mobile.dylib - Windows:
windows/rwkv_mobile.dll,windows/rwkv_mobile-arm64.dll - Linux:
linux/librwkv_mobile-linux-x86_64.so,linux/librwkv_mobile-linux-aarch64.so
The plugin loads these libraries dynamically based on the current platform and ABI.
When you see errors such as:
Invalid argument(s): Failed to lookup symbol 'xxx': undefined symbol: xxx
the bundled native libraries are usually out of sync with the generated FFI bindings or the underlying engine build. Refresh them from the latest rwkv-mobile release:
- Windows:
& ./fetch_latest_libraries.ps1- Linux / macOS:
./fetch_latest_libraries.shThese scripts download the latest platform archives from rwkv-mobile releases and copy the extracted artifacts into this plugin repository.
If you are developing the full Flutter app and this bridge together, keep the repositories side by side:
parent/
ββ rwkv_mobile_flutter/
ββ RWKV_APP/
Then use the local path dependency in RWKV_APP/pubspec.yaml:
dependencies:
rwkv_mobile_flutter:
path: ../rwkv_mobile_flutterThe demo app previously kept in example/ has been moved to RWKV_APP.
- Flutter / Dart: Cross-platform app layer and isolate model.
- Dart FFI: Native bridge between Flutter and the C API.
- rwkv_mobile_flutter: Protocol, runtime orchestration, and platform packaging layer.
- rwkv-mobile: Native inference runtime with multiple backends and multimodal support.
- Platform runtimes: CPU, GPU, and NPU execution depending on backend and device.
This repository is most useful when kept in sync with the engine and app layers:
- If you change native runtime symbols, regenerate or update the Dart FFI bindings.
- If you add a new runtime capability, update
ToRWKV,FromRWKV, and the isolate handler together. - If you change platform packaging, verify the corresponding native library layout for each target OS.
This project is licensed under the Apache License 2.0. See LICENSE for details.