Skip to content

CYB3RL1F3/react-server-sent-events

Repository files navigation

react-server-sent-events

A React library for Server-Sent Events (SSE) with TypeScript support

NPM TypeScript License

Features

  • 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

Installation

npm install react-server-sent-events
yarn add react-server-sent-events
pnpm add react-server-sent-events

Quick Start

1. Wrap your app with SSEProvider

import { SSEProvider } from 'react-server-sent-events'

function App() {
  return (
    <SSEProvider root="http://localhost:8001">
      <MyComponent />
    </SSEProvider>
  )
}

2. Use the useSSE hook in your components

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<MyResponse, MyPayload>()

  const connect = () => {
    open('/api/events', { userId: '123' })
  }

  return (
    <div>
      <button onClick={connect} disabled={isOpen}>
        Connect
      </button>
      <button onClick={close} disabled={!isOpen}>
        Disconnect
      </button>

      <p>Status: {status}</p>
      <p>Connected: {isOpen ? 'Yes' : 'No'}</p>

      {value && <p>Received: {JSON.stringify(value)}</p>}
      {error && <p>Error: {error.message}</p>}
    </div>
  )
}

API Reference

<SSEProvider>

The context provider that manages SSE connections.

Prop Type Description
root string Base URL for SSE endpoints
children ReactNode Child components

useSSE<T, P>()

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

ReadyState

Enum for connection states:

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

Custom Headers

The library sends POST requests with the following default headers:

{
  'Content-Type': 'application/json',
  'X-Event-Stream': 'SSE'
}

Using the SSE Class Directly

For advanced use cases, you can use the SSE class directly:

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

Prerequisites

  • Node.js >= 18

Setup

# Install dependencies
npm install

# Build the library
npm run build

Start the Demo

# 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

# Build
npm run build

# Watch mode
npm run dev

# Type checking
npm run typecheck

# Linting
npm run lint

Testing

The library includes comprehensive unit tests using Vitest.

# Run tests
npm run test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

Test Coverage

Tests cover:

  • SSE Class (src/utils.ts): Connection lifecycle, event parsing, error handling
  • React Components (src/index.tsx): SSEProvider, useSSE hook, state management

Pre-commit Hook

Tests run automatically before each commit via a git hook. To set it up manually:

# 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:

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)

License

MIT © CYB3RL1F3

About

A library to use Server Side Events in React components

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors