Express Server-Sent Events Middleware
raw JSON →express-sse-middleware is an npm package providing a robust Express.js middleware for implementing Server-Sent Events (SSE) in Node.js applications. It simplifies the process of pushing real-time updates from a server to clients over a single HTTP connection, making it suitable for dashboards, chat applications, and live data feeds. The current stable version is 3.0.3, released after a significant v3.0.0 update which transitioned the package to an ES Module (ESM) first architecture. While a strict release cadence isn't explicitly defined, the package appears actively maintained given recent major version bumps and ongoing development. Its primary differentiator is its straightforward integration into existing Express applications by extending the `Response` object with a dedicated `sse()` method, allowing developers to easily send data, custom events, and IDs to connected clients. It also offers an `EventBuilder` for more structured event creation, though direct string sending is fully supported and often sufficient for simple use cases.
Common errors
error TypeError: res.sse is not a function ↓
app.use(sseMiddleware); is called at an appropriate point in your Express application setup, typically before any routes that utilize SSE features. error ReferenceError: require is not defined in ES module scope ↓
import { sseMiddleware } from 'express-sse-middleware';) and ensure your package.json specifies "type": "module". error Failed to load resource: net::ERR_NAME_NOT_RESOLVED (or similar CORS error in browser console) ↓
cors middleware in your Express application: npm install cors then import cors from 'cors'; app.use(cors({ origin: 'http://your-client-app-domain.com' }));. Warnings
breaking Version 3.0.0 of `express-sse-middleware` transitioned the package to be ES Module (ESM) first. Projects using CommonJS (`require()`) must either migrate to ESM or use an older 2.x version of the middleware. ↓
gotcha SSE connections are persistent and remain open until explicitly closed by the server or client. Failing to clean up resources (e.g., `setInterval`, database listeners) upon client disconnection can lead to memory leaks and performance degradation. ↓
gotcha Server-Sent Events do not automatically handle cross-origin requests. If your client-side application is hosted on a different domain, port, or protocol than your SSE server, the browser will block the connection due to CORS policies. ↓
gotcha While SSE has built-in reconnection logic in browsers, the server-side needs to be prepared to handle new connections from clients that might be retrying after a network interruption or server restart. ↓
Install
npm install express-sse-middleware yarn add express-sse-middleware pnpm add express-sse-middleware Imports
- sseMiddleware wrong
const sseMiddleware = require('express-sse-middleware').sseMiddleware;correctimport { sseMiddleware } from 'express-sse-middleware'; - EventBuilder wrong
const { EventBuilder } = require('express-sse-middleware');correctimport { EventBuilder } from 'express-sse-middleware'; - express wrong
const express = require('express');correctimport express from 'express';
Quickstart
import express from 'express';
import { sseMiddleware } from 'express-sse-middleware';
const app = express();
const PORT = 3000;
app.use(sseMiddleware);
app.get('/events', (req, res) => {
// Set appropriate headers for SSE. This is handled by sseMiddleware but good to know.
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
const sse = res.sse(); // Adds the sse() function to the Response object
let count = 0;
const intervalId = setInterval(() => {
sse.send(String(count++), 'message', 'update-id-' + (count - 1)); // data, eventName, id
}, 1000);
// Essential cleanup: Remove resources when client disconnects to prevent memory leaks
req.on('close', () => {
console.log('Client disconnected. Cleaning up interval.');
clearInterval(intervalId);
// You might also want to end the response if it hasn't been already, though SSE implies an open connection.
// res.end();
});
console.log('New client connected for SSE updates.');
});
app.listen(PORT, () => {
console.log(`SSE server listening on http://localhost:${PORT}/events`);
console.log('To test: Open a browser and navigate to http://localhost:3000/events or use a client-side EventSource API.');
});