Library / SDK
Stremio/stremio-core avatar
Stremio/stremio-core

stremio-core: the releases belong to the web bridge, and a test double sets the defaults

⚛️ The Stremio Core: types, addon system, UI models, core logic

2,563 stars286 forksRustMIT

At a glance

What is it?
The shared Rust engine behind Stremio's applications, built on an Elm-style unidirectional loop where each platform implements four capabilities behind one trait. Its published releases are all for the WebAssembly bridge rather than the library, one feature flag is documented as a compile error on the web target, and the crate's default feature set is left switched off because a mutex guard in the test environment is not thread-safe.
Who is it for?
This crate is worth reading if you are building an application on top of an addon protocol and want the state model, the runtime loop and the protocol client already designed, particularly because the architecture documentation explains the whole design in four steps. Three things to check before you adopt it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • Stremio/stremio-core2,563 ★ · +126
Star history
Repository2026-09-302026-11-13
Stremio/stremio-core2.4k2.6k

126 Stars in the last 44 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The crate's default features are off because a test double cannot be moved between threads

One of the most honest comments in the manifest explains a production decision by pointing at the test suite. The crate defines a feature that adds thread-safety bounds to the futures returned by its environment trait, which is required for platforms that cannot move work across threads. The comment above the feature list says it should be enabled by default, and then says why it is not: the test environment used by the unit tests holds a mutex guard, and a guard is not movable between threads, so enabling it would break the tests. The safer default line is present in the file, commented out, directly above the empty default that shipped instead. So the shape of the library's public surface for anyone building a native application is currently decided by a limitation of a fake used only in tests, and the manifest says so in three lines:

code
# TODO: env-future-send should be enabled by default
# but our `TestEnv` for `unit_tests` uses a MutexGuard which is not Send.
# default = ["env-future-send"]
default = []

Two version lines live here, and the releases are the web bridge's

Follow the version numbers and you end up in the wrong repository twice. The library's own manifest declares version 0.1.0. The three most recent releases are all named for the WebAssembly bridge, in a 0.64 line, and their timestamps track commits to the main repository rather than to the library. So a user asking what version of the core is current finds a number around 0.64 that describes a different artefact, and a user reading the manifest finds 0.1.0 that has probably not moved in a long time. The default branch compounds it by being called development rather than main, so a clone lands on the working branch rather than on whatever the releases were cut from. Three repositories are published from this workspace: the bridge, the derive macro, and a small crate for compactly encoding watched state.

One feature flag is documented as a compile error on the web target

The feature table has four entries and the third is the interesting one. The environment futures can optionally carry a bound requiring that they be safe to move between threads, and the same feature is described in the manifest as required for environments that do not support that, which is a double negative that costs a reader a moment. Then the comment continues: enabling it for the web target will cause a compile error, and it links to an open issue on the bindings project for exactly that problem. So this is not a performance knob or a convenience toggle, it is a portability fork between targets that cannot both be satisfied at once. A native build can turn it on, a browser build must not, and the default state is off for everyone because of the test environment described earlier.

The whole platform surface is four capabilities behind one trait

The architecture is borrowed from a functional approach where state flows one way and side effects are explicit, and the page reduces the entire platform obligation to a single sentence: each platform implements the environment trait, which covers HTTP fetching, storage, task execution and time. Everything else is shared. The loop is described in four steps: the user interface dispatches an action to the runtime, the runtime routes it as a message to the state models, the models update themselves and return effects which are explicit descriptions of side effects to run, those effects execute through the environment trait, and changed models are announced back to the interface as new state while noteworthy happenings are emitted as events. That is the whole contract between a platform and this library, and it is why the project can say the interfaces are thin layers on top and this crate is the application.

One dependency is pinned exactly, and another is a fork with upstream pull requests in a comment

Two entries in the dependency list are worth reading closely. One is pinned to a single exact version with an equality constraint rather than a range, while every neighbouring dependency uses a caret or a wildcard. That is a deliberate choice to control one dependency at the lockfile level while leaving the rest free. The other is more unusual: instead of the upstream package, the manifest depends on a project-local namespace, and above it sit two comments saying to keep track of two open pull requests on the upstream repository, with links to both. So the crate uses a fork as a workaround for a fix that has not merged, and it has kept the links to the upstream discussion in the dependency list where the next maintainer will see them. The serialisation stack around it is correspondingly wide, with separate crates for path-to-error, URL parameters, bencode encoding, hex encoding, and a combining adapter with macros.

The release profile optimizes for size, and one crate exists to save bits

The release profile sets link-time optimisation on and drops the optimisation level to the size preset rather than the speed preset. For a library that ships to a web worker that is the obvious choice, and the reason shows up in a tip rather than in the profile: compiled output for the web target can get large, particularly when serialisation traits are derived where nothing needs them, and the page names the tool to use, a size analyser, along with the instruction to find the biggest contributors. The same reasoning produced a whole crate in the workspace whose stated purpose is a compact encoding of per-video watched state, which is a bitfield rather than a collection of flags. Two size decisions and one measurement tool, for a state model that has to carry watched state for every item in a library.

The message enums are declared as the public API surface

The tips section contains the project's own compatibility statement. New actions are defined in one file, and the message enums in that file and its sibling are described as the public API surface of the crate. That is a strong claim to make about a file of enum definitions, and it has a direct consequence for anyone depending on it: adding a variant is not an additive change for a caller that matches on the enum exhaustively, and the runtime routes on those types. It also explains the file layout, where the action, message and event types sit together under the runtime directory and the models are annotated with a derive macro from a separate proc-macro crate. A re-export of that macro is itself behind a feature flag, so a consumer that wants to compose its own models on top of the runtime has to opt in to it.

The Android bindings are archived while the web bridge ships releases

The ecosystem table lists four related repositories, and one of them is marked archived: the Kotlin bindings for Android. The others are the web interface driven through the bridge, a toolkit for building addons in Node, and a separate search suggestions engine used by one of the state models. The archived entry is the interesting one because it lines up with the release feed. If the Android binding is archived and the releases are all for the web bridge, then the actively published surface of this project is a browser target, and the Android path it used to serve has been retired. The project does not say why, and the page's own framing, that it integrates into any codebase across the stack, sits slightly awkwardly next to an archived binding for the platform with the largest mobile share.

Editorial conclusion

This crate is worth reading if you are building an application on top of an addon protocol and want the state model, the runtime loop and the protocol client already designed, particularly because the architecture documentation explains the whole design in four steps. Three things to check before you adopt it. Decide which version you are actually tracking, because the library's own manifest version and the published release numbers belong to different products and the default branch is not called main. Read the feature flags before you compile, because one of them is documented as a compile error on the web target and another is defaulted off for a reason that has nothing to do with production, namely a limitation in the test environment. And plan for the message enums as your compatibility surface, because the project states plainly that those enums are the public API, which means adding a variant is a breaking change for anyone who matches on them exhaustively.

Frequently asked questions

Is Stremio legal in the USA?

This repository does not address that, and it is a library rather than an application. It contains the shared state models, the addon protocol client and the runtime that Stremio's own apps are built on. It ships no application, no streaming sources and no addons of its own, so anything about the content or terms of a particular addon or service is outside what this code says.

Which Stremio version is the best?

Nothing here compares versions of the application. The repository publishes releases for its web assembly bridge, currently in a 0.64 line, while the core library's own version in its manifest is 0.1.0. The default branch is named development rather than main, so a clone lands on the working branch.

What is a better alternative to Stremio?

That question is about media centre applications, and this repository is the shared engine one of them is built on, so it does not answer it. What it does say is that the engine integrates into any codebase, that its types alone can be used by addon authors, and that the full state model can serve as the backbone of a whole application.

Does stremio-core talk to streaming servers?

It implements the addon protocol client in two forms, modern JSON over HTTP or HTTPS plus an adapter for the older JSON-RPC style. The state models include a streaming server model, and the addon protocol is how a host application asks an addon for playable items. The crate itself hosts and serves no content.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. Stremio/stremio-core on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/stremio-stremio-core.svg)](https://hysenlabs.com/projects/stremio-stremio-core)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/stremio-stremio-core.svg)](https://hysenlabs.com/projects/stremio-stremio-core)

Was this useful?