The floor
What is not going to change is accepted limits; what moving version to version costs is versions and upgrades; installing is where the floor first bites; and coming from a Node backend is the longer list of what the runtime does not have.
Node 22 or newer. Declared in every package’s engines.node.
TypeScript 7’s compiler needs it, and Workers’ own compatibility surface is at parity with it.
The compatibility date
2026-06-01. pithy init scaffolds an adopter’s Worker at that date, the starter template states it, and the kit’s own Workers run the same one.
How nine Workers came to sit fifteen months behind
Every one of them said 2025-01-01. Not one had been argued for.
A new capability’s wrangler.jsonc is written by copying a sibling’s, so the first Worker’s unconsidered default became the ninth’s — and seventeen test configs copied it too.
That second population is the worse half. A harness pinned older than the Worker it is evidence about is not evidence, and a full day went into a phantom unhandled rejection that only the harness could still produce.
Why this date rather than the minimum that worked
2026-03-03 was the floor on offer — the date workerd turns on the behavior that bug bisected to.
It was declined, because the minimum that fixes the last bug is exactly what 2025-01-01 once was.
A date chosen to clear one known defect is a date nobody will revisit until the next defect, and the argument for moving it will be as narrow the second time.
2026-06-01 was chosen because it is the date this repository already ships to everybody else — so there is one date in the tree rather than two, which matters most where a defect is reported by an adopter and reproduced in the kit.
What to do about yours
Do not copy a sibling’s. If you are adding a Worker by hand, take the date pithy init writes.
When you move it, move the test harness with it. A test config pinned behind the Worker it exercises is the failure above, in miniature.
Read the changes you are adopting. Cloudflare publishes them per date, and the set is invisible until something in it matters is precisely the reason to look before rather than after.
Runtime constraints that follow
No code generation at runtime. The email capability’s templates are precompiled at build time and its registry is closed to adopters for exactly this reason — a template compiled where it runs is a template that cannot run.
No filesystem. Bytes go to R2, structured data to D1.
No long-lived process. Module-level mutable state may or may not survive to the next request, and is certainly not shared globally.
A bounded CPU budget per request. Anything slow persists first and dispatches a Workflow after.
What the kit does about node: imports
The packages that could avoid a node: import do.
The locale-marker reader, the string work behind a prose census, the dashboard contract module — each reaches for no timer, no fetch, and nothing from node, so it compiles in a Worker as readily as in a build script.