[GH-ISSUE #805] Add unstable_io shim for next/cache export #176

Closed
opened 2026-05-06 12:37:53 +02:00 by BreizhHardware · 1 comment

Originally created by @github-actions[bot] on GitHub (Apr 9, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/805

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:

  1. Add unstable_io to the next/cache shim exports
  2. Have it return a pre-resolved thenable (same as the browser implementation)
  3. 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.

Originally created by @github-actions[bot] on GitHub (Apr 9, 2026). Original GitHub issue: https://github.com/cloudflare/vinext/issues/805 ## 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 - Commit: https://github.com/vercel/next.js/commit/e22dc27d8f61eb4ca9dad762d4e46b1f812fdf86 - PR: https://github.com/vercel/next.js/pull/92521 ## 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: 1. Add `unstable_io` to the `next/cache` shim exports 2. Have it return a pre-resolved thenable (same as the browser implementation) 3. 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.
BreizhHardware 2026-05-06 12:37:53 +02:00
Author
Owner

@github-actions[bot] commented on GitHub (Apr 18, 2026):

Update from Next.js canary (2026-04-17):

9f2779eRemove flag guarding unstable_io: The experimental.unstableIO config option has been removed entirely. unstable_io() now works without any config flag — the guard that threw 'unstable_io() requires the experimental.unstableIO option' has been deleted from both the server (server/request/io.ts) and browser (client/request/io.browser.ts) implementations.

When implementing the vinext shim, there's no need to check for a config flag. The function should work unconditionally.

<!-- gh-comment-id:4273210354 --> @github-actions[bot] commented on GitHub (Apr 18, 2026): **Update from Next.js canary (2026-04-17):** [`9f2779e`](https://github.com/vercel/next.js/commit/9f2779ec57c3f9afff50af4ae7947e648fa183c0) — **Remove flag guarding `unstable_io`**: The `experimental.unstableIO` config option has been removed entirely. `unstable_io()` now works without any config flag — the guard that threw `'unstable_io() requires the experimental.unstableIO option'` has been deleted from both the server (`server/request/io.ts`) and browser (`client/request/io.browser.ts`) implementations. When implementing the vinext shim, there's no need to check for a config flag. The function should work unconditionally.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#176
No description provided.