0
0
NextJSframework~5 mins

Streaming long operations in NextJS

Choose your learning style9 modes available
Introduction

Streaming long operations lets your app show results bit by bit instead of waiting for everything to finish. This makes users feel the app is faster and more responsive.

When loading large amounts of data from a server and you want to show partial results quickly.
When generating content that takes time, like reports or AI responses, and you want to display it as it arrives.
When you want to improve user experience by showing progress or partial content during slow operations.
When working with APIs that support streaming responses and you want to handle data progressively.
Syntax
NextJS
export async function GET(request) {
  const stream = new ReadableStream({
    async start(controller) {
      controller.enqueue(new TextEncoder().encode('Hello '));
      await new Promise(resolve => setTimeout(resolve, 1000));
      controller.enqueue(new TextEncoder().encode('World!'));
      controller.close();
    }
  });
  return new Response(stream);
}

This example shows a Next.js API route using a ReadableStream to send data in chunks.

Use controller.enqueue() to send parts of the response, and controller.close() to finish.

Examples
Sends two parts immediately, then closes the stream.
NextJS
export async function GET() {
  const stream = new ReadableStream({
    start(controller) {
      controller.enqueue(new TextEncoder().encode('Part 1 '));
      controller.enqueue(new TextEncoder().encode('Part 2'));
      controller.close();
    }
  });
  return new Response(stream);
}
Sends 'Loading', waits 1 second, then sends '...done'.
NextJS
export async function GET() {
  const stream = new ReadableStream({
    async start(controller) {
      controller.enqueue(new TextEncoder().encode('Loading'));
      await new Promise(r => setTimeout(r, 1000));
      controller.enqueue(new TextEncoder().encode('...done'));
      controller.close();
    }
  });
  return new Response(stream);
}
Sample Program

This Next.js API route streams text messages in three parts with 1-second pauses. The client receives updates progressively, improving user experience during long tasks.

NextJS
import { NextResponse } from 'next/server';

export async function GET() {
  const stream = new ReadableStream({
    async start(controller) {
      const encoder = new TextEncoder();
      controller.enqueue(encoder.encode('Starting operation...\n'));
      await new Promise(r => setTimeout(r, 1000));
      controller.enqueue(encoder.encode('Halfway there...\n'));
      await new Promise(r => setTimeout(r, 1000));
      controller.enqueue(encoder.encode('Operation complete!\n'));
      controller.close();
    }
  });

  return new NextResponse(stream, {
    headers: { 'Content-Type': 'text/plain; charset=utf-8' }
  });
}
OutputSuccess
Important Notes

Streaming works best with clients that can handle partial responses, like browsers or fetch API.

Always set proper Content-Type headers to help clients interpret streamed data.

Use TextEncoder to convert strings to bytes before enqueueing in the stream.

Summary

Streaming sends data in chunks so users see progress during long operations.

Use ReadableStream and controller.enqueue() in Next.js API routes to stream responses.

Streaming improves user experience by reducing wait perception.