Skip to content

Make QuickJS the default workflow VM engine - #3253

Draft
TooTallNate wants to merge 1 commit into
quickjs-vm-threshold-snapshotsfrom
quickjs-vm-default
Draft

Make QuickJS the default workflow VM engine#3253
TooTallNate wants to merge 1 commit into
quickjs-vm-threshold-snapshotsfrom
quickjs-vm-default

Conversation

@TooTallNate

Copy link
Copy Markdown
Member

What

Flips the default workflow VM engine to QuickJS (WASM). The node:vm engine remains fully supported as an explicit opt-in via WORKFLOW_VM=node — the inverse of the previous arrangement.

Changes

  • Runtime (vm-mode.ts): useQuickJSVm now defaults to QuickJS when neither the run's stamped executionContext.workflowVm nor WORKFLOW_VM specifies an engine. Run affinity is unchanged: existing runs keep executing on the engine stamped at start().
  • CI matrix inverted: quickjs legs now leave WORKFLOW_VM unset, so they exercise the real default-selection path end to end; node legs opt in explicitly with WORKFLOW_VM=node. Job names and artifact files are unchanged (labels carried via MATRIX_VM). Applies to the script-generated legs (local dev/prod/postgres + vercel prod) and the hardcoded Vitest-plugin / Windows matrices.
  • Tests: entrypoint tests that assert node replay-loop internals against mock worlds (runtime.test.ts, runtime-trace-mode.test.ts, precondition-guard-replay.test.ts, wait-completion-replay.test.ts) pin WORKFLOW_VM=node — under the new default they'd instantiate a QuickJS WASM VM per entrypoint call.
  • Docs: WORKFLOW_VM default updated in runtime-tuning; changeset (minor) included.

Verification

  • vm-mode.test.ts: default → quickjs, empty value → quickjs, node → node:vm, run-stamp precedence unchanged (23 tests)
  • Full core suite: 1726 passed | 3 expected fail
  • Local e2e smoke with WORKFLOW_VM unset: dev server logs Using QuickJS VM engine, tests green; with WORKFLOW_VM=node: zero quickjs engine logs, tests green
  • Matrix script output: 15 default-engine legs (vm: "") + 14 explicit-node legs, snapshot leg included

…ck into node:vm)

- useQuickJSVm defaults to the QuickJS engine when neither the run's
  stamped executionContext.workflowVm nor WORKFLOW_VM specifies one;
  WORKFLOW_VM=node is the explicit node:vm opt-in.
- CI matrix inverted to match: quickjs legs leave WORKFLOW_VM unset so
  the default-selection path is exercised end to end; node legs opt in
  explicitly (labels/artifacts unchanged via MATRIX_VM).
- Entrypoint tests that assert node replay-loop internals against mock
  worlds pin WORKFLOW_VM=node (the quickjs path would instantiate a WASM
  VM per call).
- Docs + changeset updated. Runs keep the engine stamped at start().
@TooTallNate
TooTallNate requested review from a team and ijjk as code owners July 31, 2026 08:52
Copilot AI review requested due to automatic review settings July 31, 2026 08:52
@changeset-bot

changeset-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f57fd88

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 16 packages
Name Type
@workflow/core Minor
@workflow/builders Patch
@workflow/cli Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/vitest Patch
@workflow/web-shared Patch
@workflow/web Patch
workflow Minor
@workflow/world-testing Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch
@workflow/nuxt Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview Jul 31, 2026 8:55am
example-nextjs-workflow-webpack Ready Ready Preview Jul 31, 2026 8:55am
example-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-astro-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-express-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-fastify-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-hono-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-nestjs-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-nitro-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-nuxt-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-sveltekit-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-tanstack-start-workflow Ready Ready Preview Jul 31, 2026 8:55am
workbench-vite-workflow Ready Ready Preview Jul 31, 2026 8:55am
workflow-docs Ready Ready Preview, v0 Jul 31, 2026 8:55am
workflow-swc-playground Ready Ready Preview Jul 31, 2026 8:55am
workflow-tarballs Ready Ready Preview Jul 31, 2026 8:55am
workflow-web Ready Ready Preview Jul 31, 2026 8:55am

@TooTallNate TooTallNate added the event-log-race-repro Run the event log race reproduction job label Jul 31, 2026
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

Some tests failed

❌ Failed E2E Tests

vercel-multi-region (24 failed)

nextjs-turbopack (24 failed):

  • multi-region (world-vercel) explicit region: start({ region }) in the test process start({ region: iad1 }) mints a tagged run ID and executes there
  • multi-region (world-vercel) explicit region: start({ region }) in the test process start({ region: sfo1 }) mints a tagged run ID and executes there
  • multi-region (world-vercel) explicit region: start({ region }) in the test process start({ region: fra1 }) mints a tagged run ID and executes there
  • multi-region (world-vercel) explicit region: start({ region }) in the test process concurrent starts across all regions stay isolated
  • multi-region (world-vercel) explicit region: start({ region }) in the test process every provisioned region executes and completes a tagged run
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/iad1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/arn1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/bom1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/cdg1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/cle1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/cpt1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/dub1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/fra1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/gru1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/hkg1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/hnd1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/icn1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/kix1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/lhr1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/pdx1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/sfo1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/sin1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/syd1 mints a run tagged with its VERCEL_REGION
  • multi-region (world-vercel) implicit region: region-pinned routes without a region option /api/e2e-region-implicit/yul1 mints a run tagged with its VERCEL_REGION

E2E Test Summary

Summary
Passed Failed Skipped Total
✅ ▲ Vercel Production 2910 0 478 3388
✅ 💻 Local Development 3126 0 416 3542
✅ 📦 Local Production 3396 0 454 3850
✅ 🐘 Local Postgres 3396 0 454 3850
✅ 🪟 Windows 308 0 0 308
✅ 📋 Other 2040 0 424 2464
❌ vercel-multi-region 3 24 0 27
Total 15179 24 2226 17429
Details by Category

✅ ▲ Vercel Production

App Passed Failed Skipped
✅ astro-node 126 0 28
✅ astro-quickjs 126 0 28
✅ example-node 126 0 28
✅ example-quickjs 126 0 28
✅ express-node 126 0 28
✅ express-quickjs 126 0 28
✅ fastify-node 126 0 28
✅ fastify-quickjs 126 0 28
✅ hono-node 126 0 28
✅ hono-quickjs 126 0 28
✅ nextjs-turbopack-node 151 0 3
✅ nextjs-turbopack-quickjs 151 0 3
✅ nextjs-webpack-node 151 0 3
✅ nextjs-webpack-quickjs 151 0 3
✅ nitro-node 126 0 28
✅ nitro-quickjs 126 0 28
✅ nuxt-node 126 0 28
✅ nuxt-quickjs 126 0 28
✅ sveltekit-node 145 0 9
✅ sveltekit-quickjs 145 0 9
✅ vite-node 126 0 28
✅ vite-quickjs 126 0 28

✅ 💻 Local Development

App Passed Failed Skipped
✅ astro-stable-node 128 0 26
✅ astro-stable-quickjs 128 0 26
✅ express-stable-node 128 0 26
✅ express-stable-quickjs 128 0 26
✅ fastify-stable-node 128 0 26
✅ fastify-stable-quickjs 128 0 26
✅ hono-stable-node 128 0 26
✅ hono-stable-quickjs 128 0 26
✅ nextjs-turbopack-canary-node 135 0 19
✅ nextjs-turbopack-canary-quickjs 135 0 19
✅ nextjs-turbopack-quickjs-snapshot 154 0 0
✅ nextjs-turbopack-stable-node 154 0 0
✅ nextjs-turbopack-stable-quickjs 154 0 0
✅ nextjs-webpack-stable-node 154 0 0
✅ nextjs-webpack-stable-quickjs 154 0 0
✅ nitro-stable-node 128 0 26
✅ nitro-stable-quickjs 128 0 26
✅ nuxt-stable-node 128 0 26
✅ nuxt-stable-quickjs 128 0 26
✅ sveltekit-stable-node 147 0 7
✅ sveltekit-stable-quickjs 147 0 7
✅ vite-stable-node 128 0 26
✅ vite-stable-quickjs 128 0 26

✅ 📦 Local Production

App Passed Failed Skipped
✅ astro-stable-node 128 0 26
✅ astro-stable-quickjs 128 0 26
✅ express-stable-node 128 0 26
✅ express-stable-quickjs 128 0 26
✅ fastify-stable-node 128 0 26
✅ fastify-stable-quickjs 128 0 26
✅ hono-stable-node 128 0 26
✅ hono-stable-quickjs 128 0 26
✅ nextjs-turbopack-canary-node 135 0 19
✅ nextjs-turbopack-canary-quickjs 135 0 19
✅ nextjs-turbopack-quickjs-snapshot 154 0 0
✅ nextjs-turbopack-stable-node 154 0 0
✅ nextjs-turbopack-stable-quickjs 154 0 0
✅ nextjs-webpack-canary-node 135 0 19
✅ nextjs-webpack-canary-quickjs 135 0 19
✅ nextjs-webpack-stable-node 154 0 0
✅ nextjs-webpack-stable-quickjs 154 0 0
✅ nitro-stable-node 128 0 26
✅ nitro-stable-quickjs 128 0 26
✅ nuxt-stable-node 128 0 26
✅ nuxt-stable-quickjs 128 0 26
✅ sveltekit-stable-node 147 0 7
✅ sveltekit-stable-quickjs 147 0 7
✅ vite-stable-node 128 0 26
✅ vite-stable-quickjs 128 0 26

✅ 🐘 Local Postgres

App Passed Failed Skipped
✅ astro-stable-node 128 0 26
✅ astro-stable-quickjs 128 0 26
✅ express-stable-node 128 0 26
✅ express-stable-quickjs 128 0 26
✅ fastify-stable-node 128 0 26
✅ fastify-stable-quickjs 128 0 26
✅ hono-stable-node 128 0 26
✅ hono-stable-quickjs 128 0 26
✅ nextjs-turbopack-canary-node 135 0 19
✅ nextjs-turbopack-canary-quickjs 135 0 19
✅ nextjs-turbopack-quickjs-snapshot 154 0 0
✅ nextjs-turbopack-stable-node 154 0 0
✅ nextjs-turbopack-stable-quickjs 154 0 0
✅ nextjs-webpack-canary-node 135 0 19
✅ nextjs-webpack-canary-quickjs 135 0 19
✅ nextjs-webpack-stable-node 154 0 0
✅ nextjs-webpack-stable-quickjs 154 0 0
✅ nitro-stable-node 128 0 26
✅ nitro-stable-quickjs 128 0 26
✅ nuxt-stable-node 128 0 26
✅ nuxt-stable-quickjs 128 0 26
✅ sveltekit-stable-node 147 0 7
✅ sveltekit-stable-quickjs 147 0 7
✅ vite-stable-node 128 0 26
✅ vite-stable-quickjs 128 0 26

✅ 🪟 Windows

App Passed Failed Skipped
✅ nextjs-turbopack-node 154 0 0
✅ nextjs-turbopack-quickjs 154 0 0

✅ 📋 Other

App Passed Failed Skipped
✅ e2e-local-dev-nest-stable-node 128 0 26
✅ e2e-local-dev-nest-stable-quickjs 128 0 26
✅ e2e-local-dev-tanstack-start-node 128 0 26
✅ e2e-local-dev-tanstack-start-quickjs 128 0 26
✅ e2e-local-postgres-nest-stable-node 128 0 26
✅ e2e-local-postgres-nest-stable-quickjs 128 0 26
✅ e2e-local-postgres-tanstack-start-node 128 0 26
✅ e2e-local-postgres-tanstack-start-quickjs 128 0 26
✅ e2e-local-prod-nest-stable-node 128 0 26
✅ e2e-local-prod-nest-stable-quickjs 128 0 26
✅ e2e-local-prod-tanstack-start-node 128 0 26
✅ e2e-local-prod-tanstack-start-quickjs 128 0 26
✅ e2e-vercel-prod-nest-node 126 0 28
✅ e2e-vercel-prod-nest-quickjs 126 0 28
✅ e2e-vercel-prod-tanstack-start-node 126 0 28
✅ e2e-vercel-prod-tanstack-start-quickjs 126 0 28

❌ vercel-multi-region

App Passed Failed Skipped
❌ nextjs-turbopack 3 24 0

📋 View full workflow run

@TooTallNate
TooTallNate marked this pull request as draft July 31, 2026 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

event-log-race-repro Run the event log race reproduction job

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants