A library to use Server Side Events in React components
npm install react-server-sent-events> A React library for Server-Sent Events (SSE) with TypeScript support



- Full TypeScript support with generics
- React Context API for global SSE state management
- Support for POST requests with custom payloads
- Connection status tracking (INITIALIZING, CONNECTING, OPEN, CLOSED)
- Automatic error handling
- Works with React 18 and 19
``bash`
npm install react-server-sent-events
`bash`
yarn add react-server-sent-events
`bash`
pnpm add react-server-sent-events
`tsx
import { SSEProvider } from 'react-server-sent-events'
function App() {
return (
)
}
`
`tsx
import { useSSE } from 'react-server-sent-events'
type MyPayload = { userId: string }
type MyResponse = { message: string; timestamp: string }
function MyComponent() {
const { open, close, isOpen, status, value, error } = useSSE
const connect = () => {
open('/api/events', { userId: '123' })
}
return (
Status: {status}
Connected: {isOpen ? 'Yes' : 'No'}
{value &&
Received: {JSON.stringify(value)}
}Error: {error.message}
}API Reference
$3
The context provider that manages SSE connections.
| Prop | Type | Description |
|------|------|-------------|
|
root | string | Base URL for SSE endpoints |
| children | ReactNode | Child components |$3
Hook to access SSE functionality. Accepts two generic types:
-
T - Type of the received value
- P - Type of the payload sent when opening connection#### Returns
| Property | Type | Description |
|----------|------|-------------|
|
open | (endpoint: string, payload: P) => void | Opens an SSE connection |
| close | () => void | Closes the current connection |
| isOpen | boolean | Whether the connection is open |
| status | ReadyState | Current connection status |
| value | T \| null | Last received value |
| error | SseError \| null | Error information if any |$3
Enum for connection states:
`typescript
enum ReadyState {
INITIALIZING = -1, // Connection not yet established
CONNECTING = 0, // Connection being established
OPEN = 1, // Connection open and receiving events
CLOSED = 2 // Connection closed
}
`> Note:
XHRStates is deprecated. Use ReadyState instead.Advanced Usage
$3
The library sends POST requests with the following default headers:
`typescript
{
'Content-Type': 'application/json',
'X-Event-Stream': 'SSE'
}
`$3
For advanced use cases, you can use the
SSE class directly:`typescript
import { SSE, SSEOptionsMethod } from 'react-server-sent-events'const sse = new SSE('http://localhost:8001/api/events', {
headers: { 'Authorization': 'Bearer token' },
method: SSEOptionsMethod.POST,
payload: JSON.stringify({ data: 'value' }),
withCredentials: true
})
sse.addEventListener('message', (event) => {
console.log('Received:', event.data)
})
sse.addEventListener('error', (event) => {
console.error('Error:', event)
})
sse.stream()
// Later...
sse.close()
`Running the Example
$3
- Node.js >= 18
$3
`bash
Install dependencies
npm installBuild the library
npm run build
`$3
`bash
Terminal 1 - Start the SSE demo server
cd example
npm run server
Server running at http://localhost:8001
Terminal 2 - Start the React app
cd example
npm start
App running at http://localhost:5173
`The demo server sends events every second with a counter and timestamp.
Development
`bash
Build
npm run buildWatch mode
npm run devType checking
npm run typecheckLinting
npm run lint
`Testing
The library includes comprehensive unit tests using Vitest.
`bash
Run tests
npm run testRun tests in watch mode
npm run test:watchRun tests with coverage
npm run test:coverage
`$3
Tests cover:
- SSE Class (
src/utils.ts): Connection lifecycle, event parsing, error handling
- React Components (src/index.tsx): SSEProvider, useSSE hook, state management$3
Tests run automatically before each commit via a git hook. To set it up manually:
`bash
The hook is already configured in .husky/pre-commit
npm run test
`Server-Side Implementation
Your SSE server should respond with the following format:
`
id: 1
event: message
data: {"your": "json", "data": "here"}`Example Node.js server using better-sse:
`javascript
import express from 'express'
import { createSession } from 'better-sse'const app = express()
app.use(express.json())
app.post('/api/events', async (req, res) => {
const session = await createSession(req, res)
let counter = 0
const interval = setInterval(() => {
if (!session.isConnected) {
clearInterval(interval)
return
}
counter++
session.push({ time: new Date(), counter }, 'message', String(counter))
}, 1000)
session.on('disconnected', () => clearInterval(interval))
})
app.listen(8001)
``MIT © CYB3RL1F3