vuejs/core · error · Error

ReadableStream constructor is not available in the global sc

Error message

ReadableStream constructor is not available in the global scope. If the target environment does support web streams, consider using pipeToWebWritable() with an existing WritableStream instance instead.

What it means

Thrown by renderToWebStream in @vue/server-renderer when the global ReadableStream constructor is missing (`typeof ReadableStream !== 'function'`). Web Streams must be globally available for this entry point; older Node versions and some runtimes lack it. renderToStream.ts:150 fails fast and points to pipeToWebWritable() with a caller-supplied WritableStream as the alternative.

Source

Thrown at packages/server-renderer/src/renderToStream.ts:150

    push(content) {
      if (content != null) {
        writable.write(content)
      } else {
        writable.end()
      }
    },
    destroy(err) {
      writable.destroy(err)
    },
  })
}

export function renderToWebStream(
  input: App | VNode,
  context: SSRContext = {},
): ReadableStream {
  if (typeof ReadableStream !== 'function') {
    throw new Error(
      `ReadableStream constructor is not available in the global scope. ` +
        `If the target environment does support web streams, consider using ` +
        `pipeToWebWritable() with an existing WritableStream instance instead.`,
    )
  }

  const encoder = new TextEncoder()
  let cancelled = false

  return new ReadableStream({
    start(controller) {
      renderToSimpleStream(input, context, {
        push(content) {
          if (cancelled) return
          if (content != null) {
            controller.enqueue(encoder.encode(content))
          } else {
            controller.close()

View on GitHub (pinned to a2b40db9a8)

Solutions

  1. Upgrade to Node 18+ (or a runtime) that provides a global ReadableStream.
  2. Polyfill the global: `globalThis.ReadableStream = require('node:stream/web').ReadableStream` before importing the renderer.
  3. Switch to pipeToWebWritable(app, {}, existingWritableStream) passing a stream you construct yourself.
  4. Use renderToNodeStream/pipeToNodeWritable (CJS) if you cannot add Web Streams.

Example fix

// before (Node < 18, no global ReadableStream)
const stream = renderToWebStream(app)

// after — polyfill, then call
import { ReadableStream } from 'node:stream/web'
globalThis.ReadableStream = globalThis.ReadableStream || ReadableStream
const stream = renderToWebStream(app)
Defensive patterns

Strategy: validation

Validate before calling

// Check Web Streams availability before renderToWebStream.
function supportsWebStreams() {
  return typeof ReadableStream === 'function'
}
if (!supportsWebStreams()) {
  throw new Error('Upgrade to Node 18+ or polyfill globalThis.ReadableStream')
}

Type guard

function hasGlobalReadableStream(): boolean {
  return typeof (globalThis as any).ReadableStream === 'function'
}

Prevention

When it happens

Trigger: Calling renderToWebStream(input) on a Node version below 18 (or an environment) without a global ReadableStream; running SSR on a runtime that polyfills fetch but not Web Streams.

Common situations: SSR on Node 16 or earlier; edge workers/sandboxes without full Web Streams; an SSR server upgraded to a newer @vue/server-renderer while staying on an older Node.

Related errors


AI-assisted analysis of vuejs/core@a2b40db9a8 (2026-08-12). Data as JSON: /api/errors/ead0484213ab65bf. Report an issue: GitHub.