Summary
Next.js added a new unstable_io() export from next/cache behind the experimental.unstableIO config flag. This is a metasyntactic IO boundary that, during prerendering with cache components, returns a hanging promise to prevent execution of code that follows it. In all other contexts it resolves as a fulfilled thenable that React can unwrap synchronously.
Upstream
What changed
- New export
unstable_io from next/cache (both server and client/browser paths)
- New config option
experimental.unstableIO (boolean, default false)
- New env variable
process.env.__NEXT_UNSTABLE_IO
- Server implementation in
packages/next/src/server/request/io.ts with behavior varying by work unit type:
request: resolves immediately (production) or uses staged rendering (dev)
prerender / prerender-client / prerender-runtime: returns a hanging promise to prevent prerendering past the IO boundary
cache / unstable-cache / generate-static-params / prerender-legacy: resolves immediately
- Client/browser implementation always resolves immediately (returns a pre-resolved thenable)
- Throws if called without
experimental.unstableIO enabled
Impact on vinext
vinext shims next/cache and needs to add unstable_io to the shim. Since vinext primarily targets Cloudflare Workers (no prerendering context), the simplest correct implementation is:
- Add
unstable_io to the next/cache shim exports
- Have it return a pre-resolved thenable (same as the browser implementation)
- Optionally: gate behind
experimental.unstableIO config check and throw if not enabled (matching Next.js behavior)
This is gated behind an experimental flag and not ready for general use, so this is low priority.
Summary
Next.js added a new
unstable_io()export fromnext/cachebehind theexperimental.unstableIOconfig flag. This is a metasyntactic IO boundary that, during prerendering with cache components, returns a hanging promise to prevent execution of code that follows it. In all other contexts it resolves as a fulfilled thenable that React can unwrap synchronously.Upstream
What changed
unstable_iofromnext/cache(both server and client/browser paths)experimental.unstableIO(boolean, defaultfalse)process.env.__NEXT_UNSTABLE_IOpackages/next/src/server/request/io.tswith behavior varying by work unit type:request: resolves immediately (production) or uses staged rendering (dev)prerender/prerender-client/prerender-runtime: returns a hanging promise to prevent prerendering past the IO boundarycache/unstable-cache/generate-static-params/prerender-legacy: resolves immediatelyexperimental.unstableIOenabledImpact on vinext
vinext shims
next/cacheand needs to addunstable_ioto the shim. Since vinext primarily targets Cloudflare Workers (no prerendering context), the simplest correct implementation is:unstable_ioto thenext/cacheshim exportsexperimental.unstableIOconfig check and throw if not enabled (matching Next.js behavior)This is gated behind an experimental flag and not ready for general use, so this is low priority.