> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livepeer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Applications

> Build frontend applications on Livepeer using the React Player and Broadcast components, or integrate directly with hls.js for non-React environments.

export const CenteredContainer = ({children, maxWidth = "800px", padding = "0", preset = "default", width = "", minWidth = "", marginRight = "", marginBottom = "", textAlign = "", style = {}, className = "", ...rest}) => {
  const presets = {
    default: {},
    fitContent: {
      width: "fit-content",
      minWidth: "fit-content"
    },
    readable70: {
      width: "70%",
      minWidth: "fit-content"
    },
    readable80: {
      width: "80%",
      minWidth: "fit-content"
    },
    readable90: {
      width: "90%"
    },
    wide900: {
      maxWidth: "900px"
    }
  };
  const presetStyle = presets[preset] || presets.default;
  return <div className={className} style={{
    maxWidth: presetStyle.maxWidth || maxWidth,
    margin: "0 auto",
    padding: padding,
    ...presetStyle.width ? {
      width: presetStyle.width
    } : {},
    ...presetStyle.minWidth ? {
      minWidth: presetStyle.minWidth
    } : {},
    ...width ? {
      width
    } : {},
    ...minWidth ? {
      minWidth
    } : {},
    ...marginRight ? {
      marginRight
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...textAlign ? {
      textAlign
    } : {},
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const CustomDivider = ({color = "var(--lp-color-border-default)", middleText = "", spacing = "default", style = {}, className = "", ...rest}) => {
  const spacingPresets = {
    default: {
      margin: "24px 0"
    },
    overlap: {
      margin: "-1rem 0 -1rem 0"
    },
    tight: {
      margin: "0 0 -1rem 0"
    },
    section: {
      margin: "0 0 -2rem 0"
    },
    sectionOverlap: {
      margin: "-1rem 0 -2rem 0"
    },
    deepOverlap: {
      margin: "-1rem 0 -1.5rem 0"
    }
  };
  const spacingStyle = spacingPresets[spacing] || spacingPresets.default;
  return <div role="separator" aria-orientation="horizontal" className={className} style={{
    display: "flex",
    alignItems: "center",
    ...spacingStyle,
    fontSize: style?.fontSize || "16px",
    height: "fit-content",
    ...style
  }} {...rest}>
      <span style={{
    marginRight: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
      </span>
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      {middleText && <>
          <Icon icon="circle" size={2} />
          <span style={{
    margin: "0 8px",
    fontWeight: "bold",
    color: color,
    opacity: 0.7
  }}>
            {middleText}
          </span>
          <Icon icon="circle" size={2} />
        </>}
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      <span style={{
    marginLeft: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <span style={{
    display: "inline-block",
    transform: "scaleX(-1)"
  }}>
          <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
        </span>
      </span>
    </div>;
};

<CenteredContainer preset="readable90">
  <Tip>The @livepeer/react package provides Player and Broadcast components that handle ABR selection, WebRTC fallback, and WHIP publishing. For non-React environments, use HLS.js directly with Livepeer playback URLs.</Tip>
</CenteredContainer>

<CustomDivider />

Livepeer provides three frontend integration paths depending on your framework and requirements.

**`@livepeer/react` Player** handles HLS and WebRTC playback with automatic ABR (adaptive bitrate) selection, poster images, and playback metrics. It accepts a `playbackId` from any stream or asset and negotiates the best transport automatically.

**`@livepeer/react` Broadcast** provides browser-based WHIP publishing for live streams. Users can stream directly from the browser without OBS or external encoders.

**HLS.js (non-React)** works with any framework. Livepeer playback URLs are standard HLS manifests; any HLS-compatible player works. Use HLS.js for Vue, Svelte, Angular, or vanilla JavaScript applications.

<CustomDivider />

## Quick start

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
npm install @livepeer/react
```

```tsx theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import * as Player from '@livepeer/react/player';

export function VideoPlayer({ playbackId }: { playbackId: string }) {
  return (
    <Player.Root src={`https://livepeercdn.studio/hls/${playbackId}/index.m3u8`}>
      <Player.Container>
        <Player.Video />
        <Player.Controls>
          <Player.PlayPauseTrigger />
        </Player.Controls>
      </Player.Container>
    </Player.Root>
  );
}
```

<CustomDivider />

<CardGroup cols={3}>
  <Card title="React Player" icon="play" href="/v2/developers/build/applications/frontend-react-player">
    HLS and WebRTC playback with ABR, poster, and metrics.
  </Card>

  <Card title="React Broadcast" icon="video" href="/v2/developers/build/applications/frontend-react-broadcast">
    Browser-based WHIP publishing for live streams.
  </Card>

  <Card title="Core Web (hls.js)" icon="code" href="/v2/developers/build/applications/frontend-core-web">
    Framework-agnostic HLS playback for Vue, Svelte, and vanilla JS.
  </Card>
</CardGroup>
