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

# Installation

> Install @daily-co/daily-js via a package manager or load it from a CDN.

## Requirements

daily-js runs in any browser that supports WebRTC. See [here](/reference/daily-js/static-methods/supported-browser#supported-browsers) for a full list of supported browsers and versions.

```javascript theme={null}
const { supported, name, version } = Daily.supportedBrowser();

if (!supported) {
  alert(`${name} ${version} does not support WebRTC. Please use a modern browser.`);
}
```

## Package manager

Install the `@daily-co/daily-js` package using your preferred package manager:

<Tip>
  The `@daily-co/daily-js` package is small by design — the call bundle is fetched from Daily's CDN at runtime when you join. See [How it works](/docs/daily-js/introduction#how-it-works) for details.
</Tip>

<CodeGroup>
  ```bash npm theme={null}
  npm install @daily-co/daily-js
  ```

  ```bash yarn theme={null}
  yarn add @daily-co/daily-js
  ```

  ```bash pnpm theme={null}
  pnpm add @daily-co/daily-js
  ```
</CodeGroup>

## Importing the library

<Note>
  The package's default export is declared as `Daily` in the TypeScript types, while, for historical reasons, the underlying class is named `DailyIframe`. In our documentation and examples, we refer to the default export as `Daily` for clarity, but you may see `DailyIframe` in some contexts, especially in older code snippets. Both refer to the same default export.
</Note>

<Tabs>
  <Tab title="ESM">
    Use a default import. The exported default is the `Daily` class, which acts as both a factory and a namespace for static utilities.

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

    const call = Daily.createCallObject();
    ```

    You can also import named exports for constants and types:

    ```javascript theme={null}
    Daily, {
      DAILY_STATE_JOINED,
      DAILY_STATE_LEFT,
      DAILY_TRACK_STATE_PLAYABLE,
    } from '@daily-co/daily-js';
    ```
  </Tab>

  <Tab title="CommonJS">
    Require the package as you would any CommonJS module. The default export is available on the `.default` property:

    ```javascript theme={null}
    const Daily = require('@daily-co/daily-js').default;
    // or, if your bundler resolves the `main` field directly:
    // const Daily = require('@daily-co/daily-js');

    const call = Daily.createCallObject();
    ```
  </Tab>

  <Tab title="CDN (script tag)">
    Load daily-js directly from [unpkg](https://unpkg.com) without a build step. After the script loads, `DailyIframe` is available as a global on `window`.

    ```html theme={null}
    <script src="https://unpkg.com/@daily-co/daily-js"></script>
    <script>
      const call = Daily.createCallObject();
    </script>
    ```

    To pin a specific version, append it to the URL:

    ```html theme={null}
    <script src="https://unpkg.com/@daily-co/daily-js@0.89.1/dist/daily.js"></script>
    ```

    <Tip>
      Pinning a version in production prevents your app from being affected by future breaking changes.
    </Tip>
  </Tab>
</Tabs>

## TypeScript

`@daily-co/daily-js` ships with TypeScript definitions in `index.d.ts`. No additional `@types` package is needed.

```typescript theme={null}
Daily, {
  DailyCall,
  DailyParticipant,
  DailyEventObjectParticipants,
  DailyBrowserInfo,
} from '@daily-co/daily-js';

// Factory methods return DailyCall
const call: DailyCall = Daily.createCallObject();

// Event callbacks are fully typed
call.on('joined-meeting', (event: DailyEventObjectParticipants) => {
  Object.values(event.participants).forEach((p: DailyParticipant) => {
    console.log(p.user_name, p.session_id);
  });
});

// Browser support check
const info: DailyBrowserInfo = Daily.supportedBrowser();
if (!info.supported) {
  throw new Error('WebRTC not supported in this browser');
}
```

<Note>
  While `Daily` is the default export and namespace, `DailyCall` is the interface describing an active call instance returned by the factory methods (`createFrame`, `createCallObject`, `wrap`).
</Note>

## Named exports

In addition to the default export (the `DailyIframe` class), the package exports a set of named constants you can use for comparisons:

```javascript theme={null}
Daily, {
  // Meeting state constants
  DAILY_STATE_NEW,
  DAILY_STATE_JOINING,
  DAILY_STATE_JOINED,
  DAILY_STATE_LEFT,
  DAILY_STATE_ERROR,

  // Track state constants
  DAILY_TRACK_STATE_BLOCKED,
  DAILY_TRACK_STATE_OFF,
  DAILY_TRACK_STATE_SENDABLE,
  DAILY_TRACK_STATE_LOADING,
  DAILY_TRACK_STATE_INTERRUPTED,
  DAILY_TRACK_STATE_PLAYABLE,

  // Access level constants
  DAILY_ACCESS_UNKNOWN,
  DAILY_ACCESS_LEVEL_FULL,
  DAILY_ACCESS_LEVEL_LOBBY,
  DAILY_ACCESS_LEVEL_NONE,

  // Receive settings special keys
  DAILY_RECEIVE_SETTINGS_BASE_KEY,
  DAILY_RECEIVE_SETTINGS_ALL_PARTICIPANTS_KEY,

  // Fatal error type constants
  DAILY_FATAL_ERROR_EJECTED,
  DAILY_FATAL_ERROR_NBF_ROOM,
  DAILY_FATAL_ERROR_NBF_TOKEN,
  DAILY_FATAL_ERROR_EXP_ROOM,
  DAILY_FATAL_ERROR_EXP_TOKEN,
  DAILY_FATAL_ERROR_NO_ROOM,
  DAILY_FATAL_ERROR_MEETING_FULL,
  DAILY_FATAL_ERROR_NOT_ALLOWED,
  DAILY_FATAL_ERROR_CONNECTION,
  DAILY_FATAL_ERROR_EOL,

  // Camera error type constants
  DAILY_CAMERA_ERROR_CAM_IN_USE,
  DAILY_CAMERA_ERROR_MIC_IN_USE,
  DAILY_CAMERA_ERROR_CAM_AND_MIC_IN_USE,
  DAILY_CAMERA_ERROR_PERMISSIONS,
  DAILY_CAMERA_ERROR_UNDEF_MEDIADEVICES,
  DAILY_CAMERA_ERROR_NOT_FOUND,
  DAILY_CAMERA_ERROR_CONSTRAINTS,
  DAILY_CAMERA_ERROR_UNKNOWN,
} from '@daily-co/daily-js';
```

These constants match the string literal values used in the `DailyMeetingState`, `DailyFatalErrorType`, and `DailyCameraErrorType` types. Using constants instead of raw strings helps avoid typos:

```javascript theme={null}
call.on('error', ({ error }) => {
  if (error?.type === DAILY_FATAL_ERROR_EJECTED) {
    showMessage('You were removed from the call.');
  }
});

if (call.meetingState() === DAILY_STATE_JOINED) {
  // safe to interact with the call
}
```

## Verifying the installation

After installing, run the following snippet in your browser console or application to confirm that daily-js loaded correctly:

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

console.log('daily-js version:', Daily.version());
// → "0.89.1"

const { supported, name, version } = Daily.supportedBrowser();
console.log(`Browser: ${name} ${version}, supported: ${supported}`);
```
