| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
| uniffi-bindgen.rs | ||
| uniffi.toml | ||
fluxa-core
The platform-agnostic Rust brain behind Fluxa.
State management · Stream policy · Addon protocol · Effect-driven I/O
What is fluxa-core?
fluxa-core is a headless Rust library that contains all of Fluxa's domain logic. It handles content discovery, stream selection, playback state, user profiles, library management, calendar tracking, and external integrations (Trakt, Simkl) — with no platform-specific code inside Rust.
Rust never calls the network. Instead, the engine emits typed effects that the host platform (Kotlin on Android, or a native Rust runtime on desktop) executes and reports back. This keeps the same crate portable across Android (JNI), desktop (UniFFI), and future targets (WASM).
Architecture
The Effect Loop
Host (Kotlin / native) → dispatch(action_json)
← { state, effects: [{ id, type, payload }] }
Host → executes each effect (HTTP / storage / player / ...)
→ completeEffect({ effectId, result })
← { state, effects: [...] }
The host owns all I/O. The Rust engine owns all decisions.
Binding Layers
┌─────────────────────────────────────────────┐
│ fluxa-core (Rust) │
│ │
│ headless_engine ← domain modules │
│ ↓ │
│ ┌─────────────┬──────────────┐ │
│ │ JNI (jni) │ UniFFI │ │
│ │ Android │ Desktop/WASM │ │
│ └─────────────┴──────────────┘ │
└─────────────────────────────────────────────┘
JNI bindings are compiled under the native feature (default). UniFFI bindings are always compiled and are the long-term cross-platform target.
What's Inside
| Module | Responsibility |
|---|---|
headless_engine |
Central state machine — dispatches actions, owns pending effects |
addon_protocol |
Manifest URL normalisation, resource URL construction, manifest merging |
stream_policy |
Stream selection, magnet building, audio/subtitle preference matching |
player_policy |
Backend selection (ExoPlayer / MPV / external), track state |
player_flow |
Playback state machine (load → select → play → scrobble) |
content_identity |
ID parsing and normalisation (IMDB, TMDB, Kitsu, episode locators) |
home_ranking |
Billboard and shelf ordering, continue-watching deduplication |
library_state |
Continue-watching badge computation, next-episode resolution |
profile_contract |
Profile activation, auth token merging, settings migration |
profile_prefs |
Typed read of user preferences from raw profile JSON |
search_plan |
Search query planning, result grouping, discover sort |
calendar_plan |
Calendar item filtering, widget rows, release notifications |
external_sync |
Trakt and Simkl API response parsing and history mapping |
addon_store |
Addon search policy, CloudStream repo URL normalisation |
addon_resource |
Addon HTTP response classification (success / empty / error) |
intro_segments |
introdb.app and AniSkip segment parsing, deduplication |
dolby_vision_rpu |
Dolby Vision RPU metadata extraction for HDR stream selection |
platform_plan |
Season/episode navigation planning for the detail screen |
tmdb_plan |
TMDB ID resolution hints, trailer mapping |
discovery_plan |
Discover catalog request planning |
watchlist_plan |
Watchlist toggle, offline grouping, progress merging |
Building
Prerequisites
- Rust toolchain (stable) — install via rustup
- For Android targets, the NDK and cross-compilation targets:
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
Library
cargo build --release
Tests
cargo test
Android (via Fluxa)
The Android app builds this crate as part of its Gradle build. See the Fluxa repo for the full build setup.
UniFFI bindings (desktop)
cargo build --release --features uniffi-cli
cargo run --features uniffi-cli --bin uniffi-bindgen generate \
--library target/release/libfluxa_core.so \
--language kotlin \
--out-dir bindings/
Used By
- Fluxa — Android media hub (Kotlin + Jetpack Compose)
- FluxaDesktop — Desktop media hub (Rust + Tauri)