Skip to content
Tutorial
11 min read

Vercel Streaming Quickstart

Learn how to stream responses from Serverless and Edge Functions to provide an improved user experience.
Table of Contents
Choose a framework to optimize documentation to:

In this quickstart, you'll learn how to get started with streaming on Vercel. The guide will cover:

  • Creating an Edge or Serverless Function
  • Using the Web Streams API to stream an API response
  • Deploying an Edge or Serverless Function with Vercel CLI
  1. You should have the latest version of Vercel CLI installed. To check your version, use vercel --version. To install or update Vercel CLI, use:

    pnpm
    yarn
    npm
    pnpm i -g vercel@latest
  2. You should have an existing project. If you don't have one, you can run the following terminal commands to create a Next project:

    pnpm
    yarn
    npm
    pnpm i next
    terminal
    npx create-next-app@latest
  3. Your preferred framework should support streaming

This guide will lead with Edge Function examples. Serverless streaming is available in Next.js by switching the runtime config value to "nodejs". Vercel only supports Serverless streaming in other frameworks if it's built into them, such as SvelteKit.

Check your preferred framework's docs to learn if it supports streaming. Otherwise, Vercel recommends streaming with Edge Functions.

Learn more about selecting a runtime in Choosing a Runtime.

  1. To get started, first create app/api/streaming-example/route.ts
  1. Then, add the following code, which sets up a basic Function with a route handler method:

    Next.js (/app)
    Next.js (/pages)
    Other frameworks
    app/api/streaming-example/route.ts
    // Can be 'nodejs', but Vercel recommends using 'edge'
    export const runtime = 'edge';
    // Prevents this route's response from being cached
    export const dynamic = 'force-dynamic';
     
    // This method must be named GET
    export async function GET() {
      // Streaming code will go here
    }
    To learn more about creating Edge Functions, see Edge Functions quickstart.

A ReadableStream is a stream of data that can be read. To demonstrate a basic example of streaming on Vercel, this quickstart will show you how to send a ReadableStream as a response to requests to your Function.

Add the following code to your API method to instantiate a new ReadableStream:

const customReadable = new ReadableStream({
  start(controller) {},
});

The start method is where you provide your ReadableStream with a data source, or begin generating the data that will be streamed. The function will generate a string of text to demonstrate basic streaming functionality.

To do so, use the TextEncoder interface, which emits a stream of text as UTF-8 bytes.

Update your API handler so that its code looks like this:

// This encoder will stream your text
const encoder = new TextEncoder();
const customReadable = new ReadableStream({
  start(controller) {
    // Start encoding 'Basic Streaming Test',
    // and add the resulting stream to the queue
    controller.enqueue(encoder.encode('Basic Streaming Test'));
    // Prevent anything else being added to the stream
    controller.close();
  },
});

To complete your Function, return a new instance of a Response object. Pass your customReadable as an argument to the constructor, along with the appropriate Content-Type headers. Add the following to the end of your API handler:

return new Response(customReadable, {
  headers: { 'Content-Type': 'text/html; charset=utf-8' },
});

Finally, the whole file should look like this:

Next.js (/app)
Next.js (/pages)
Other frameworks
app/api/streaming-example/route.ts
// Can be 'nodejs', but Vercel recommends using 'edge'
export const runtime = 'edge';
// Prevents this route's response from being cached
export const dynamic = 'force-dynamic';
 
// This method must be named GET
export async function GET() {
  // This encoder will stream your text
  const encoder = new TextEncoder();
  const customReadable = new ReadableStream({
    start(controller) {
      // Start encoding 'Basic Streaming Test',
      // and add the resulting stream to the queue
      controller.enqueue(encoder.encode('Basic Streaming Test'));
      // Prevent anything else being added to the stream
      controller.close();
    },
  });
 
  return new Response(customReadable, {
    headers: { 'Content-Type': 'text/html; charset=utf-8' },
  });
}

Use next dev to start a local development server:

terminal
next dev

Navigate to http://localhost:3000/api/streaming-example to see the streamed response from your route.

The page should display the message "Basic Streaming Text".

Last updated on December 1, 2023