A production-ready example demonstrating how to build a real-time video chat application with a SvelteKit frontend and a Cloudflare Durable Object backend for signaling.
This project showcases how to build a real-time video chat application using SvelteKit and Cloudflare Durable Objects. The Durable Object acts as a signaling server to facilitate peer-to-peer WebRTC connections between clients.
Durable Objects are Cloudflare's solution for building stateful applications. In this project, they are used to manage the state of a chat room, including the participants and the signaling messages required to establish WebRTC connections.
This monorepo consists of two main applications:
chat-workerA Cloudflare Worker that defines and exposes a Durable Object instance. This service:
sveltekit-video-chat-appA modern SvelteKit application serving as the user interface:
Install dependencies across the monorepo:
pnpm install
Start the development environment:
pnpm start
This single command:
Once running, open your browser and navigate to:
http://localhost:5173/
You can then create a room and share the link with another user to start a video chat session.
The application uses WebRTC for peer-to-peer video and audio communication. The Cloudflare Durable Object is used as a signaling server to exchange metadata between the clients to establish the connection.
This application uses WebRTC to establish peer-to-peer video connections. TURN and STUN servers are critical infrastructure components for NAT traversal.
STUN (Session Traversal Utilities for NAT): Helps clients discover their public IP address and determine the best path for direct peer-to-peer communication. Most connections use STUN when both peers are on standard NAT.
TURN (Traversal Using Relays around NAT): A relay server that forwards media traffic between peers when a direct connection is not possible (e.g., behind symmetric NAT or restrictive firewalls). TURN requires more bandwidth but ensures connectivity in challenging network conditions.
The application is configured to use different servers based on the environment:
{
iceServers: [
{ urls: 'stun:stun.cloudflare.com:3478' }
]
}
{
iceServers: [
{
urls: 'turn:turn.cloudflare.com:3478?transport=udp',
username: 'your_username',
credential: 'your_credential'
},
{
urls: 'turn:turn.cloudflare.com:3478?transport=tcp',
username: 'your_username',
credential: 'your_credential'
},
{
urls: 'turns:turn.cloudflare.com:5349?transport=tcp',
username: 'your_username',
credential: 'your_credential'
}
]
}
To use your own TURN/STUN servers, modify the ICE server configuration in src/routes/call/+page.svelte:
env.servers = {
iceServers: [
{ urls: 'stun:your-stun-server.com:3478' },
{
urls: 'turn:your-turn-server.com:3478?transport=udp',
username: 'your_username',
credential: 'your_credential'
}
]
};
Ready to go live? Follow these steps:
Deploy the backend worker first:
cd chat-worker
pnpm run deploy
Then deploy the SvelteKit application:
cd ../sveltekit-video-chat-app
pnpm run deploy
ā
Real-time Video and Audio Chat
ā
Peer-to-Peer Communication with WebRTC
ā
Signaling with Cloudflare Durable Objects
ā
Unified Local Development - Frontend and backend run together locally
ā
Production Ready - Same setup works during development and after deployment
ā
Type Safe - Full TypeScript support in both frontend and backend
Feel free to fork this repository and use it as a starting point for your own Cloudflare + SvelteKit projects!
This project is based on and inspired by dario-piotrowicz/sveltekit-durable-object-local-usage-example. Special thanks to Dario Piotrowicz for creating an excellent foundation for SvelteKit + Durable Object integration.
This project is open source and available under the MIT License.