TrueSpec

Real-Time Updates with SSE

EventSource API, reconnection, broadcasting, and Express/Fastify SSE

What You’ll Build

After following this guide, you will have a working implementation of real-time updates with sse in your project. Server-Sent Events (SSE) is the simplest way to push real-time updates from server to client. Unlike WebSockets, SSE works over plain HTTP, auto-reconnects, and is supported in all browsers. Perfect for live dashboards, notifications, progress updates, and AI streaming responses.

Use Cases & Problems Solved

  • Build reliable server endpoints that clients can consume consistently
  • Handle common backend patterns like routing, middleware, and error handling
  • Provide a clean interface between your frontend and data layer

Prerequisites

  • Node.js 18+
  • Express.js

Step-by-Step Implementation

SSE endpoint on Express

The following snippet shows how to sse endpoint on express. Copy this into your project and adjust the values for your environment.

const clients = new Set();

app.get('/api/events', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
  });

  // Send initial connection event
  res.write('data: {"type":"connected"}\
\
');

  clients.add(res);
  req.on('close', () => clients.delete(res));
});

// Broadcast to all connected clients
function broadcast(eventName, data) {
  const message = \`event: \${eventName}\
data: \${JSON.stringify(data)}\
\
\`;
  for (const client of clients) {
    client.write(message);
  }
}

// Example: call this when a new order is created
app.post('/api/orders', async (req, res) => {
  const order = await createOrder(req.body);
  broadcast('new-order', order);
  res.json(order);
});

Client-side EventSource with auto-reconnect

The following snippet shows how to client-side eventsource with auto-reconnect. Copy this into your project and adjust the values for your environment.

const eventSource = new EventSource('/api/events');

eventSource.addEventListener('new-order', (event) => {
  const order = JSON.parse(event.data);
  console.log('New order:', order);
  // Update UI
});

eventSource.onerror = () => {
  console.log('SSE connection lost, auto-reconnecting...');
  // EventSource automatically reconnects!
};

⚠️ Don’t Do This

❌ Polling the server every second for updates

// Wastes bandwidth and server resources!
setInterval(async () => {
  const data = await fetch('/api/orders/latest').then(r => r.json());
  updateUI(data);
}, 1000); // 86,400 requests per day PER USER

✅ Use SSE — server pushes updates only when they happen

// ONE persistent connection, updates only when data changes
const es = new EventSource('/api/events');
es.addEventListener('new-order', (e) => updateUI(JSON.parse(e.data)));

Testing

Add these tests to verify your API endpoints work correctly:

// __tests__/api.test.ts
import { describe, it, expect } from 'vitest';

describe('Real-Time Updates with SSE', () => {
  it('should return 200 for valid requests', async () => {
    const res = await fetch('/api/endpoint', { method: 'GET' });
    expect(res.status).toBe(200);
    const data = await res.json();
    expect(data).toBeDefined();
  });

  it('should return 400 for invalid input', async () => {
    const res = await fetch('/api/endpoint', {
      method: 'POST',
      body: JSON.stringify({}),
    });
    expect(res.status).toBe(400);
  });

  it('should handle errors gracefully', async () => {
    const res = await fetch('/api/endpoint/nonexistent');
    expect(res.status).toBe(404);
  });
});

Verification

# Open browser to your app with DevTools Network tab
# Filter by EventStream
# Should see persistent connection with events flowing
# Create an order in another tab — event should appear instantly

Related Specs

Intermediate

WebSocket Chat with Socket.io

Rooms, namespaces, auth middleware, reconnection, and scaling

API & Backend
Advanced

Secure Webhook Handler

Signature verification, idempotency, retry handling, and queue processing

API & Backend
Intermediate

Production-Ready REST API (Express)

Error handling, Zod validation, rate limiting, CORS, and structured logging

API & Backend