{"id":17643,"library":"express-sse","title":"Express Server-Sent Events Middleware","description":"express-sse (from `dpskvn/express-sse`) is a lightweight Express.js middleware designed for easily implementing Server-Sent Events (SSE) in Node.js applications. It provides a straightforward API to send real-time, unidirectional updates from the server to connected clients over a standard HTTP connection, making it suitable for dashboards, live feeds, and notification systems. The current stable version is `1.0.0`, released on April 17, 2025, indicating active development and maintenance. Its primary differentiator is its simplicity and focus on one-way communication, which often makes it a more suitable and simpler alternative to WebSockets for server-to-client data streaming scenarios. It handles the necessary HTTP headers and connection management for SSE, allowing developers to focus on sending data without extensive boilerplate.","status":"active","version":"1.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/dpskvn/express-sse","tags":["javascript","express","sse","server-sent","events","eventsource","middleware","stream","typescript"],"install":[{"cmd":"npm install express-sse","lang":"bash","label":"npm"},{"cmd":"yarn add express-sse","lang":"bash","label":"yarn"},{"cmd":"pnpm add express-sse","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This package is an Express middleware and requires Express.js to function.","package":"express","optional":false}],"imports":[{"note":"The primary class `SSE` is exported as the default export for CommonJS and likely as a default export for ESM. Named import `{ SSE }` might also work if dual-packaged, but `import SSE from 'express-sse'` is the idiomatic way for the default export.","wrong":"const SSE = require('express-sse').SSE;","symbol":"SSE","correct":"import SSE from 'express-sse';"},{"note":"For CommonJS environments (Node.js versions that don't use 'type: module'), `require('express-sse')` directly provides the `SSE` constructor.","wrong":"import SSE from 'express-sse';","symbol":"SSE (CJS)","correct":"const SSE = require('express-sse');"},{"note":"The `init` method of the `SSE` instance should be used as the Express route handler, not the `SSE` instance itself, to correctly set up the SSE connection.","wrong":"app.use('/stream', sse);","symbol":"App Middleware","correct":"app.get('/stream', sse.init);"}],"quickstart":{"code":"import express from 'express';\nimport SSE from 'express-sse';\n\nconst app = express();\nconst port = 3000;\n\n// Initialize SSE with optional initial data and options\nconst sse = new SSE([\"Initial message 1\", \"Initial message 2\"], {\n  isSerialized: true, // Send initial data as separate events\n  initialEvent: 'initial-data' // Optional event name for initial data\n});\n\n// Set up the SSE endpoint\napp.get('/stream', sse.init);\n\n// Send events periodically\nlet counter = 0;\nsetInterval(() => {\n  const message = `Server time: ${new Date().toLocaleTimeString()} - Count: ${counter++}`;\n  sse.send(message, 'time-update', Date.now()); // content, eventName, customID\n  \n  // Example of sending an error event\n  if (counter % 5 === 0) {\n    sse.send({ error: 'Heartbeat error detected' }, 'error', `error-${Date.now()}`);\n  }\n\n}, 2000);\n\n// Update initial data dynamically\napp.post('/update-init', (req, res) => {\n  const newInitialData = req.body?.data || [\"Updated initial content\"];\n  sse.updateInit(newInitialData);\n  res.status(200).send('Initial data updated');\n});\n\napp.listen(port, () => {\n  console.log(`Express SSE server listening at http://localhost:${port}`);\n  console.log(`Connect to SSE stream at http://localhost:${port}/stream`);\n});\n\n/*\n// Client-side JavaScript (e.g., in an HTML file):\n// Ensure to include express and body-parser for the server, and a client-side HTML file to test.\n// Example client.html:\n// <script>\n//   const eventSource = new EventSource('/stream');\n//\n//   eventSource.onopen = () => console.log('SSE connection opened.');\n//   eventSource.onerror = (error) => {\n//     console.error('SSE Error:', error);\n//     eventSource.close();\n//   };\n//   eventSource.onmessage = (event) => {\n//     console.log('Received generic message:', event.data);\n//   };\n//   eventSource.addEventListener('time-update', (event) => {\n//     console.log('Received time-update:', event.data, 'ID:', event.lastEventId);\n//   });\n//   eventSource.addEventListener('initial-data', (event) => {\n//     console.log('Received initial-data:', event.data);\n//   });\n//   eventSource.addEventListener('error', (event) => {\n//     console.error('Received error event:', event.data);\n//   });\n// </script>\n*/","lang":"typescript","description":"This example demonstrates how to set up an Express.js server using `express-sse` to stream real-time updates. It initializes SSE with some optional initial data, then sends periodic 'time-update' events. It also shows how to send custom-named events (like 'error') and includes client-side JavaScript for consuming the stream using the browser's `EventSource` API."},"warnings":[{"fix":"Configure your reverse proxy/load balancer with 'no-buffering' settings for SSE endpoints. For Nginx, add `proxy_buffering off; proxy_cache off; proxy_http_version 1.1; proxy_set_header Connection '';` to your location block.","message":"When deploying `express-sse` (or any SSE solution) behind reverse proxies (like Nginx, Apache) or load balancers, ensure that the proxy is configured to not buffer responses. Proxies often buffer entire responses before sending them to the client, which can prevent SSE streams from delivering real-time updates. Look for settings like `proxy_buffering off` in Nginx.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Exclude SSE routes from compression middleware. For example, if using `compression`, apply it conditionally: `app.use(compression({ filter: shouldCompress }))` and define `shouldCompress` to return `false` for your SSE paths.","message":"Using compression middleware (e.g., `compression` package) with SSE routes can break the event stream, as the middleware will try to compress the response, effectively buffering it until completion. This defeats the purpose of real-time streaming.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Be mindful of client-side connection limits. Consider consolidating data streams where possible, using a single SSE connection for multiple types of events, or leveraging HTTP/2 which allows multiplexing over a single TCP connection. For applications requiring many simultaneous connections, WebSockets might be a better fit.","message":"Browsers enforce a limit on the number of concurrent HTTP connections to a single domain (typically 6 per browser, not per tab). If multiple SSE tabs are open or other long-polling requests are made, new SSE connections might be blocked.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"When sending multi-line content or data that might contain newlines (e.g., JSON strings, markdown), ensure that each line in your data is prefixed with `data:` and ends with `\\n`, with the final data line followed by two `\\n\\n` to properly terminate the event. Alternatively, JSON-serialize your data and then stringify it, ensuring any internal newlines are escaped as `\\n` within the JSON string itself (e.g., `data: {\"text\": \"line1\\nline2\"}\\n\\n`).","message":"Newlines within `data` fields in SSE messages can cause unexpected truncation or parsing errors on the client side, as `\\n` signifies the end of a line in the SSE protocol, and `\\n\\n` signifies the end of an event.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure `res.flushHeaders()` is called after setting SSE-specific headers (handled by `express-sse.init`). Check for proxy buffering or compression middleware interfering with the stream and disable them for the SSE route. For `express-sse`, ensure `sse.init` is correctly applied to the route.","cause":"The SSE stream is being buffered by a proxy, compression middleware, or Express itself is not flushing headers correctly.","error":"Client not receiving messages or receives all messages at once when `res.end()` is called."},{"fix":"If your project uses CommonJS (no `\"type\": \"module\"` in `package.json`), use `const SSE = require('express-sse');`. If using ES modules, ensure your Node.js environment supports them (Node.js >= 12 with `\"type\": \"module\"` or via Babel/TypeScript compilation), and use `import SSE from 'express-sse';`.","cause":"Attempting to use ES module `import` syntax in a CommonJS Node.js project or environment without proper transpilation/configuration.","error":"SyntaxError: Unexpected token 'export'"},{"fix":"Verify that `express-sse` is correctly installed (`npm install express-sse`) and that the `SSE` class is being imported/required as `const SSE = require('express-sse');` or `import SSE from 'express-sse';` before attempting to call `new SSE()`.","cause":"The `SSE` constructor was not properly imported or initialized, or `express-sse` might not be the package being installed.","error":"TypeError: Cannot read properties of undefined (reading 'init')"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}