Modern EventSource client for browsers and Node.js
npm install eventsource-client
A modern, streaming client for server-sent events/eventsource.
Yes! There are indeed lots of different EventSource clients and polyfills out there. In fact, I am a co-maintainer of the most popular one. This one is different in a few ways, however:
- Works in both Node.js and browsers with minimal amount of differences in code
- Ships with both ESM and CommonJS versions
- Uses modern APIs such as the fetch() API and Web Streams
- Does NOT attempt to be API-compatible with the browser EventSource API:
- Supports async iterator pattern
- Supports any request method (POST, PATCH, DELETE etc)
- Supports setting custom headers
- Supports sending a request body
- Supports configurable reconnection policies
- Supports subscribing to any event (eg if event names are not known)
- Supports subscribing to events named error
- Supports setting initial last event ID
``bash`
npm install --save eventsource-client
- Node.js >= 18
- Chrome >= 63
- Safari >= 11.3
- Firefox >= 65
- Edge >= 79
- Deno >= 1.30
- Bun >= 1.1.23
Basically, any environment that supports:
- ReadableStream
- TextDecoderStream
- Symbol.asyncIterator
`ts
import {createEventSource} from 'eventsource-client'
const es = createEventSource({
url: 'https://my-server.com/sse',
// your fetch() implementation of choice, or globalThis.fetch if not set
fetch: myFetch,
})
let seenMessages = 0
for await (const {data, event, id} of es) {
console.log('Data: %s', data)
console.log('Event ID: %s', id) // Note: can be undefined
console.log('Event: %s', event) // Note: can be undefined
if (++seenMessages === 10) {
break
}
}
// IMPORTANT: EventSource is _not_ closed automatically when breaking out of
// loop. You must manually call close() to close the connection.`
es.close()
callback)`ts
import {createEventSource} from 'eventsource-client'
const es = createEventSource({
url: 'https://my-server.com/sse',
onMessage: ({data, event, id}) => {
console.log('Data: %s', data)
console.log('Event ID: %s', id) // Note: can be undefined
console.log('Event: %s', event) // Note: can be undefined
},
// your fetch() implementation of choice, or globalThis.fetch if not set
fetch: myFetch,
})
console.log(es.readyState) // open, closed or connecting
console.log(es.lastEventId)
// Later, to terminate and prevent reconnections:
es.close()
`
`ts
import {createEventSource} from 'eventsource-client'
const es = createEventSource('https://my-server.com/sse')
for await (const {data} of es) {
console.log('Data: %s', data)
}
`
Should you need to read/respond to comments, pass an onComment callback:
`ts
import {createEventSource} from 'eventsource-client'
const es = createEventSource({
url: 'https://my-server.com/sse',
onComment: (comment: string) => {
/ a single, leading space will be trimmed if present /
/ eg : hello and :hello will both yield hello /
},
})
``
- [ ] Figure out what to do on broken connection on request body
- [ ] Configurable stalled connection detection (eg no data)
- [ ] Configurable reconnection policy
- [ ] Consider legacy build
MIT © Espen Hovlandsdal