Requirements
daily-js runs in any browser that supports WebRTC. See here for a full list of supported browsers and versions.
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:
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 for details.
npm install @daily-co/daily-js
Importing the library
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.
ESM
CommonJS
CDN (script tag)
Use a default import. The exported default is the Daily class, which acts as both a factory and a namespace for static utilities.import Daily from '@daily-co/daily-js';
const call = Daily.createCallObject();
You can also import named exports for constants and types:Daily, {
DAILY_STATE_JOINED,
DAILY_STATE_LEFT,
DAILY_TRACK_STATE_PLAYABLE,
} from '@daily-co/daily-js';
Require the package as you would any CommonJS module. The default export is available on the .default property: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();
Load daily-js directly from unpkg without a build step. After the script loads, DailyIframe is available as a global on window.<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:<script src="https://unpkg.com/@daily-co/daily-js@0.89.1/dist/daily.js"></script>
Pinning a version in production prevents your app from being affected by future breaking changes.
TypeScript
@daily-co/daily-js ships with TypeScript definitions in index.d.ts. No additional @types package is needed.
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');
}
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).
Named exports
In addition to the default export (the DailyIframe class), the package exports a set of named constants you can use for comparisons:
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:
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:
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}`);