Skip to main content
Stremio Web is a React single-page application (SPA) bundled with Webpack. Business logic lives in the stremio-core-web WebAssembly module; the UI layer in src/ is primarily responsible for rendering state and dispatching actions to the core.

Source tree overview

src/
├── index.js            # Application entry point
├── index.html          # HTML template
├── modules.d.ts        # Global module type declarations
├── types/              # Shared TypeScript type definitions
├── App/                # Root component and router configuration
├── routes/             # Page-level route components
├── components/         # Reusable UI components
├── services/           # Application services (Core, Chromecast, etc.)
├── common/             # Shared hooks, utilities, and constants
└── router/             # Custom client-side router

src/App/

The App/ directory contains the root React component and the global router configuration.
FilePurpose
App.jsRoot component. Initialises services and renders the router.
routerViewsConfig.jsDeclares which route components are mounted in which router view layers.
DeepLinkHandler.jsHandles deep-link URLs (e.g. stremio:// scheme) and translates them to in-app navigation.
SearchParamsHandler.jsReads and propagates URL search parameters on navigation.
ServicesToaster.jsSubscribes to service events and displays toast notifications.
withProtectedRoutes.jsHOC that redirects unauthenticated users away from protected routes.
ErrorDialog/Full-screen error dialog rendered when a fatal error occurs.
ShortcutsModal/Modal that displays all registered keyboard shortcuts.
UpdaterBanner/Banner that prompts the user to reload when a new version is available.

Router view layers

routerViewsConfig.js defines five view layers, each rendered on top of the previous. This allows overlapping routes (e.g. a player on top of a catalog):
  1. Board — the home screen
  2. Main views — Intro, Discover, Library, Calendar, Search
  3. MetaDetails — content detail overlay
  4. Overlay views — Addons, Settings
  5. Player — full-screen video player

src/routes/

Each subdirectory is a page-level component mounted by the router when its URL pattern matches.
RoutePathDescription
Board//Home screen with catalog rows
Intro//introOnboarding and login screen
Discover//discoverBrowse catalogs by type and genre
Library//library, /continuewatchingUser library and continue-watching list
Calendar//calendarEpisode release calendar
Search//searchFull-text search across all addons
MetaDetails//detailContent detail view (synopsis, streams, cast)
Addons//addonsAddon management
Settings//settingsApplication settings
Player//playerVideo player
NotFound/*404 fallback

src/components/

Shared UI components used across multiple routes. All components are re-exported from index.ts.
ComponentDescription
MetaItem/Poster card for a single piece of content
MetaRow/Horizontal scrolling row of MetaItems
MetaPreview/Expanded preview panel for selected content
LibItem/Library entry card
ContinueWatchingItem/Card variant with playback progress
Video/Video playback element, wraps stremio-video
Image/Lazy-loading image with fallback
ComponentDescription
Button/Base button with consistent focus/hover styles
TextInput/Controlled text input
NumberInput/Numeric input with increment/decrement
Checkbox/Checkbox input
Toggle/Binary on/off toggle
RadioButton/Radio button
Slider/Range slider
Multiselect/Multi-option select dropdown
MultiselectMenu/Menu variant of the multiselect
Chips/Horizontal chip/tag selector
ColorInput/Color picker input
SearchBar/Search input with clear button
ComponentDescription
AddonDetailsModal/Modal showing addon info and install controls
EventModal/Generic event/announcement modal
SharePrompt/Share-to prompt overlay
Transition/Animated mount/unmount wrapper
DelayedRenderer/Defers rendering until after a delay
HorizontalScroll/Scroll container with arrow navigation
ShortcutsGroup/Rendered group of keyboard shortcut entries

src/services/

Services are long-lived singletons initialised at app startup and provided to the component tree via ServicesContext.

Core

Wraps @stremio/stremio-core-web. Manages the WebAssembly core lifecycle and exposes a transport object used to dispatch actions and getState from any model. Components subscribe to state via the useModelState hook in common/.

Shell

Communicates with the native Stremio shell (desktop app wrapper) when running inside it. Provides APIs for opening external links, controlling the window, and handling native events.

Chromecast

Manages the Google Cast SDK lifecycle. Initialises the cast session, handles device discovery, and bridges play/pause/seek commands between the UI and a cast receiver.

KeyboardShortcuts

Registers global keyboard event listeners and maps key combinations to application actions. Shortcuts are declaratively defined and displayed via the ShortcutsModal.

ServicesContext

ServicesContext/ exposes a useServices() hook that components use to access any service:
const { core, shell, chromecast } = useServices();

State management

Stremio Web does not use Redux or a similar global store. State is owned by stremio-core-web (the WASM module) and fetched on demand:
  1. A route component calls useModelState({ model: 'discover', ... }).
  2. useModelState calls core.transport.getState('discover') to read the initial state.
  3. When the core emits a NewState event, the hook re-fetches and updates local React state using setState.
  4. Actions are dispatched with core.transport.dispatch({ action: 'LoadDiscover', ... }, 'discover').
This keeps all business logic and side effects inside the WASM core while the React layer remains a pure rendering layer.

src/common/

Shared utilities, constants, and custom React hooks used across the codebase.

Hooks

HookDescription
useModelStateSubscribes a component to a stremio-core-web model
useProfileReturns the current user profile from the core
useSettingsReturns application settings
useStreamingServerReturns streaming server status and settings
useNotificationsReturns notification data
useShellReturns the Shell service instance
useBinaryStateBoolean state with setTrue / setFalse helpers
useFullscreenFullscreen API wrapper
useIntervalsetInterval in a hook
useTimeoutsetTimeout in a hook
useAnimationFramerequestAnimationFrame loop hook
useOutsideClickFires a callback when a click occurs outside a ref
useOnScrollToBottomFires a callback when the user scrolls to the bottom
useOrientationReturns device orientation
usePWAPWA install prompt handling
useLiveRefRef that always holds the latest value of a variable
useLanguageSortingReturns a comparator for sorting by current language
useTranslatei18next translation hook wrapper
useTorrentTorrent magnet link handling

Utilities

FileDescription
CONSTANTS.jsApplication-wide constants
routesRegexp.jsURL pattern regular expressions for each route
Platform/Platform/browser detection utilities
Shortcuts/Keyboard shortcut definitions
Toast/Imperative toast notification system
Tooltips/Tooltip positioning utilities
CoreSuspender.jsReact Suspense integration for the core WASM module
getVisibleChildrenRange.jsCalculates which children are visible in a scroll container
comparatorWithPriorities.jsSorting comparator with priority weights

src/router/

A custom client-side router built for Stremio’s layered view model. It does not use React Router.
ModuleDescription
Router/Core router component. Matches the current URL against view configs and mounts the appropriate route components.
Route/Renders a single route. Passes URL params as props to the route component.
Modal/Router-managed modal layer. Modals are pushed onto a stack and dismissed in order.
ModalsContainerContext/Context providing access to the modal stack.
RouteFocusedContext/Context that exposes whether the current route is the focused (top-most visible) layer. Used by useModelState to pause updates for background routes.
The stremio-router path alias (configured in webpack.config.js and tsconfig.json) maps to src/router/, allowing imports like:
const { useRouteFocused } = require('stremio-router');

Build system

The build is fully managed by Webpack 5, configured in webpack.config.js.

Loaders

LoaderHandles
babel-loader.js files — transpiles with @babel/preset-env and @babel/preset-react
ts-loader.ts / .tsx files — TypeScript compilation
less-loader + css-loader + postcss-loader.less files — compiles Less, applies autoprefixer and cssnano
thread-loaderRuns all of the above in a worker thread pool for faster builds

CSS modules

All .less files use CSS Modules with local scoping. Class names are hashed in the format [local]-[hash:base64:5].

Path aliases

AliasResolves to
stremio/*src/*
stremio-routersrc/router/

Output

Production builds output to build/. All script and style filenames include the current Git commit hash, which acts as a cache-busting mechanism. A Workbox service worker is generated in production mode for offline support.

Environment variables

The following environment variables are injected via webpack.EnvironmentPlugin:
VariableDefaultDescription
VERSIONFrom package.jsonApplication version string
COMMIT_HASHGit HEAD hashCurrent commit hash
DEBUGtrue in devEnables debug logging
SERVICE_WORKER_DISABLEDfalseDisables the PWA service worker
SENTRY_DSNnullSentry error reporting DSN

Build docs developers (and LLMs) love