> ## 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.

# Custom layouts with VCS

> Use Daily's Video Component System to build custom live streaming and cloud recording layouts with text overlays, image overlays, and more.

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

Daily's Video Component System (VCS) lets you build custom layouts for live streaming and cloud recording. VCS goes beyond the built-in presets (`default`, `single-participant`, `active-participant`, `portrait`) to give you full control over composition, overlays, and presentation.

<Warning>
  VCS is only available for `cloud` recordings and live streaming. It is not available for `local` or `raw-tracks` recording.
</Warning>

<img src="https://mintcdn.com/daily-co/UZ5SeZfPxiPGRDvT/assets/guides-vcs-hero.png?fit=max&auto=format&n=UZ5SeZfPxiPGRDvT&q=85&s=a3a6c671d6be417c507f85aa44561f9d" alt="Live streaming UI" width="1200" height="674" data-path="assets/guides-vcs-hero.png" />

## What VCS can do

VCS is a video-oriented layout engine based on JavaScript functions. It generates layouts called **compositions**, which let you turn Daily calls into engaging streamed and recorded content.

Using VCS's baseline composition, you can:

* Apply custom video grid layouts and dominant-speaker views
* Add animated overlay graphics
* Display text overlays (titles, lower-thirds)
* Show image overlays (logos, watermarks)
* Embed live web content with the WebFrame component
* Customize layout based on participant count or call state

Some ways developers use VCS:

1. Building a live streaming "studio" for streamers and creators
2. Hosting interactive multiparty virtual events broadcast live to a wider audience via YouTube or Facebook Live
3. Creating high-quality recorded content from live events (e.g. an online fitness studio archiving recorded classes)

## The baseline composition

Daily provides a "baseline" composition as part of [`daily-js`](/reference/daily-js/types/daily-streaming-layout-config#vcs-baseline-composition) and [`react-native-daily-js`](/reference/react-native/types/daily-streaming-layout-config#vcs-baseline-composition). It's available to any Daily call using the live streaming or recording APIs.

Most developers will find the baseline composition flexible enough to meet their needs — it supports a variety of grid formats, layout parameters, overlay text, overlay graphics, and more. The `composition_id` for the baseline is `'daily:baseline'`, which is also the default if you omit it.

If you need customization beyond what the baseline offers, the [VCS SDK](/docs/vcs) is open source and lets you build fully custom compositions from scratch.

## Using the `custom` preset

To use VCS, set `layout.preset` to `'custom'` in your [`startLiveStreaming()`](/reference/daily-js/instance-methods/start-live-streaming) or [`startRecording()`](/reference/daily-js/instance-methods/start-recording) call:

```javascript theme={null}
await call.startLiveStreaming({
  layout: {
    preset: 'custom',
    composition_id: 'daily:baseline', // optional, this is the default
    composition_params: {
      // VCS parameters — see below
    },
    // session_assets must be declared at start if used in any update
    session_assets: {
      'images/logo': 'https://example.com/logo.png',
    },
  },
});
```

**Key options:**

* `composition_id` — the composition to use. `'daily:baseline'` is the default and currently the only option.
* `composition_params` — parameters that configure how the composition behaves. Pass them in `startLiveStreaming()` or `startRecording()` to set the initial layout, and in `updateLiveStreaming()` or `updateRecording()` to change the layout mid-stream.
* `session_assets` — a map of string keys to public asset URLs (e.g. `'images/logo': 'https://...'`). Think of this as a directory of files loaded from those URLs and named by their keys. Image asset keys must start with `"images/"`.

<Warning>
  `session_assets` must be passed in the `startLiveStreaming()` or `startRecording()` call, even if they won't be used until a later `updateLiveStreaming()` or `updateRecording()` call.
</Warning>

You can update the layout at any time using `updateLiveStreaming()` or `updateRecording()`:

```javascript theme={null}
await call.updateLiveStreaming({
  layout: {
    preset: 'custom', // required even in updates
    composition_params: {
      showTextOverlay: true,
      'text.content': 'Live now',
    },
  },
});
```

## VCS Simulator

The best way to explore VCS is with the **[VCS Simulator](https://daily.co/tools/vcs-simulator)** — an interactive tool that lets you configure baseline composition parameters and see results in real time, without writing code.

<img src="https://mintcdn.com/daily-co/UZ5SeZfPxiPGRDvT/assets/vcs_simulator.png?fit=max&auto=format&n=UZ5SeZfPxiPGRDvT&q=85&s=9fa5178f88ecb11ee08c5d9f2ca568e2" alt="VCS Simulator example" width="1759" height="866" data-path="assets/vcs_simulator.png" />

Things to try:

* Set `mode` to `'grid'` and click the numbered video input buttons to preview grid layout changes.
* Set `mode` to `'dominant'` and click "Make dominant" to see the active speaker layout.
* Enable `showTextOverlay` and update the text content, alignment, and positioning.
* Drag a PNG into the asset images box and enable `showImageOverlay`.

### API Call Builder

The **API Call Builder** tab in the Simulator generates ready-to-use `composition_params` based on your interactions:

* **Record / Stop** — capture parameter changes as you interact with the Simulator.
* **Capture all** — output all current parameter values, including defaults.
* **Screenshot** — get a preview image of your current composition.
* **Clear** — reset your recorded options.

<img src="https://mintcdn.com/daily-co/k5NXwOZS3v6Jul7S/assets/api_call_builder.png?fit=max&auto=format&n=k5NXwOZS3v6Jul7S&q=85&s=093d52dddaff491bac34867e8003cd8b" alt="API call builder tab in the VCS simulator" width="1036" height="800" data-path="assets/api_call_builder.png" />

The generated parameters work in `startLiveStreaming()`, `updateLiveStreaming()`, `startRecording()`, and `updateRecording()`.

## Example configurations

### Text overlay

```javascript theme={null}
await call.updateLiveStreaming({
  layout: {
    preset: 'custom',
    composition_params: {
      showTextOverlay: true,
      'text.content': 'Hello streaming',
      'text.align_vertical': 'bottom',
      'text.align_horizontal': 'center',
      'text.offset_y': 20,
      'text.color': 'white',
      'text.strokeColor': 'rgba(0, 0, 0, 0.8)',
    },
  },
});
```

Assuming you are using the default values for other parameters, this will look like:

<img src="https://mintcdn.com/daily-co/k5NXwOZS3v6Jul7S/assets/guides-livestreaming-text-overlay.png?fit=max&auto=format&n=k5NXwOZS3v6Jul7S&q=85&s=65a72bd34bf0f13fcb4631d810d2d62c" alt="Live streaming with AWS IVS and a text overlay" width="982" height="758" data-path="assets/guides-livestreaming-text-overlay.png" />

### Dominant speaker layout

```javascript theme={null}
await call.updateLiveStreaming({
  layout: {
    preset: 'custom',
    composition_params: {
      mode: 'dominant',
      'videoSettings.dominant.position': 'left',
    },
  },
});
```

Assuming you are using the default values for other parameters, this will look like:

<img src="https://mintcdn.com/daily-co/k5NXwOZS3v6Jul7S/assets/guides-livestreaming-dominant.png?fit=max&auto=format&n=k5NXwOZS3v6Jul7S&q=85&s=0dc78a04a51168034278191bbf83d796" alt="Live streaming with AWS IVS and a text overlay with a larger video displayed on the left side" width="964" height="764" data-path="assets/guides-livestreaming-dominant.png" />

In dominant mode, the active speaker's video renders large on the specified side, with other participants in smaller tiles on the other side. This layout can be further customized with additional `videoSettings.dominant.*` parameters.

<Note>
  The "dominant" video corresponds to the current [active speaker](/reference/daily-js/events/participant-events#participant-counts-updated).
</Note>

## Testing with the Daily Prebuilt demo app

The [`vcs-live-streaming` branch of the Daily Prebuilt demo app](https://github.com/daily-demos/prebuilt-ui/tree/vcs-live-streaming) includes UI for starting a live stream, applying VCS properties via `updateLiveStreaming()`, and stopping the stream. You can use any transcoder — YouTube Live, Mux, or AWS IVS all work.

<img src="https://mintcdn.com/daily-co/UZ5SeZfPxiPGRDvT/assets/vcs_example.png?fit=max&auto=format&n=UZ5SeZfPxiPGRDvT&q=85&s=372f3543a031653ce17684dc7f1c8203" alt="Comparison of Daily Prebuilt UI with the VCS custom properties applied" width="1892" height="792" data-path="assets/vcs_example.png" />

## VCS SDK

The baseline composition is open source. If you need customization beyond what `composition_params` provides, the [VCS SDK](/docs/vcs) lets you build fully custom compositions from scratch.
