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

# Live streaming

> Start, stop, and observe RTMP live streams in React with the useLiveStreaming hook.

<Badge color="blue">Paid plans only</Badge>

Live streaming broadcasts a call to an RTMP endpoint such as YouTube Live, Twitch, or a custom server. [`useLiveStreaming`](/reference/daily-react/use-live-streaming) mirrors [`useRecording`](/docs/daily-react/docs/recording): reactive state plus start, stop, and update helpers.

## Start and stop a stream

`startLiveStreaming` takes RTMP endpoint options and an optional layout; `stopLiveStreaming` ends it. `isLiveStreaming` reflects whether any stream is active:

```jsx theme={null}
import { useLiveStreaming } from '@daily-co/daily-react';

function StreamButton({ rtmpUrl }) {
  const { isLiveStreaming, startLiveStreaming, stopLiveStreaming } = useLiveStreaming();

  const start = () =>
    startLiveStreaming({
      rtmpUrl,
      layout: { preset: 'default' },
    });

  return (
    <button onClick={() => (isLiveStreaming ? stopLiveStreaming() : start())}>
      {isLiveStreaming ? 'Stop stream' : 'Go live'}
    </button>
  );
}
```

The options match the daily-js [`startLiveStreaming()`](/reference/daily-js/instance-methods/start-live-streaming) method. To change the layout or endpoints while live, call `updateLiveStreaming`.

## Gate on permission

Like recording, starting and stopping streams requires owner status or `canAdmin: 'streaming'`. Gate the controls with [`usePermissions`](/reference/daily-react/use-permissions):

```jsx theme={null}
import { usePermissions, useLiveStreaming } from '@daily-co/daily-react';

function StreamControls({ rtmpUrl }) {
  const { canAdminStreaming } = usePermissions();
  const { isLiveStreaming, startLiveStreaming, stopLiveStreaming } = useLiveStreaming();
  if (!canAdminStreaming) return null;
  return (
    <button
      onClick={() =>
        isLiveStreaming ? stopLiveStreaming() : startLiveStreaming({ rtmpUrl })
      }
    >
      {isLiveStreaming ? 'Stop' : 'Go live'}
    </button>
  );
}
```

## React to stream events and errors

Live streaming has more failure modes than recording (the remote RTMP endpoint can reject or drop the connection), so handle the error and warning callbacks:

```jsx theme={null}
import { useCallback, useState } from 'react';
import { useLiveStreaming } from '@daily-co/daily-react';

function StreamStatus() {
  const [error, setError] = useState(null);

  const { isLiveStreaming } = useLiveStreaming({
    onLiveStreamingStarted: useCallback(() => setError(null), []),
    onLiveStreamingError: useCallback((event) => setError(event.errorMsg), []),
    onLiveStreamingWarning: useCallback((event) => console.warn(event), []),
  });

  if (error) return <p role="alert">Live streaming error: {error}</p>;
  return <p>{isLiveStreaming ? '🔴 Live' : 'Offline'}</p>;
}
```

## Multiple concurrent streams

To run several streams at once (for example, different layouts for mobile and desktop), pass an `instanceId` (a valid UUID) to scope the hook. Without it, the hook returns aggregate state across all instances:

```jsx theme={null}
const { isLiveStreaming } = useLiveStreaming();                  // any active?
const mobile = useLiveStreaming({ instanceId: MOBILE_UUID });    // one instance
```

[`useLiveStreamingInstances`](/reference/daily-react/use-live-streaming-instances) lists every active stream. See the [multi-instance guide](/docs/guides/features/live-streaming/multi-instance) for details.

## Next steps

<CardGroup cols={2}>
  <Card title="Recording" icon="circle-dot" href="/docs/daily-react/docs/recording">
    The same pattern, for recordings.
  </Card>

  <Card title="Live streaming guide" icon="book-open" href="/docs/guides/features/live-streaming">
    Layouts and RTMP configuration in depth.
  </Card>
</CardGroup>
