A stremio client with slightly different stream server
Dart
0
928 commits
updated Sep 17, 2026

A native, cross-platform Stremio client built on a Rust core with a Flutter UI.
Xtremio is the client half of a two-part project. The other half is
zond/stream-server, a headless
torrent-streaming server written in Rust, which Xtremio embeds in its own
process. It pairs that with
stremio-core -- the official Rust
engine for addons, catalogs, library and playback state, built here from a
fork -- and
media_kit/libmpv for playback.
All of this is built and runs today. docs/STATUS.md is the screen-by-screen inventory; a feature with a design document links it.
stream-server runs
in-process on loopback: nothing to ship beside the app, launch, or keep
alive on mobile. In the default layout a title's sources are one row per
release rather than one per addon offering it, in a section per resolution,
ranked by peers per megabyte unless another order is picked; a torrent
starts behind a card that says what it is doing -- checking, finding peers,
buffering -- instead of a spinner./proxy. The player screen becomes
a remote, and a cast does not binge: the end of an episode on the
television never starts the next one. What it refuses, why it refuses
rather than guesses, and the fact that no real receiver has confirmed it
yet are in docs/CASTING.md.stremio:// link; where Xtremio can register that scheme it opens
that addon's details screen, and nothing is installed until the button
waiting there is pressed. The contract in full, and the registration per
platform, is in docs/DEEP_LINKS.md.Every version tag builds Linux, Windows, macOS and both Android ABIs and attaches them to a GitHub Release -- that is where a build comes from. Nothing is tagged yet, so until the first one that page is empty and building it yourself is the only way. Two things about those builds are worth knowing before installing, and the release notes say both: the APKs are signed with the Flutter template's debug key, and the macOS build is unsigned.
flutter pub get
make run DEVICE=linux # flutter run -d linux, stamped with version and commit
make linux # a release build; also apk, apk-tv, apk-split, macos, ios (compile check)
The Makefile adds two --dart-defines so the Diagnostics screen can say which
build it is, and its APK targets also set the ABI and a version code that
Android installs over an APK from make apk-split. Plain
flutter run -d <device> works too and reports app: unknown. A build needs
Flutter stable (CI uses 3.47.1) and a Rust toolchain no older than
rust-version in rust/Cargo.toml (1.97.1): the Rust crate is compiled by
the build itself, through cargokit. Linux desktop also needs clang, cmake,
ninja, pkg-config, GTK 3 dev libraries, and libmpv-dev (media_kit links
libmpv); Android has a document of its own, ANDROID.md.
Everything else a dev machine wants is in docs/OPERATIONS.md.
┌──────────────────────────────────────────────────────────────┐
│ Flutter UI (this repo) — screens, navigation, playback UI │
├──────────────────────────────────────────────────────────────┤
│ Dart ⇄ Rust FFI (flutter_rust_bridge), crate in rust/ │
│ • stremio-core → addons, catalogs, search, library, │
│ account, playback state (the "brain") │
│ • stream-server → embedded: settings, stats, storage and │
│ downloads as FFI calls │
├──────────────────────────────────────────────────────────────┤
│ media_kit / libmpv — fetches the media over loopback HTTP, │
│ decodes and renders it (direct play; codecs and subtitles │
│ on-device) │
└──────────────────────────────────────────────────────────────┘
The UI stays thin: discovery/library/addon logic lives in stremio-core, the
bytes come from stream-server, and the client's job is presentation plus
driving libmpv. stream-server runs in-process: the Rust crate in rust/
links it as a library and starts it on its own thread with its own runtime,
bound to 127.0.0.1 on a port the OS picks and retargeting stremio-core at
the address it reads back, so no sidecar binary ships and no fixed port is
lost to a desktop Stremio. The Dart side never speaks HTTP to it: libmpv
fetches the media routes, the app's own questions -- settings, a torrent's
stats, storage, downloads -- are FFI calls into the server's library API, and
stremio-core's requests to it carry a per-launch bearer token that only the
Rust side holds. The only HTTP it serves beyond loopback is the media listener
a cast session turns on and off. Because a capable on-device player handles
codecs and subtitles, the server never transcodes -- it just gets bytes onto an
HTTP connection. Settings can point stremio-core at a remote streaming server
by URL, and torrents then play straight off that one; the embedded server
still starts and still fronts an addon's direct links. The embedded one is
the default.
How that bridge is built, what crosses it and what every field of the state means is in docs/ARCHITECTURE.md.
Every git dependency in rust/Cargo.toml is pinned to a rev with its
reason beside it: the three forks are listed in
docs/ARCHITECTURE.md.
The hard constraint is BitTorrent: the streaming path needs raw TCP/UDP sockets, a local HTTP server, disk cache, and libmpv. That decides everything.
| Platform | Support | Notes |
|---|---|---|
| Linux (desktop) | ✅ First-class | The easiest target; video is software-rendered until media_kit's Linux renderer lands (docs/OPERATIONS.md). |
| Windows (desktop) | ✅ Built weekly in CI (build.yml) | Flutter desktop, media_kit and native Rust, as on Linux; registering stremio:// needs an installer and there is none (docs/DEEP_LINKS.md). |
| macOS (desktop) | ✅ Built weekly in CI (build.yml) | Native Rust + media_kit; unsigned, and needs a Mac to build yourself -- there is none in the project. |
| Android | ✅ Supported | Rust cross-compiles to the NDK and is embedded as a native lib; the primary mobile target (ANDROID.md). |
| Android TV / Google TV | ✅ Supported | The same app, not a separate build; install the APK for the ABI the box reports -- a Chromecast with Google TV is 32-bit, make apk-tv (ANDROID.md). |
| iOS | ❌ Does not build today | CI compiles it and it fails in an upstream crate (librqbit-dualstack-sockets 0.7.0 calls a socket2 method iOS does not have). Past that, there is no signing identity here, the App Store is out on GPL-3 (see License), and iOS throttles background work. |
| Web | ❌ Not possible | A browser cannot do BitTorrent -- no raw sockets, no local server, no libmpv. A thin client onto a separate server is a different architecture, not this app. |
What is genuinely not built:
| Document | What is in it |
|---|---|
| docs/STATUS.md | What is built today, screen by screen. |
| docs/ARCHITECTURE.md | How the Rust core is wired in: the bridge, what crosses it as JSON, every model field, the pinned forks, and what the app reads from the settings. Its design notes are docs/phase3-design.md. |
| docs/OPERATIONS.md | What to run before a commit, how to see video play, what the server's storage costs, and getting a log off a device. |
| ANDROID.md | Building, running and verifying on Android and Android TV: prerequisites, the APK, the manifest decisions, the emulators, a real box. |
| docs/CASTING.md | The cast button: what it hands a receiver untouched, and every rule it refuses on. |
| docs/ADDONS.md | How each installed addon has been answering, and the verdict the Installed tab reads off that record. |
| docs/DEEP_LINKS.md | What a stremio:// link may and may not do, and how the scheme is registered on each platform. |
| AGENTS.md | What a change has to satisfy here; see Contributing. |
AGENTS.md is what a change has to satisfy here: single-concept
commits, the verification that gates them, and the rules a real television
taught us. Read it before opening a pull request. CI runs the same checks on every push
to main and every pull request: formatting, analysis, the Flutter and Rust
suites, cargo clippy -D warnings, a cargo check of the core for 32-bit
Android, and a check that the flutter_rust_bridge bindings regenerate to
what is committed (AGENTS.md
has the commands).
The source here is MIT (LICENSE). A compiled Xtremio embeds
stream-server, which links unrar-rs (GPL-3.0-or-later) so a RAR archive in
a torrent plays: distributed binaries are GPL-3.0-or-later
(LICENSE-GPL-3.0). unrar-rs asks that a binary reproduce its
licence file, the unRAR restriction included, so that text ships in the app too
(LICENSE-unrar-rs; Settings → About → Open source
licences). stream-server with default-features = false drops both.
928 commits
Dart
78.5%
Rust
18.3%
Kotlin
1.3%
A stremio client with slightly different stream server
Dart
0
928 commits
updated Sep 17, 2026

A native, cross-platform Stremio client built on a Rust core with a Flutter UI.
Xtremio is the client half of a two-part project. The other half is
zond/stream-server, a headless
torrent-streaming server written in Rust, which Xtremio embeds in its own
process. It pairs that with
stremio-core -- the official Rust
engine for addons, catalogs, library and playback state, built here from a
fork -- and
media_kit/libmpv for playback.
All of this is built and runs today. docs/STATUS.md is the screen-by-screen inventory; a feature with a design document links it.
stream-server runs
in-process on loopback: nothing to ship beside the app, launch, or keep
alive on mobile. In the default layout a title's sources are one row per
release rather than one per addon offering it, in a section per resolution,
ranked by peers per megabyte unless another order is picked; a torrent
starts behind a card that says what it is doing -- checking, finding peers,
buffering -- instead of a spinner./proxy. The player screen becomes
a remote, and a cast does not binge: the end of an episode on the
television never starts the next one. What it refuses, why it refuses
rather than guesses, and the fact that no real receiver has confirmed it
yet are in docs/CASTING.md.stremio:// link; where Xtremio can register that scheme it opens
that addon's details screen, and nothing is installed until the button
waiting there is pressed. The contract in full, and the registration per
platform, is in docs/DEEP_LINKS.md.Every version tag builds Linux, Windows, macOS and both Android ABIs and attaches them to a GitHub Release -- that is where a build comes from. Nothing is tagged yet, so until the first one that page is empty and building it yourself is the only way. Two things about those builds are worth knowing before installing, and the release notes say both: the APKs are signed with the Flutter template's debug key, and the macOS build is unsigned.
flutter pub get
make run DEVICE=linux # flutter run -d linux, stamped with version and commit
make linux # a release build; also apk, apk-tv, apk-split, macos, ios (compile check)
The Makefile adds two --dart-defines so the Diagnostics screen can say which
build it is, and its APK targets also set the ABI and a version code that
Android installs over an APK from make apk-split. Plain
flutter run -d <device> works too and reports app: unknown. A build needs
Flutter stable (CI uses 3.47.1) and a Rust toolchain no older than
rust-version in rust/Cargo.toml (1.97.1): the Rust crate is compiled by
the build itself, through cargokit. Linux desktop also needs clang, cmake,
ninja, pkg-config, GTK 3 dev libraries, and libmpv-dev (media_kit links
libmpv); Android has a document of its own, ANDROID.md.
Everything else a dev machine wants is in docs/OPERATIONS.md.
┌──────────────────────────────────────────────────────────────┐
│ Flutter UI (this repo) — screens, navigation, playback UI │
├──────────────────────────────────────────────────────────────┤
│ Dart ⇄ Rust FFI (flutter_rust_bridge), crate in rust/ │
│ • stremio-core → addons, catalogs, search, library, │
│ account, playback state (the "brain") │
│ • stream-server → embedded: settings, stats, storage and │
│ downloads as FFI calls │
├──────────────────────────────────────────────────────────────┤
│ media_kit / libmpv — fetches the media over loopback HTTP, │
│ decodes and renders it (direct play; codecs and subtitles │
│ on-device) │
└──────────────────────────────────────────────────────────────┘
The UI stays thin: discovery/library/addon logic lives in stremio-core, the
bytes come from stream-server, and the client's job is presentation plus
driving libmpv. stream-server runs in-process: the Rust crate in rust/
links it as a library and starts it on its own thread with its own runtime,
bound to 127.0.0.1 on a port the OS picks and retargeting stremio-core at
the address it reads back, so no sidecar binary ships and no fixed port is
lost to a desktop Stremio. The Dart side never speaks HTTP to it: libmpv
fetches the media routes, the app's own questions -- settings, a torrent's
stats, storage, downloads -- are FFI calls into the server's library API, and
stremio-core's requests to it carry a per-launch bearer token that only the
Rust side holds. The only HTTP it serves beyond loopback is the media listener
a cast session turns on and off. Because a capable on-device player handles
codecs and subtitles, the server never transcodes -- it just gets bytes onto an
HTTP connection. Settings can point stremio-core at a remote streaming server
by URL, and torrents then play straight off that one; the embedded server
still starts and still fronts an addon's direct links. The embedded one is
the default.
How that bridge is built, what crosses it and what every field of the state means is in docs/ARCHITECTURE.md.
Every git dependency in rust/Cargo.toml is pinned to a rev with its
reason beside it: the three forks are listed in
docs/ARCHITECTURE.md.
The hard constraint is BitTorrent: the streaming path needs raw TCP/UDP sockets, a local HTTP server, disk cache, and libmpv. That decides everything.
| Platform | Support | Notes |
|---|---|---|
| Linux (desktop) | ✅ First-class | The easiest target; video is software-rendered until media_kit's Linux renderer lands (docs/OPERATIONS.md). |
| Windows (desktop) | ✅ Built weekly in CI (build.yml) | Flutter desktop, media_kit and native Rust, as on Linux; registering stremio:// needs an installer and there is none (docs/DEEP_LINKS.md). |
| macOS (desktop) | ✅ Built weekly in CI (build.yml) | Native Rust + media_kit; unsigned, and needs a Mac to build yourself -- there is none in the project. |
| Android | ✅ Supported | Rust cross-compiles to the NDK and is embedded as a native lib; the primary mobile target (ANDROID.md). |
| Android TV / Google TV | ✅ Supported | The same app, not a separate build; install the APK for the ABI the box reports -- a Chromecast with Google TV is 32-bit, make apk-tv (ANDROID.md). |
| iOS | ❌ Does not build today | CI compiles it and it fails in an upstream crate (librqbit-dualstack-sockets 0.7.0 calls a socket2 method iOS does not have). Past that, there is no signing identity here, the App Store is out on GPL-3 (see License), and iOS throttles background work. |
| Web | ❌ Not possible | A browser cannot do BitTorrent -- no raw sockets, no local server, no libmpv. A thin client onto a separate server is a different architecture, not this app. |
What is genuinely not built:
| Document | What is in it |
|---|---|
| docs/STATUS.md | What is built today, screen by screen. |
| docs/ARCHITECTURE.md | How the Rust core is wired in: the bridge, what crosses it as JSON, every model field, the pinned forks, and what the app reads from the settings. Its design notes are docs/phase3-design.md. |
| docs/OPERATIONS.md | What to run before a commit, how to see video play, what the server's storage costs, and getting a log off a device. |
| ANDROID.md | Building, running and verifying on Android and Android TV: prerequisites, the APK, the manifest decisions, the emulators, a real box. |
| docs/CASTING.md | The cast button: what it hands a receiver untouched, and every rule it refuses on. |
| docs/ADDONS.md | How each installed addon has been answering, and the verdict the Installed tab reads off that record. |
| docs/DEEP_LINKS.md | What a stremio:// link may and may not do, and how the scheme is registered on each platform. |
| AGENTS.md | What a change has to satisfy here; see Contributing. |
AGENTS.md is what a change has to satisfy here: single-concept
commits, the verification that gates them, and the rules a real television
taught us. Read it before opening a pull request. CI runs the same checks on every push
to main and every pull request: formatting, analysis, the Flutter and Rust
suites, cargo clippy -D warnings, a cargo check of the core for 32-bit
Android, and a check that the flutter_rust_bridge bindings regenerate to
what is committed (AGENTS.md
has the commands).
The source here is MIT (LICENSE). A compiled Xtremio embeds
stream-server, which links unrar-rs (GPL-3.0-or-later) so a RAR archive in
a torrent plays: distributed binaries are GPL-3.0-or-later
(LICENSE-GPL-3.0). unrar-rs asks that a binary reproduce its
licence file, the unRAR restriction included, so that text ships in the app too
(LICENSE-unrar-rs; Settings → About → Open source
licences). stream-server with default-features = false drops both.
928 commits
Dart
78.5%
Rust
18.3%
Kotlin
1.3%