Limeplay - Open Source Video Player UI ComponentsLimeplay

Concepts

The key ideas behind Limeplay's architecture.

Feature Model

Limeplay is built from features. A feature owns one capability, such as playback, volume, timeline, playlist, player setup, or asset loading.

Each feature can provide:

  • A namespaced store slice, such as playback.paused or volume.level.
  • A setup component that syncs native media or Shaka Player state.
  • Typed events for state changes, such as play, seek, or assetloaded.

You compose the features you need with createMediaKit.

lib/media.ts
"use client"

import { createMediaKit } from "@/components/limeplay/media-provider"
import { mediaFeature } from "@/hooks/limeplay/use-media"
import { playbackFeature } from "@/hooks/limeplay/use-playback"
import { volumeFeature } from "@/hooks/limeplay/use-volume"

export const media = createMediaKit({
  features: [mediaFeature(), playbackFeature(), volumeFeature()] as const,
})

export const { MediaProvider, useMediaApi, useMediaEvents, useMediaStore } =
  media

Use this page to understand the model. Use the Hooks section when you need exact APIs.

Store

Each MediaProvider creates an isolated Zustand store. Multiple players on the same page do not share state unless you explicitly wire them together.

Read state with selectors so components only re-render for the fields they use.

const paused = usePlaybackStore((state) => state.paused)
const volume = useVolumeStore((state) => state.level)

For imperative code, use the media API returned by your kit.

const api = useMediaApi()

api.setState(({ volume }) => {
  volume.level = 0.5
})

Event And Action Bridge

Limeplay keeps events and actions separate.

  • UI components call actions, such as playback.togglePaused() or timeline.seek().
  • Actions update the native media element or Shaka Player.
  • Native events flow back into feature setup components.
  • Feature setup components update the store and emit typed events.
action native event render update typed event UI ComponentReact Media ElementDOM or Shaka Feature StoreZustand Media Events

Subscribe to events with useMediaEvents.

const events = useMediaEvents()

React.useEffect(() => {
  return events.on("play", () => {
    console.log("playing")
  })
}, [events])

For exact event names and payloads, use the relevant hook docs. Each feature exports its own event type.

Component Hierarchy

Most Limeplay players follow this shape. Blocks package this structure for you; custom players can compose the pieces directly.

MediaProviderStore, events, feature setup RootContainerRoot state attributes PlayerContainerMedia layout Mediavideo or audio element ControlsContainer Playback controls Timeline controls Volume controls FallbackPoster

Source Loading

For blocks, pass content through source and loading behavior through loading. Blocks use use-playback-source, which calls use-asset internally.

Use useAsset directly when you need lower-level source orchestration. Use usePlayer directly only when you intentionally want to bypass asset, playlist, preload, and recovery behavior.

See Usage for the full loading model.

Core Dependencies

On this page