
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
eventsource
Advanced tools
WhatWG/W3C-compatible server-sent events/eventsource client. The module attempts to implement an absolute minimal amount of features/changes beyond the specification.
If you're looking for a modern alternative with a less constrained API, check out the eventsource-client package.
npm install --save eventsource
Basically, any environment that supports:
If you need to support runtimes without private class fields, methods and accessors, try the 4.x branch/version range.
If you need to support even older runtimes, try the 2.x branch/version range (note: 2.x branch is primarily targeted at Node.js, not browsers).
import {EventSource} from 'eventsource'
const es = new EventSource('https://my-server.com/sse')
/*
* This will listen for events with the field `event: notice`.
*/
es.addEventListener('notice', (event) => {
console.log(event.data)
})
/*
* This will listen for events with the field `event: update`.
*/
es.addEventListener('update', (event) => {
console.log(event.data)
})
/*
* The event "message" is a special case, as it will capture events _without_ an
* event field, as well as events that have the specific type `event: message`.
* It will not trigger on any other event type.
*/
es.addEventListener('message', (event) => {
console.log(event.data)
})
/**
* To explicitly close the connection, call the `close` method.
* This will prevent any reconnection from happening.
*/
setTimeout(() => {
es.close()
}, 10_000)
Make sure you have configured your TSConfig so it matches the environment you are targetting. If you are targetting browsers, this would be dom:
{
"compilerOptions": {
"lib": ["dom"],
},
}
If you're using Node.js, ensure you have @types/node installed (and it is version 22 or higher). Cloudflare workers have @cloudflare/workers-types etc.
The following errors are caused by targetting an environment that does not have the necessary types available:
error TS2304: Cannot find name 'Event'.
error TS2304: Cannot find name 'EventTarget'.
error TS2304: Cannot find name 'MessageEvent'.
Cloudflare Workers require compatibilityDate: '2024-11-11' or later, and addEventListener() instead of the onmessage, onopen and onerror properties.
workerd's EventTarget dispatches on<type> handler properties itself, on top of the listener this module registers, so a handler assigned that way is called twice per event - and assigning null only removes one of the two registrations, so it does not unsubscribe (workerd#6022).
// Called twice per message on Cloudflare Workers
eventSource.onmessage = (event) => console.log(event.data)
// Use this instead
eventSource.addEventListener('message', (event) => console.log(event.data))
workerd also drops origin and lastEventId from the MessageEvent constructor. This module assigns them itself, so both are correct on Workers today; the workaround goes away once workerd#6995 lands.
See MIGRATION.md for a detailed migration guide.
The error event has a message and code property that can be used to get more information about the error. In the specification, the Event
es.addEventListener('error', (err) => {
if (err.code === 401 || err.code === 403) {
console.log('not authorized')
}
})
The parser buffers up to 100 MB while waiting for a complete EventSource line. To change that limit, pass maxBufferSize in the constructor options:
const es = new EventSource('https://my-server.com/sse', {
maxBufferSize: 10 * 1024 * 1024, // 10 MB
})
If the limit is exceeded, the connection fails and emits an error event, and will not reconnect. Prefer servers that emit smaller chunks or newlines more frequently over increasing this limit.
fetch implementationThe EventSource constructor accepts an optional fetch property in the second argument that can be used to specify the fetch implementation to use.
This can be useful in environments where the global fetch function is not available - but it can also be used to alter the request/response behaviour.
const es = new EventSource('https://my-server.com/sse', {
fetch: (input, init) =>
fetch(input, {
...init,
headers: {
...init.headers,
Authorization: 'Bearer myToken',
},
}),
})
Use a package like undici to add proxy support, either through environment variables or explicit configuration.
// npm install undici --save
import {fetch, EnvHttpProxyAgent} from 'undici'
const proxyAgent = new EnvHttpProxyAgent()
const es = new EventSource('https://my-server.com/sse', {
fetch: (input, init) => fetch(input, {...init, dispatcher: proxyAgent}),
})
Use a package like undici that supports HTTP2.
// npm install undici --save
import {Agent, fetch} from 'undici'
const http2Dispatcher = new Agent({allowH2: true})
const es = new EventSource('https://my-server.com/sse', {
fetch: (url, init) => fetch(url, {...init, dispatcher: http2Dispatcher}),
})
Use a package like undici for more control of fetch options through the use of an Agent.
// npm install undici --save
import {fetch, Agent} from 'undici'
const unsafeAgent = new Agent({
connect: {
rejectUnauthorized: false,
},
})
await fetch('https://my-server.com/sse', {
dispatcher: unsafeAgent,
})
For library authors, you may want to feature-check if an EventSource implementation supports passing a custom fetch implementation (such as this library does). We declare (from v4.1.0 and onwards) a non-enumerable symbol on the EventSource class to indicate this, named eventsource.supports-fetch-override. It can be used downstream such as:
function yourLibrary(options) {
const OurEventSource = options.polyfills.EventSource || globalThis.EventSource
if (OurEventSource && Symbol.for('eventsource.supports-fetch-override') in OurEventSource) {
// We can safely assume this supports overriding/specifying `fetch`!
const es = new OurEventSource('https://some.url', {
fetch: (input, init) =>
fetch(input, {
...init,
headers: {
...(init.headers || {}),
'x-some-header': 'foo',
},
}),
})
// …
}
}
MIT-licensed. See LICENSE.
The sse-client package is another implementation of the EventSource API for Node.js. It provides similar functionality for connecting to SSE servers and handling server-sent events. Compared to eventsource, it may have different API nuances or additional features, but the core functionality remains the same.
Oceanwind is not a direct alternative to eventsource, but it is an example of a package that uses server-sent events to provide real-time updates to clients. It is a library for managing real-time communication between servers and clients, and it may include an SSE implementation as part of its feature set.
FAQs
WhatWG/W3C compliant EventSource client for Node.js and browsers
The npm package eventsource receives a total of 52,791,933 weekly downloads. As such, eventsource popularity was classified as popular.
We found that eventsource demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.