# Stremio Web Architecture: How the React SPA Is Structured

> Explore Stremio Web architecture a modular React SPA. Discover its core bootstrapping service context custom router and UI components organized for clear logic separation.

- Repository: [Stremio/stremio-web](https://github.com/Stremio/stremio-web)
- Tags: architecture
- Published: 2026-05-23

---

**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`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/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:

```javascript
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`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/src/router/Router/Router.js) and processes URL fragments (e.g., `#/discover`, `#/library`).

Route definitions live in [`routerViewsConfig.js`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/src/router/Router/routeConfigForPath.js) matches the current path to a configuration, while [`src/router/Router/urlParamsForPath.js`](https://github.com/Stremio/stremio-web/blob/main/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:

```javascript
// 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`](https://github.com/Stremio/stremio-web/blob/main/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/`:

- **`useBinaryState`**: Manages boolean toggles with explicit open/close handlers from [`src/common/useBinaryState.js`](https://github.com/Stremio/stremio-web/blob/main/src/common/useBinaryState.js)
- **`useProfile`**: Watches user settings and authentication state from [`src/common/useProfile.js`](https://github.com/Stremio/stremio-web/blob/main/src/common/useProfile.js)
- **`useTranslate`**: Wraps `react-i18next` for UI translations from [`src/common/useTranslate.js`](https://github.com/Stremio/stremio-web/blob/main/src/common/useTranslate.js)

Example implementation of `useBinaryState`:

```javascript
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`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/src/App/App.js) bootstraps the core (`useCore`), services, and routing infrastructure.
- **Routing**: Custom hash-based router (`stremio-router`) uses [`routeConfigForPath.js`](https://github.com/Stremio/stremio-web/blob/main/routeConfigForPath.js) and [`urlParamsForPath.js`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/src/router/Router/Router.js). This hash-based router monitors URL fragments (e.g., `#/library`) and matches them against descriptors in [`routerViewsConfig.js`](https://github.com/Stremio/stremio-web/blob/main/routerViewsConfig.js) using regular expressions. The system supports dynamic URL parameters via [`urlParamsForPath.js`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/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`.