Backend Development 7 min read

Implementing Server‑Sent Events (SSE) with NestJS and React

This tutorial explains the concept of Server‑Sent Events, compares it with WebSocket, and provides a step‑by‑step guide to create an SSE endpoint in a NestJS backend, enable CORS, and consume the stream from a React frontend using the native EventSource API.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing Server‑Sent Events (SSE) with NestJS and React

When thinking about pushing data from server to client, WebSocket often comes to mind because it supports full‑duplex communication, but for one‑way push scenarios the HTTP‑based Server‑Sent Events (SSE) is a simpler alternative.

SSE works by returning a response with Content‑Type: text/event-stream , which keeps the connection open and allows the server to send multiple JSON messages over time.

To try it yourself, first create a NestJS project:

npx nest new sse-test

Start the development server:

npm run start:dev

Add an SSE endpoint in AppController using the @Sse decorator. The method returns an Observable that calls observer.next whenever a new message should be sent.

@Sse('stream')
stream() {
  return new Observable(observer => {
    observer.next({ data: { msg: 'aaa' } });
    setTimeout(() => {
      observer.next({ data: { msg: 'bbb' } });
    }, 2000);
    setTimeout(() => {
      observer.next({ data: { msg: 'ccc' } });
    }, 5000);
  });
}

On the frontend, create a React TypeScript project and use the native EventSource API to connect to the SSE endpoint. The onmessage handler parses the incoming JSON and logs it.

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    const eventSource = new EventSource('http://localhost:3000/stream');
    eventSource.onmessage = ({ data }) => {
      console.log('New message', JSON.parse(data));
    };
  }, []);

  return
hello
;
}

export default App;

Enable CORS in the NestJS application so the browser can access the endpoint from a different origin.

SSE also works well for streaming logs or ChatGPT‑style incremental responses. By executing tail -f via child_process.exec and forwarding the stdout data through an SSE stream, you can display real‑time log updates in the browser.

const { exec } = require('child_process');
const childProcess = exec('tail -f ./log');
return new Observable(observer => {
  childProcess.stdout.on('data', msg => {
    observer.next({ data: { msg } });
  });
});

Binary data can also be sent: read a file into a Buffer , call toJSON() to obtain a JSON‑serializable representation, and push it through SSE.

const { readFileSync } = require('fs');
const json = readFileSync('./package.json').toJSON();
observer.next({ data: { msg: json } });

Compatibility is good: all modern browsers except IE support SSE, and the browser automatically reconnects if the connection drops, unlike WebSocket which requires manual reconnection.

Typical use cases include internal notifications, real‑time build logs, and incremental AI responses, making SSE a lightweight alternative to WebSocket for one‑directional server push scenarios.

real-timeReactBackend DevelopmentServer-Sent EventsSSENestJS
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.