Compatibility matrix
Honest, evidence-gated status of what the knext adapter supports.
Honest, evidence-gated status of what the knext adapter supports. Every row is grounded in real, on-disk evidence and a mechanical guard test fails CI if a ✅ ("supported") row cannot be backed up. When in doubt it is marked ⚠️, not ✅.
Status: a credentialing window is currently in progress, not complete.
The credential window now runs against Next.js v16.3.8. Every credential run executes against that
published release-candidate build, not the fast-moving main branch. New apps scaffold a
newer Next.js release on the 16.4.x line (16.4.3): every Next.js release up to and including 16.4.0 is
affected by critical security advisories (GHSA-2464-fhr4-w9xw, GHSA-673q-mjm6-r5xr) that are fixed
only on 16.4.x, so the scaffold moved ahead of the credential. knext doctor reports 16.4 as a
supported but not yet credentialed minor until the credential catches up. The separate credential
for the 1.3 release line has started running against Next.js v16.4.3; no run at that version has
counted yet. See
Next.js security upgrades. The 14-consecutive-run count needed before any cell is
considered fully credentialed started recently and has not yet completed for any cell — do not
read anything on this page as "14 of 14, passing." Dispatched confirmation runs at v16.3.8 passed
on all four v1.0 cells (node/bun x turbopack/webpack): 16 shards each, 1101 of 1101 tests passing.
Earlier confirmation runs at v16.3.5, before the v16.3.6 and v16.3.8 security updates, also passed
on all four. Neither is a substitute for the 14-run window. See
The official Next.js compatibility credential for exactly what the
credential covers, what counts as a credentialed run, and the honest current status.
The official suite runs per runtime × builder cell — not one number. knext builds and runs a
Next.js app more than one way (standalone on Node or Bun, built with Turbopack or webpack, or the
vinext build), and each combination is tracked separately rather than folded into a single "the suite is green" headline. The
most-verified cell overall is still the Turbopack build on the Node runtime, whose last
completed 14-run-eligible run observed 792 tests passed, 0 failed, at Next.js v16.2.12 — the
prior credentialed ref, kept here for history. The default cell — Turbopack on the Bun runtime, the
compiled bytecode executable — and the two webpack cells each have a 792/0 run behind them at
that same prior ref. See The official Next.js compatibility credential
for what credentialing requires and where every cell currently stands.
A handful of upstream tests introduced between the two releases encode behaviour that only Vercel's own hosting infrastructure produces (for example, a CDN cache header) rather than anything a self-hosted deploy can or should reproduce; those are documented and excluded the same way the architectural gaps below are, with their own evidence trail.
Legend
| Marker | Meaning |
|---|---|
| ✅ | Supported — backed by a red-on-fail check (the per-PR compat-smoke gate) or test-covered source on disk. |
| ⚠️ | Partial — implemented but not guarded by a hard correctness check, or with a known caveat. Do not rely on it as "verified." |
| ❌ | Unsupported / unverified — no working implementation or no evidence; treat as a gap. |
| ⛔ | Upstream-gated — architecturally out of reach today (global edge, not yet adapter-standardizable upstream). |
The compat-smoke job runs per-PR on a Node + Bun matrix. It is a knext smoke gate, not the
official suite.
Matrix
| Feature | Status | Notes |
|---|---|---|
App Router (RSC server render, GET / → 200 HTML) | ✅ | Hard-asserts 200 + text/html + non-trivial body against the standalone server.js. |
RSC flight payload (RSC: 1 → text/x-component) | ✅ | Hard-asserts the React flight content-type. |
Route handlers (app/api/*/route.ts) | ✅ | Hard-asserts GET /api/health → 200 + valid JSON. |
Dynamic routes (force-dynamic) | ✅ | Hard-asserts 200 on a force-dynamic route. |
Static / prerendered routes (force-static) | ✅ | Hard-asserts 200 on a force-static route. |
| Middleware (Node runtime, header injection) | ✅ | Hard-asserts a middleware-injected header. Node-runtime middleware only. |
| Graceful shutdown (SIGTERM drain) | ✅ | End-to-end proven on the shipped compiled-executable image: a real SIGTERM against a running container, asserting the in-flight request completes and the drain markers land in order. The same image also proves that after() work runs before the process exits 0, including work an after() callback schedules after the signal has landed. |
| ISR / Data Cache (Redis-backed cache handler) | ✅ | Redis cache handler, not GCS — registered by the vinext() plugin's cache.data adapter in vite.config.ts (Next's cacheHandler config option is not read by this build; see ISR & the Redis cache). The gate runs against a real Redis and asserts behaviour: back-to-back requests served from cache, the value changing after the revalidate window, the ISR route's own key present in Redis by name with a TTL longer than the revalidate window, and no cache-registration failure in the server log. |
next/image optimization (sharp, avif/webp) | ✅ | Accept: image/webp is honoured with content-type: image/webp, and the optimized output is materially smaller than the source — a hard, always-enforced check. |
Server Actions ('use server' mutations) | ✅ | A real round-trip over the no-JS progressive-enhancement path: the rendered form's action id is POSTed and its effect is asserted on a subsequent render. |
| Streaming / Suspense (incremental flush) | ✅ | Asserts chunk-arrival ordering: the shell marker must land in a strictly earlier chunk than the Suspense payload. |
| Edge Middleware (edge runtime) | ⛔ | Upstream-gated: edge-runtime middleware is not yet adapter-standardizable on Knative; knext middleware runs on the Node runtime only. |
| PPR / Cache Components | ⛔ | Upstream-gated: Partial Prerendering / Cache Components are not yet adapter-standardizable. |
| Official suite — Turbopack build, Node runtime | ✅ | build: 'turbopack', runtime: 'node' — the uncompiled fallback, not the default. 792 passed / 0 failed (16 shards, Next.js v16.2.12, deploy mode), most recently observed on the main-branch nightly (early warning — see below for what counts toward a v1.0 credential). Covers Next's deploy-eligible e2e set minus 4 documented architectural exclusions (the ⛔ rows) and a small evidence-backed flaky-quarantine ledger — see the compatibility credential. A red nightly withdraws this row. |
| Official suite — Turbopack build, Bun runtime, compiled executable (default) | ✅ | This is knext's default (build: 'turbopack', runtime: 'bun') — a bytecode executable that runs inside the standalone folder. One dispatched run on the compiled executable: 792 passed / 0 failed (16 shards, Next.js v16.2.12, Bun 1.4.2), with every deploy confirmed to boot the bytecode executable. A later dispatched run at Next.js v16.3.8 passed 1101 of 1101. Verified in dispatched runs, not credentialed: the credential needs 14 consecutive scheduled runs against a release candidate. |
| Official suite — Webpack build, Node and Bun runtimes | ✅ | build: 'webpack'. One dispatched run per runtime, each 792 passed / 0 failed (16 shards, Next.js v16.2.12). A later dispatched run per runtime at Next.js v16.3.8 passed 1101 of 1101. Passed in dispatched runs, not credentialed. |
Official suite — vinext build, Bun runtime | ❌ | Selectable (build: 'vinext'), not the default, and not credentialed in v1.0. The most recent measured run (Next.js v16.3.6, Bun 1.4.2) passed 1016 of 1099 files. Of the 83 that did not, 41 are disclosed known-gap files — vinext does not implement the Next.js 16.3 client-router architecture — 6 are individually quarantined and 36 fail. On the official suite minus those 41 disclosed known-gap files (client-router architecture), 1016 of 1058 pass; vinext remains Beta. That number is a measurement, not a claim of parity, and it is not the bar the default-target cells meet. See Bun & the compiled executable. |
Official suite — vinext build, Node runtime | ⚠️ | Buildable: knext build produces a Node server and an image that ships the V8 compile cache baked in, proven by a per-PR build-and-boot check. The suite has no lane for this cell yet. See vinext on Node. |
v1.0 credentialing
A green suite run is evidence for a cell; it is not the same claim as v1.0-credentialed. Each
of the four v1.0 cells (Node and Bun, each on Turbopack and on webpack) must independently bank 14
consecutive scheduled, independent runs (three a day, at least two hours apart, each with fresh caches), run against a frozen release build of knext (not the fast-moving main
branch), before it counts toward v1.0. The vinext cells are outside the credential and stay Beta. Main
nightlies keep running as an early-warning signal and can flip a row back to ❌ on a regression, but
they never advance a cell's credential count. No cell is credentialed today. Full detail:
the compatibility credential.
Maintenance & honesty
- Every ✅ is mechanically gated. In the knext source repository, a guard test parses this
table's canonical twin and fails CI if a ✅ row's evidence does not resolve to real on-disk
files, a hard
compat-smokecheck, or a recorded green run. - The official-suite claims are revocable, not permanent. Each cell's ✅ or ⚠️ is backed by the most recently cited run; a shard with any failed test fails the job, a red scheduled run raises an alarm, and the policy is to flip the affected row back and withdraw the claim.
This page mirrors the CI-guarded compatibility matrix in the knext source repository, which is the canonical source. If the two ever diverge, the source-repo file wins.
The official Next.js compatibility credential
Exactly what knext's compatibility credential covers, what it does not, and its current status — stated honestly, not as a marketing claim.
SCS / Zones
Self-Contained Systems and Multi-Zones on knext — the architecture, the hard rules, and what's recipe-level today.