Hi there! I'm Maneshwar. Right now, I’m building LiveAPI, a first-of-its-kind tool for helping you automatically index API endpoints across all your repositories. LiveAPI helps you discover, understand, and use APIs in large tech infrastructures with ease.
If you've ever built something like a live score ticker, stock updates, or notification feed, chances are you've needed real-time updates from your server.
While WebSockets often steal the spotlight, there's a quieter but super-effective player on the field: Server-Sent Events (SSE).
Let's break it down and show you how to implement it from scratch using just HTML + JavaScript + a simple backend.
What Are Server-Sent Events?
Server-Sent Events (SSE) enable one-way, real-time communication from the server to the browser, using a single long-lived HTTP connection.
Key Features:
- Unidirectional (server ➡️ client)
- Reconnects automatically
- Lightweight compared to WebSockets
- Text-based event format
- Native browser support via the
EventSource
API
When Should You Use SSE?
Great for:
- Live dashboards
- Notifications
- News or social feeds
- Streaming logs or metrics
Not ideal for:
- Chat apps (need bidirectional)
- Multiplayer games
- Anything requiring client-to-server messages
How It Works: The Basics
- Client opens a connection using
EventSource
. - Server keeps the connection open and streams updates in
text/event-stream
format. - Client listens for messages using
.onmessage
oraddEventListener
.
Let's Build It
Backend (Node.js Example)
// sse-server.js
const http = require('http');
http.createServer((req, res) => {
if (req.url === '/events') {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
const interval = setInterval(() => {
const now = new Date().toLocaleTimeString();
res.write(`data: Server time is ${now}\n\n`);
}, 2000);
req.on('close', () => {
clearInterval(interval);
res.end();
});
} else {
res.writeHead(404);
res.end();
}
}).listen(3000, () => {
console.log('SSE server running on http://localhost:3000');
});
Frontend (HTML + JS)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSE Example</title>
</head>
<body>
<h1>🛰️ Real-Time Server Time</h1>
<div id="output">Waiting for updates...</div>
<script>
const output = document.getElementById('output');
const evtSource = new EventSource("http://localhost:3000/events");
evtSource.onopen = () => {
console.log("Connection opened");
};
evtSource.onmessage = (event) => {
output.innerText = event.data;
};
evtSource.onerror = (err) => {
console.error("EventSource failed:", err);
};
</script>
</body>
</html>
Server-Sent Format
Every SSE message looks like this:
data: Hello World
data: Another message
Optional fields:
// Named event
event: custom
data: Custom message
// Retry interval in milliseconds
retry: 5000
Note: A blank line means “end of message.”
EventSource API Breakdown
Property / Method | Description |
---|---|
EventSource(url) |
Opens the connection |
onmessage |
Default handler for incoming data |
addEventListener("foo") |
Listen for custom event types |
close() |
Manually close the connection |
readyState |
0 = connecting, 1 = open, 2 = closed |
withCredentials |
Handles CORS cookies |
Gotchas & Tips
- Max connections: Browsers often limit 6 connections per domain (per tab), unless you’re using HTTP/2.
- CORS: If your frontend is on a different domain, the server must send:
Access-Control-Allow-Origin: http://your-frontend.com
-
Auto-reconnect: Happens automatically unless you call
.close()
. - No binary support: SSE only supports UTF-8 text.
SSE vs WebSockets
Feature | SSE | WebSocket |
---|---|---|
Direction | One-way | Bi-directional |
Protocol | HTTP | WS/TCP |
Built-in reconnect | Yes | No |
Text only | Yes | Text + Binary |
CORS support | Easy | Requires config |
Complexity | Low | Medium-High |
Conclusion
SSE is the perfect lightweight tool when your use case is read-only from server to client, like dashboards, feeds, or real-time monitoring.
No need for a full WebSocket setup or third-party libraries—just native browser support, some headers, and a res.write()
.
Bonus: Named Events
// Server
res.write('event: alert\n');
res.write('data: You got a new message!\n\n');
// Client
evtSource.addEventListener("alert", (e) => {
alert(e.data);
});
Simple and sweet.
Let SSE handle the push, and you just sip that data like a chilled stream. ☕
LiveAPI helps you get all your backend APIs documented in a few minutes
With LiveAPI, you can quickly generate interactive API documentation that allows users to search and execute APIs directly from the browser.
If you’re tired of manually creating docs for your APIs, this tool might just make your life easier.
Top comments (1)
Very nice. Good Luck with LiveAPI !!
How do you generate the docs pages?
Btw, WebSockets are very complex, and that's why in Kiponos were providing an SDK that simplify and hides all the WebSockets complexity so you can benefit of bi-directional, permanent connection with reconnect strategies all in a simple SDK.
If you have a Java server like Spring Boot, check us out: Kiponos.io.
Kiponos is a true real-time configuration hub. Whatever you modify online, is instantly affecting your app.