What is daily-js?
daily-js (@daily-co/daily-js) is Daily’s JavaScript library that lets you embed WebRTC-based video and audio calls into any web application. It handles all the complexity of WebRTC — signaling, media negotiation, network traversal, device handling,and more — so you can focus on building your product.
Key features
Participant management
Track participants, control audio/video, manage permissions, and handle waiting rooms
Device management
Error handling, automatic device switching, and permission management — abstracted across browsers with their differing specs, bugs, and quirks
Recording
Cloud and local recording with custom layout presets and compositing
Live streaming
Stream to any RTMP endpoint with multiple layout options
Transcription
Real-time transcription powered by Deepgram with language and model selection
Media processing
Background blur and virtual backgrounds via Banuba, plus AI noise cancellation via Krisp
Custom tracks
Send custom audio and video tracks alongside camera/mic streams
Network diagnostics
Monitor network quality and run pre-call connectivity tests
Integration modes
daily-js supports two primary ways to integrate video calls into your app:Iframe mode (Prebuilt UI)
Daily manages a full-featured call UI inside an<iframe>. You get a complete video call experience — participant tiles, controls, chat, and more — with minimal code.
Call object mode (Headless)
Daily manages audio/video streams with no UI of its own. You have full control over the participant interface and can build any custom design.How it works
The@daily-co/daily-js npm package is a small orchestration layer — it does not contain the full call machinery. When you call join() (or load() if you pre-load ahead of time), the SDK fetches a call bundle from Daily’s CDN. That bundle contains the WebRTC engine, media pipeline, and everything else needed to run the call.
This keeps your application’s initial bundle size minimal, but it means:
- A network request happens on first join. The
loadingandloadedevents mark the start and end of this fetch. - If the fetch fails,
load-attempt-failedfires and a few retries are attempted before anerrorevent is emitted. - You can call
load()beforejoin()to fetch the bundle early and hide the loading latency from users.
Iframe mode and Prebuilt
In iframe mode, there are actually two daily-js instances in play. The one you import and interact with in your app is the outer orchestration layer. Inside the<iframe>, Daily’s Prebuilt UI runs its own separate daily-js instance — the one that directly manages WebRTC, devices, and media.
Your calls (join(), setLocalVideo(), etc.) are forwarded into the iframe via postMessage. Events from the inner instance are forwarded back out the same way, which is why you can listen for them on the outer call object just like in call object mode.
Because the inner instance is served directly from Daily’s CDN rather than from your npm dependency, the two versions may not be identical — but they are tested for compatibility. This also means that in Prebuilt, you’re always running Daily’s latest Prebuilt release, and frequently ahead of what’s published to npm.
Call lifecycle
Create
Call one of the factory methods to create a
DailyCall instance. No network activity starts yet.Join
Call
call.join({ url }). Daily fetches the call bundle, connects to the room, and meeting state transitions through joining-meeting → joined-meeting.Leave
Call
call.leave() to disconnect. Meeting state becomes left-meeting. The instance is reusable — you can call join() again.Next steps
Quickstart
Get a working video call running in under 5 minutes
Installation
Install daily-js via npm/yarn or a CDN script tag
Call Modes
Choose between iframe-based or headless call object mode
API Reference
Explore the full API surface