Stremio Web Architecture: How the React SPA Is Structured

Stremio Web is built as a modular single-page React application that separates concerns into a core bootstrapping layer, a service provider context, a custom hash-based router, and reusable UI components, all organized under src/ with clear boundaries between platform integration and presentation logic.

Stremio Web serves as the browser-based interface for the Stremio media streaming ecosystem. Understanding the Stremio Web architecture reveals how the application manages complex state, platform-specific services, and navigation while maintaining a clean separation between the core engine and the React UI layer.

Core Bootstrapping and Platform Integration

The entry point at src/App/App.js initializes the application's foundational systems. It invokes three critical hooks: useCore to boot the Stremio core engine, useProfile to load user preferences, and usePlatform to abstract platform-specific capabilities.

Core-level actions—such as syncing the library or pulling notifications—are dispatched via core.transport.dispatch, while analytics events flow through core.transport.analytics. This creates a strict boundary where the React UI communicates with the underlying Stremio core through a well-defined transport layer rather than direct state mutation.

Service Layer Architecture

Services like Chromecast and Gamepad support are instantiated in App.js and distributed throughout the component tree via the ServicesProvider from stremio/services. This React context pattern ensures that any component can access hardware-specific functionality without prop drilling.

The ServicesToaster component listens for service-related events and renders toast notifications, providing user feedback for background operations like casting initiation or peripheral connections.

To consume a service within a component:

const { useServices } = require('stremio/services');

function MyComponent() {
    const { services } = useServices();
    const playOnChromecast = (url) => services.chromecast.play(url);
    // ...
}

useServices is exported from src/services/index.js and provides access to all instantiated platform services.

Custom Routing System

Unlike standard React Router implementations, Stremio Web uses stremio-router, a custom hash-based routing solution. The router logic resides in src/router/Router/Router.js and processes URL fragments (e.g., #/discover, #/library).

Route definitions live in routerViewsConfig.js as an array of view groups, where each route descriptor specifies a regexp pattern, urlParamsNames array, and target component. When the hash changes, src/router/Router/routeConfigForPath.js matches the current path to a configuration, while src/router/Router/urlParamsForPath.js extracts dynamic segments using the defined parameter names.

The router wraps views in a RouteFocusedProvider to manage focus states for keyboard navigation, and withProtectedRoutes guards sensitive sections behind authentication logic.

Adding a new route requires extending the configuration array:

// src/router/routerViewsConfig.js
const discoverRoutes = [
    {
        regexp: /^\/discover\/?$/,
        urlParamsNames: [],
        component: require('../routes/Discover')
    }
    // Add new route definitions here
];
module.exports = [discoverRoutes, /* other route groups */];

UI Components and Shared Utilities

The presentation layer is organized under src/components/ (housing Video, Slider, NavBar, and other view-specific pieces) and src/common/ (containing hooks, providers, and cross-cutting utilities). The stremio/common package exports UI primitives—including tooltips, modals, and fullscreen handlers—that wrap the router in App.js.

This modular structure allows developers to import standardized interaction patterns, such as the toast notification system via ToastProvider or internationalization via useTranslate, without reimplementing accessibility or animation logic.

Context Providers and React Hooks

Global state management relies on React Context rather than external stores. RouteFocusedContext tracks the currently focused route for accessibility navigation, while ModalsContainerContext maintains a stack of open overlays.

Reusable logic is encapsulated in hooks located in src/common/:

Example implementation of useBinaryState:

const { useBinaryState } = require('stremio/common');
const [isOpen, , close, toggle] = useBinaryState(false);

Platform-Specific Event Handlers

Bridging the browser environment with Stremio's native capabilities, several handler components translate external events into UI actions. DeepLinkHandler and SearchParamsHandler process incoming URLs from the operating system or shell application, converting them into router navigation commands.

File-drop functionality for torrent files is wired directly in App.js through an onFileDrop handler that dispatches StreamingServer actions to the core. This enables seamless torrent streaming without manual file selection dialogs, connecting browser events directly to the Stremio transport layer.

Summary

  • Entry Point: src/App/App.js bootstraps the core (useCore), services, and routing infrastructure.
  • Routing: Custom hash-based router (stremio-router) uses routeConfigForPath.js and urlParamsForPath.js for URL matching and parameter extraction.
  • Services: Hardware abstractions like Chromecast are provided via ServicesProvider context from stremio/services and accessed through the useServices hook.
  • State: React Contexts manage focus (RouteFocusedContext) and modals (ModalsContainerContext), while custom hooks encapsulate reusable logic in src/common/.
  • Structure: Clean separation between src/App/ (orchestration), src/router/ (navigation), src/services/ (platform integration), and src/common/ (UI utilities).

Frequently Asked Questions

How does Stremio Web handle routing without React Router?

Stremio Web uses a custom stremio-router implementation defined in src/router/Router/Router.js. This hash-based router monitors URL fragments (e.g., #/library) and matches them against descriptors in routerViewsConfig.js using regular expressions. The system supports dynamic URL parameters via urlParamsForPath.js and protects routes using the withProtectedRoutes higher-order component.

Where are Chromecast and other device services initialized?

Device services are instantiated in src/App/App.js and supplied through the ServicesProvider context from stremio/services. This makes service instances available throughout the component tree via the useServices hook, allowing any UI component to trigger casting or gamepad interactions without prop drilling.

What pattern does Stremio Web use for global state management?

Rather than Redux or Zustand, Stremio Web relies on React Context for global state. RouteFocusedContext manages navigation focus for accessibility, ModalsContainerContext tracks overlay stacks, and ServicesProvider distributes hardware service instances. Reusable state logic is encapsulated in hooks like useProfile (user data) and useBinaryState (boolean toggles) located in src/common/.

How can I add a new page route to Stremio Web?

Add a route descriptor to the appropriate array in src/router/routerViewsConfig.js. Each descriptor requires a regexp pattern, urlParamsNames array for dynamic segments, and a component reference. The custom router automatically picks up new entries when the hash changes, rendering the component with injected urlParams and queryParams wrapped in a RouteFocusedProvider.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →