Back to Blog
★ Backend ★
Real-time Updates with Server-Sent Events
May 24, 2025 7 min read By Ahmad Zaini Nijar
Use SvelteKit server routes to stream real-time data to your frontend without WebSockets.
What Are Server-Sent Events?
Server-Sent Events (SSE) allow the server to push data to the browser over a single HTTP connection. Unlike WebSockets, SSE is:
- Unidirectional — server to client only
- Simple — built on standard HTTP
- Auto-reconnecting — the browser handles reconnection
- Text-based — streams plain text (usually JSON)
Creating an SSE Endpoint
// src/routes/api/stream/+server.ts
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async () => {
const stream = new ReadableStream({
start(controller) {
const send = (data: unknown) => {
controller.enqueue(`data: ${JSON.stringify(data)}\n\n`);
};
// Send an event every second
const interval = setInterval(() => {
send({ time: new Date().toISOString(), value: Math.random() });
}, 1000);
// Clean up when client disconnects
setTimeout(() => {
clearInterval(interval);
controller.close();
}, 30_000);
}
});
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
}
});
};
Consuming SSE in Svelte
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
let messages = $state<string[]>([]);
let eventSource: EventSource;
onMount(() => {
eventSource = new EventSource('/api/stream');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
messages = [...messages, data.time];
};
});
onDestroy(() => {
eventSource?.close();
});
</script>
{#each messages as msg}
<p>{msg}</p>
{/each}
Conclusion
Server-Sent Events are a perfect fit for real-time dashboards, live feeds, and progress tracking. They're simpler than WebSockets for one-way data flow, and SvelteKit makes them easy to implement on both server and client.