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

# Call Modes

> Choose between iframe-based and call object modes to match your integration requirements.

Daily supports two fundamental integration modes. The mode you choose determines how much UI Daily renders versus how much you build yourself.

<CardGroup cols={2}>
  <Card title="Iframe Mode" icon="window">
    Daily renders a full call UI inside an `<iframe>`. Best for fast integration with minimal custom UI work.
  </Card>

  <Card title="Call Object Mode" icon="code">
    Headless — Daily manages WebRTC and media, but you build every pixel of UI. Maximum flexibility.
  </Card>
</CardGroup>

## Iframe Mode

In iframe mode, Daily creates an `<iframe>` element and loads its full prebuilt call UI inside it. You interact with the call through the `Daily` JavaScript API, but the camera tiles, controls, and layout all live inside the iframe.

This mode is ideal when:

* You want a working video call in minutes
* Custom branding is handled via [themes](/docs/prebuilt/customizing-daily-prebuilt-calls-with-color-themes) rather than custom components
* You're embedding a call widget into an existing page

### Factory methods

Three factory methods create iframe-backed instances:

<Tabs>
  <Tab title="createFrame">
    [`createFrame()`](/reference/daily-js/factory-methods/create-frame) creates and appends a new `<iframe>` element. Optionally accepts a parent element and/or properties object.

    ```typescript theme={null}
    // Appends iframe to document.body with a default floating style
    const call = Daily.createFrame();

    // Appends iframe to a specific container
    const call = Daily.createFrame(
      document.getElementById('call-container'),
      { showFullscreenButton: false }
    );
    ```

    When `parentEl` is `document.body`, the default `iframeStyle` is a fixed-position widget (375×450 px, bottom-right). When a custom container is provided the iframe stretches to fill it (`width: 100%; height: 100%; border: 0`).
  </Tab>

  <Tab title="wrap">
    [`wrap()`](/reference/daily-js/factory-methods/wrap) wraps an existing `<iframe>` element that you control. Useful for when you need complete control over the iframe's lifecycle and properties.

    ```html theme={null}
    <iframe
      id="my-iframe"
      allow="microphone; camera; autoplay; display-capture"
    ></iframe>
    ```

    ```typescript theme={null}
    const iframe = document.getElementById('my-iframe') as HTMLIFrameElement;

    const call = Daily.wrap(iframe, {
      url: 'https://your-domain.daily.co/hello',
    });
    ```

    The `allow` attribute is required — without `microphone` and `camera` the browser will block device access, and without `display-capture` screen sharing will fail. `createFrame()` and `createTransparentFrame()` set this automatically; with `wrap()` you are responsible for it.

    The iframe must already exist in the DOM before calling `wrap()`.
  </Tab>

  <Tab title="createTransparentFrame">
    [`createTransparentFrame()`](/reference/daily-js/factory-methods/create-transparent-frame) creates a full-viewport, pointer-events-none iframe layered on top of your page. Use this when you need Daily's audio/video without its default UI blocking interaction with your own UI.

    ```typescript theme={null}
    const call = Daily.createTransparentFrame({
      url: 'https://your-domain.daily.co/hello',
    });
    ```

    The iframe is positioned `fixed; top: 0; left: 0; width: 100%; height: 100%` with `pointer-events: none`.
  </Tab>
</Tabs>

### Full iframe example

```typescript theme={null}
import Daily from '@daily-co/daily-js';

const call = Daily.createFrame(
  document.getElementById('call-container'),
  {
    url: 'https://your-domain.daily.co/hello',
    showLeaveButton: true,
    iframeStyle: {
      width: '100%',
      height: '100%',
      border: '0',
    },
  }
);

call.on('joined-meeting', (event) => {
  console.log('Joined!', event.participants);
});

await call.join();
```

## Call Object Mode

Call object mode is headless. Daily loads its media engine but renders no UI. Your application receives participant state and media tracks, and you render everything yourself.

This mode is created with [`createCallObject()`](/reference/daily-js/factory-methods/create-call-object):

```typescript theme={null}
static createCallObject(properties?: DailyFactoryOptions): DailyCall
```

### Call object example

```typescript theme={null}
import Daily from '@daily-co/daily-js';

const call = Daily.createCallObject({
  url: 'https://your-domain.daily.co/hello',
  subscribeToTracksAutomatically: true,
});

// You handle all rendering
call.on('track-started', ({ participant, track, type }) => {
  if (type === 'video' && !participant?.local) {
    const videoEl = document.createElement('video');
    videoEl.autoplay = true;
    videoEl.srcObject = new MediaStream([track]);
    document.getElementById('video-grid')?.appendChild(videoEl);
  }
});

call.on('track-stopped', ({ track }) => {
  // remove video element whose srcObject contains this track
});

await call.join();
```

<Note>
  Several properties are iframe-only and log a console error in call object mode: `showLocalVideo`, `showParticipantsBar`, `activeSpeakerMode`, `customTrayButtons`, `customIntegrations`.

  Conversely, `receiveSettings` is only available in call object mode.
</Note>

## Choosing a Mode

| Criterion                            | Iframe Mode            | Call Object Mode                       |
| ------------------------------------ | ---------------------- | -------------------------------------- |
| Time to first call                   | Minutes                | Hours–days                             |
| Custom UI                            | Limited (CSS + themes) | Full control                           |
| Track access                         | Via events             | Via events + direct `MediaStreamTrack` |
| React / custom framework integration | Moderate               | Native                                 |

## Next steps

<CardGroup cols={2}>
  <Card title="Prebuilt UI" icon="window" href="/docs/prebuilt/index">
    Learn what Daily Prebuilt offers out of the box — themes, custom buttons, language settings, and more
  </Card>

  <Card title="API Reference" icon="code" href="/reference/daily-js/factory-methods/create-call-object">
    Explore the full factory method and instance method reference for `DailyCall`
  </Card>
</CardGroup>
