🔥 From Zero to Serverless: Building a Real-Time Chat App with Deno, WebSockets, and No Backend
Imagine building a real-time chat application where there's no traditional backend—no Express, no database, not even a VM running 24/7. Sounds crazy? Welcome to the world of Deno and serverless WebSockets.
In this article, we’re diving deep into a lesser-known yet powerful use case: spinning up a real-time chat system using Deno Deploy, native WebSockets, and entirely stateless architecture. This is not your normal CRUD + PostgreSQL tutorial—this is an architectural eye-opener for modern developers.
Most chat apps are built on socket.io with Express or Nest.js, tethered to a server and a database with sessions, user tokens, etc. But what if:
You can use Deno Deploy + WebSockets + Edge broadcast channels to build a chat app that’s instantly scalable and runs at the edge. Welcome to the serverless revolution.
A real-time chat app:
chat-app/ ├── main.ts # Deno serverless handler └── static/ └── index.html # UI
// main.ts import { serve } from "https://deno.land/[email protected]/http/server.ts"; // Broadcast channel to relay messages across edge instances const channel = new BroadcastChannel("global-chat"); serve((req) => { const { socket, response } = Deno.upgradeWebSocket(req); socket.onopen = () => { console.log("Client connected"); }; socket.onmessage = (event) => { const msg = event.data; // Broadcast to all edges / users channel.postMessage(msg); }; // Relay messages to connected clients channel.onmessage = (e) => { socket.send(e.data); }; socket.onclose = () => console.log("Client disconnected"); return response; });
You can instantly deploy this with:
deno deploy --project=chat-app main.ts
<!-- static/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Deno Chat</title> <style> body { font-family: sans-serif; margin: 1rem; } #messages { height: 300px; overflow-y: scroll; border: 1px solid #ccc; padding: 1rem; } input { width: 80%; } </style> </head> <body> <h2>💬 Deno Real-Time Chat</h2> <div id="messages"></div> <input id="messageInput" placeholder="Type a message..." /> <button onclick="sendMessage()">Send</button> <script> const ws = new WebSocket("wss://your-deno-project.deno.dev"); const messagesDiv = document.getElementById("messages"); ws.onmessage = (event) => { const el = document.createElement("div"); el.textContent = event.data; messagesDiv.appendChild(el); messagesDiv.scrollTop = messagesDiv.scrollHeight; }; window.sendMessage = () => { const input = document.getElementById("messageInput"); if (input.value) ws.send(input.value); input.value = ""; }; </script> </body> </html>
Deno Deploy has support for BroadcastChannel, which is essentially a real-time communication tunnel across Deno's global edge locations.
This is the key. Since your WebSocket connections might hit different edge servers, a local in-memory relay won’t work. But with BroadcastChannel, messages get broadcast to all connected edge nodes, creating true global state synchronization—without Redis or databases.
This app is great for use cases where message history is ephemeral. Think more WhatsApp group live than Slack workspace. If you need persistence:
But if your messages can vanish after reload, you just built a beautiful stateless chat system, instantly scalable, with no backend code beyond a single file. Pretty cool, huh?
✅ WebSockets are amazing — and native everywhere now
✅ Deno Deploy lets you build at the edge without thinking about servers
✅ Broadcast Channel turns stateless services into networked ones
✅ Simplicity wins — one TypeScript file > 4 services
If you're still binding socket.io to Express in 2024, you're working too hard. Embrace the edge. 🧠
💡 If you need this done – we offer fullstack development services! Check it out here
Information