Skip to content

web: construct worlds explicitly instead of via static-injection stub#2804

Merged
karthikscale3 merged 2 commits into
mainfrom
karthik/web-fix-local-world-static-injection
Jul 7, 2026
Merged

web: construct worlds explicitly instead of via static-injection stub#2804
karthikscale3 merged 2 commits into
mainfrom
karthik/web-fix-local-world-static-injection

Conversation

@karthikscale3

Copy link
Copy Markdown
Contributor

What changed

Fixes workflow web crashing for the local and postgres backends on latest main.

Since #2752, createWorld() from @workflow/core/runtime is a static-injection stub that throws unless a framework build plugin aliases @workflow/core/runtime/world-target to the selected world package at the host app's build time. The CLI was migrated to construct worlds explicitly (packages/cli/src/lib/inspect/setup.ts), but @workflow/web's getWorldFromEnv still called the stub. Since the web UI selects its backend at runtime via env, no build plugin ever aliases its bundle, so every server action failed with:

Workflow target world was not statically injected. Configure a Workflow builder/framework plugin so @workflow/core/runtime/world-target is aliased to the selected world package.

The Vercel backend was unaffected because that path constructs createVercelWorld directly.

Fix

Mirror the CLI's approach in getWorldFromEnv:

  • local / @workflow/world-local → import createWorld from @workflow/world-local directly (added as a dependency of @workflow/web)
  • any other backend id (e.g. @workflow/world-postgres, community worlds) → resolve the package from the inspected project's directory (WORKFLOW_OBSERVABILITY_CWD) and call its createWorld(), preserving the pre-Statically inject workflow world target #2752 dynamic-selection behavior with a clear error when the package isn't installed

Repro / validation

  • Before: workflow web against a local-world project → every RPC returns the static-injection error.
  • After: rebuilt @workflow/web and verified end-to-end against a local-world project (runs/steps/events/hooks list + detail + lazy hook-token fetch all working), and against the Vercel backend (unaffected path, still works).
  • pnpm exec vitest run app/server/workflow-server-actions.server.test.ts — 3/3 pass
  • tsc --noEmit on @workflow/web — 15 errors, identical to the pre-existing main baseline (zero new)

🤖 Generated with Claude Code

Since #2752, createWorld() from @workflow/core/runtime is a stub that
throws unless a framework build plugin aliases it to a world package.
The CLI was migrated to construct worlds directly, but @workflow/web
still called the stub, so 'workflow web' crashed with 'Workflow target
world was not statically injected' for local and postgres backends
(the vercel path was unaffected since it constructs the world directly).

Mirror the CLI: import the local world statically and resolve any other
configured world package from the inspected project's directory.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@karthikscale3 karthikscale3 requested review from a team and ijjk as code owners July 7, 2026 20:25
@changeset-bot

changeset-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a42603f

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

This PR includes changesets to release 16 packages
Name Type
@workflow/web Patch
@workflow/cli Patch
@workflow/nitro Patch
workflow Patch
@workflow/world-testing Patch
@workflow/nuxt Patch
@workflow/core Patch
@workflow/web-shared Patch
@workflow/builders Patch
@workflow/next Patch
@workflow/vitest Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite 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

@vercel

vercel Bot commented Jul 7, 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, Comment Jul 7, 2026 9:19pm
example-nextjs-workflow-webpack Ready Ready Preview, Comment Jul 7, 2026 9:19pm
example-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-astro-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-express-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-fastify-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-hono-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-nitro-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-nuxt-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-sveltekit-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-tanstack-start-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workbench-vite-workflow Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workflow-docs Ready Ready Preview, Comment, Open in v0 Jul 7, 2026 9:19pm
workflow-swc-playground Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workflow-tarballs Ready Ready Preview, Comment Jul 7, 2026 9:19pm
workflow-web Ready Ready Preview, Comment Jul 7, 2026 9:19pm

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 1442 0 230 1672
✅ 💻 Local Development 1453 0 219 1672
✅ 📦 Local Production 1605 0 219 1824
✅ 🐘 Local Postgres 1605 0 219 1824
✅ 🪟 Windows 152 0 0 152
✅ 📋 Other 887 0 177 1064
Total 7144 0 1064 8208

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 125 0 27
✅ example 125 0 27
✅ express 125 0 27
✅ fastify 125 0 27
✅ hono 125 0 27
✅ nextjs-turbopack 149 0 3
✅ nextjs-webpack 149 0 3
✅ nitro 125 0 27
✅ nuxt 125 0 27
✅ sveltekit 144 0 8
✅ vite 125 0 27
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 127 0 25
✅ express-stable 127 0 25
✅ fastify-stable 127 0 25
✅ hono-stable 127 0 25
✅ nextjs-turbopack-canary 133 0 19
✅ nextjs-webpack-canary 133 0 19
✅ nextjs-webpack-stable 152 0 0
✅ nitro-stable 127 0 25
✅ nuxt-stable 127 0 25
✅ sveltekit-stable 146 0 6
✅ vite-stable 127 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 127 0 25
✅ express-stable 127 0 25
✅ fastify-stable 127 0 25
✅ hono-stable 127 0 25
✅ nextjs-turbopack-canary 133 0 19
✅ nextjs-turbopack-stable 152 0 0
✅ nextjs-webpack-canary 133 0 19
✅ nextjs-webpack-stable 152 0 0
✅ nitro-stable 127 0 25
✅ nuxt-stable 127 0 25
✅ sveltekit-stable 146 0 6
✅ vite-stable 127 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 127 0 25
✅ express-stable 127 0 25
✅ fastify-stable 127 0 25
✅ hono-stable 127 0 25
✅ nextjs-turbopack-canary 133 0 19
✅ nextjs-turbopack-stable 152 0 0
✅ nextjs-webpack-canary 133 0 19
✅ nextjs-webpack-stable 152 0 0
✅ nitro-stable 127 0 25
✅ nuxt-stable 127 0 25
✅ sveltekit-stable 146 0 6
✅ vite-stable 127 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 152 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 127 0 25
✅ e2e-local-dev-tanstack-start- 127 0 25
✅ e2e-local-postgres-nest-stable 127 0 25
✅ e2e-local-postgres-tanstack-start- 127 0 25
✅ e2e-local-prod-nest-stable 127 0 25
✅ e2e-local-prod-tanstack-start- 127 0 25
✅ e2e-vercel-prod-tanstack-start 125 0 27

📋 View full workflow run


Some E2E test jobs failed:

  • Vercel Prod: success
  • Local Dev: failure
  • Local Prod: success
  • Local Postgres: success
  • Windows: success

Check the workflow run for details.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

📈 Comparing against baseline from main branch. Green 🟢 = faster, Red 🔺 = slower.

workflow with no steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 0.047s (+4.9%) 1.006s (~) 0.959s 10 1.00x
💻 Local Nitro 0.048s (+3.2%) 1.006s (~) 0.958s 10 1.02x
💻 Local Next.js (Turbopack) 0.056s (+6.0% 🔺) 1.006s (~) 0.950s 10 1.20x
🐘 Postgres Nitro 0.063s (-3.7%) 1.012s (~) 0.949s 10 1.35x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 0.219s (-2.8%) 1.458s (-28.8% 🟢) 1.239s 10 1.00x
▲ Vercel Nitro 0.487s (+159.0% 🔺) 2.038s (~) 1.551s 10 2.23x
▲ Vercel Next.js (Turbopack) 0.635s (+161.2% 🔺) 2.291s (-3.7%) 1.656s 10 2.90x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 1.089s (~) 2.006s (~) 0.916s 10 1.00x
💻 Local Nitro 1.091s (+1.2%) 2.007s (~) 0.915s 10 1.00x
💻 Local Next.js (Turbopack) 1.093s (~) 2.007s (~) 0.914s 10 1.00x
🐘 Postgres Nitro 1.095s (~) 2.010s (~) 0.915s 10 1.01x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 1.442s (+5.9% 🔺) 3.166s (+4.9%) 1.724s 10 1.00x
▲ Vercel Express 1.474s (+4.0%) 2.878s (+1.9%) 1.403s 10 1.02x
▲ Vercel Next.js (Turbopack) 2.324s (-0.9%) 4.149s (+15.5% 🔺) 1.825s 10 1.61x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 10.467s (~) 11.016s (~) 0.549s 3 1.00x
💻 Local Nitro 10.494s (~) 11.024s (~) 0.530s 3 1.00x
💻 Local Express 10.514s (~) 11.022s (~) 0.508s 3 1.00x
💻 Local Next.js (Turbopack) 10.527s (~) 11.025s (~) 0.497s 3 1.01x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 11.727s (~) 14.211s (+11.9% 🔺) 2.484s 3 1.00x
▲ Vercel Express 12.164s (+4.2%) 13.805s (-1.0%) 1.642s 3 1.04x
▲ Vercel Next.js (Turbopack) 13.328s (+3.1%) 14.774s (+4.2%) 1.446s 3 1.14x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 13.611s (-0.6%) 14.026s (~) 0.415s 5 1.00x
🐘 Postgres Nitro 13.614s (-0.7%) 14.019s (~) 0.405s 5 1.00x
💻 Local Nitro 13.635s (~) 14.029s (~) 0.394s 5 1.00x
💻 Local Next.js (Turbopack) 13.937s (+1.6%) 14.030s (~) 0.093s 5 1.02x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 16.424s (+1.5%) 18.599s (+6.7% 🔺) 2.175s 4 1.00x
▲ Vercel Express 16.637s (~) 18.412s (-2.8%) 1.775s 4 1.01x
▲ Vercel Next.js (Turbopack) 18.769s (+4.5%) 20.394s (+3.2%) 1.625s 3 1.14x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 12.110s (-1.8%) 13.018s (~) 0.908s 7 1.00x
💻 Local Express 12.259s (~) 13.025s (~) 0.766s 7 1.01x
💻 Local Nitro 12.334s (+0.9%) 13.026s (~) 0.693s 7 1.02x
💻 Local Next.js (Turbopack) 12.987s (+6.1% 🔺) 13.459s (+3.3%) 0.472s 7 1.07x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 18.067s (+4.5%) 19.946s (+4.0%) 1.880s 5 1.00x
▲ Vercel Nitro 19.085s (+11.7% 🔺) 20.914s (+11.4% 🔺) 1.828s 5 1.06x
▲ Vercel Next.js (Turbopack) 23.005s (+16.7% 🔺) 24.524s (+13.1% 🔺) 1.519s 4 1.27x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.202s (+1.3%) 2.008s (~) 0.806s 15 1.00x
💻 Local Express 1.414s (-2.1%) 2.007s (~) 0.593s 15 1.18x
💻 Local Nitro 1.425s (+1.3%) 2.007s (~) 0.582s 15 1.19x
💻 Local Next.js (Turbopack) 1.458s (+3.6%) 2.007s (~) 0.549s 15 1.21x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.058s (-10.0% 🟢) 4.046s (+12.3% 🔺) 1.987s 8 1.00x
▲ Vercel Express 2.129s (-6.3% 🟢) 3.832s (-1.8%) 1.704s 8 1.03x
▲ Vercel Next.js (Turbopack) 3.677s (+25.2% 🔺) 5.040s (+8.6% 🔺) 1.363s 6 1.79x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.309s (-6.4% 🟢) 2.222s (-10.1% 🟢) 0.913s 14 1.00x
💻 Local Nitro 2.389s (+3.0%) 3.009s (~) 0.620s 10 1.82x
💻 Local Next.js (Turbopack) 2.473s (-0.6%) 3.010s (-3.2%) 0.537s 10 1.89x
💻 Local Express 2.491s (-6.2% 🟢) 3.009s (-3.2%) 0.517s 10 1.90x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.366s (-6.4% 🟢) 4.064s (+14.2% 🔺) 1.698s 8 1.00x
▲ Vercel Express 2.432s (-6.7% 🟢) 4.074s (-1.1%) 1.642s 8 1.03x
▲ Vercel Next.js (Turbopack) 4.373s (+31.4% 🔺) 5.955s (+21.3% 🔺) 1.582s 6 1.85x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.542s (-5.3% 🟢) 4.136s (~) 2.594s 8 1.00x
💻 Local Next.js (Turbopack) 2.942s (-37.4% 🟢) 4.442s (-19.4% 🟢) 1.500s 7 1.91x
💻 Local Nitro 4.604s (+7.2% 🔺) 5.515s (+13.2% 🔺) 0.910s 6 2.99x
💻 Local Express 4.804s (+8.8% 🔺) 5.345s (+3.2%) 0.541s 6 3.12x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.779s (-1.8%) 4.829s (+7.1% 🔺) 2.050s 7 1.00x
▲ Vercel Express 2.978s (+2.0%) 4.815s (+9.6% 🔺) 1.837s 7 1.07x
▲ Vercel Next.js (Turbopack) 4.742s (+20.0% 🔺) 6.242s (+8.1% 🔺) 1.500s 5 1.71x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.179s (-1.5%) 2.008s (~) 0.829s 15 1.00x
💻 Local Nitro 1.437s (+1.6%) 2.007s (~) 0.570s 15 1.22x
💻 Local Express 1.452s (~) 2.007s (~) 0.555s 15 1.23x
💻 Local Next.js (Turbopack) 1.522s (+1.4%) 2.008s (~) 0.486s 15 1.29x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.055s (+6.3% 🔺) 3.862s (+5.7% 🔺) 1.807s 8 1.00x
▲ Vercel Nitro 2.153s (+13.4% 🔺) 3.930s (+17.5% 🔺) 1.778s 8 1.05x
▲ Vercel Next.js (Turbopack) 3.867s (+30.1% 🔺) 5.350s (+13.7% 🔺) 1.483s 6 1.88x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.294s (-1.9%) 2.316s (+15.4% 🔺) 1.022s 13 1.00x
💻 Local Nitro 2.601s (+6.5% 🔺) 3.010s (~) 0.409s 10 2.01x
💻 Local Express 2.608s (+4.8%) 3.110s (+3.4%) 0.502s 10 2.02x
💻 Local Next.js (Turbopack) 2.737s (-2.6%) 3.009s (-10.0% 🟢) 0.272s 10 2.12x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.427s (-21.7% 🟢) 4.164s (-9.0% 🟢) 1.737s 8 1.00x
▲ Vercel Nitro 2.715s (+23.6% 🔺) 4.460s (+27.2% 🔺) 1.746s 7 1.12x
▲ Vercel Next.js (Turbopack) 3.706s (+17.5% 🔺) 5.007s (+10.3% 🔺) 1.300s 6 1.53x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.576s (-3.6%) 4.011s (-6.7% 🟢) 2.435s 8 1.00x
💻 Local Express 5.357s (+50.2% 🔺) 6.214s (+24.0% 🔺) 0.857s 5 3.40x
💻 Local Nitro 5.624s (+1.8%) 6.015s (~) 0.392s 5 3.57x
💻 Local Next.js (Turbopack) 5.759s (+6.5% 🔺) 6.418s (+6.8% 🔺) 0.659s 5 3.65x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.839s (+11.5% 🔺) 4.916s (+29.2% 🔺) 2.076s 7 1.00x
▲ Vercel Express 3.410s (+28.1% 🔺) 5.027s (+13.3% 🔺) 1.617s 6 1.20x
▲ Vercel Next.js (Turbopack) 4.339s (-3.8%) 6.148s (~) 1.809s 5 1.53x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.600s (~) 1.041s (+1.7%) 0.442s 58 1.00x
💻 Local Nitro 0.610s (+4.4%) 1.005s (~) 0.395s 60 1.02x
💻 Local Express 0.624s (+3.0%) 1.022s (+1.7%) 0.399s 59 1.04x
💻 Local Next.js (Turbopack) 0.728s (+21.5% 🔺) 1.023s (+1.8%) 0.295s 59 1.21x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.688s (+3.2%) 4.312s (+7.5% 🔺) 1.624s 15 1.00x
▲ Vercel Express 2.717s (+9.2% 🔺) 4.414s (+11.2% 🔺) 1.697s 14 1.01x
▲ Vercel Next.js (Turbopack) 3.979s (-1.8%) 5.460s (-3.5%) 1.481s 11 1.48x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.209s (-13.2% 🟢) 2.008s (-1.1%) 0.798s 45 1.00x
💻 Local Express 1.512s (+1.2%) 2.006s (~) 0.495s 45 1.25x
💻 Local Nitro 1.535s (+6.1% 🔺) 2.006s (~) 0.471s 45 1.27x
💻 Local Next.js (Turbopack) 1.709s (+8.6% 🔺) 2.007s (~) 0.297s 45 1.41x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 6.321s (+8.2% 🔺) 8.024s (+8.7% 🔺) 1.703s 12 1.00x
▲ Vercel Express 6.554s (+12.6% 🔺) 8.335s (+11.4% 🔺) 1.781s 11 1.04x
▲ Vercel Next.js (Turbopack) 8.643s (+4.8%) 10.042s (+4.7%) 1.399s 10 1.37x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 2.672s (-6.1% 🟢) 3.192s (-0.8%) 0.520s 38 1.00x
💻 Local Express 3.321s (~) 4.009s (~) 0.688s 30 1.24x
💻 Local Nitro 3.368s (+6.0% 🔺) 4.043s (+2.5%) 0.675s 30 1.26x
💻 Local Next.js (Turbopack) 3.766s (+9.8% 🔺) 4.144s (+3.4%) 0.378s 30 1.41x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 12.319s (+5.4% 🔺) 14.027s (+1.4%) 1.707s 9 1.00x
▲ Vercel Nitro 13.548s (+17.9% 🔺) 15.518s (+20.0% 🔺) 1.971s 8 1.10x
▲ Vercel Next.js (Turbopack) 17.303s (+0.9%) 18.740s (~) 1.438s 7 1.40x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.210s (-4.8%) 1.006s (~) 0.795s 60 1.00x
💻 Local Nitro 0.523s (+2.2%) 1.005s (~) 0.482s 60 2.49x
💻 Local Express 0.606s (+17.3% 🔺) 1.039s (+3.4%) 0.434s 58 2.88x
💻 Local Next.js (Turbopack) 0.728s (+13.3% 🔺) 1.022s (~) 0.294s 59 3.46x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.148s (+2.0%) 2.715s (+3.3%) 1.567s 23 1.00x
▲ Vercel Nitro 1.215s (+10.8% 🔺) 2.857s (+19.0% 🔺) 1.643s 21 1.06x
▲ Vercel Next.js (Turbopack) 2.173s (+11.0% 🔺) 3.410s (+1.5%) 1.237s 18 1.89x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.329s (-6.0% 🟢) 1.006s (~) 0.677s 90 1.00x
💻 Local Nitro 2.521s (~) 3.043s (+1.1%) 0.522s 30 7.66x
💻 Local Express 2.555s (+1.0%) 3.044s (~) 0.489s 30 7.76x
💻 Local Next.js (Turbopack) 2.752s (~) 3.077s (-2.2%) 0.325s 30 8.36x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.371s (-3.8%) 2.931s (-3.9%) 1.560s 31 1.00x
▲ Vercel Nitro 1.402s (+6.0% 🔺) 2.882s (+15.8% 🔺) 1.481s 32 1.02x
▲ Vercel Next.js (Turbopack) 2.875s (+11.0% 🔺) 4.427s (+9.0% 🔺) 1.552s 21 2.10x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.553s (-3.6%) 1.160s (+7.7% 🔺) 0.607s 104 1.00x
💻 Local Express 5.138s (-14.1% 🟢) 8.157s (-3.9%) 3.019s 15 9.29x
💻 Local Nitro 5.141s (-12.2% 🟢) 8.811s (+1.4%) 3.671s 14 9.30x
💻 Local Next.js (Turbopack) 6.644s (+3.3%) 9.643s (+4.3%) 2.999s 13 12.02x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.832s (+14.2% 🔺) 3.682s (+1.2%) 1.849s 33 1.00x
▲ Vercel Nitro 1.861s (+11.7% 🔺) 3.866s (+9.2% 🔺) 2.006s 32 1.02x
▲ Vercel Next.js (Turbopack) 3.980s (-5.3% 🟢) 5.511s (-3.8%) 1.531s 22 2.17x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Stream Benchmarks (includes TTFB metrics)
workflow with stream

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.145s (-1.5%) 2.000s (~) 0.001s (-16.7% 🟢) 2.011s (~) 0.866s 10 1.00x
💻 Local Next.js (Turbopack) 1.163s (+2.1%) 1.963s (~) 0.013s (+30.1% 🔺) 2.022s (~) 0.859s 10 1.02x
💻 Local Express 1.165s (~) 2.004s (~) 0.012s (+5.3% 🔺) 2.019s (~) 0.854s 10 1.02x
💻 Local Nitro 1.166s (+0.9%) 2.005s (~) 0.013s (+21.9% 🔺) 2.021s (~) 0.855s 10 1.02x
🐘 Postgres Express ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.063s (+8.2% 🔺) 3.682s (+24.3% 🔺) 5.347s (+190.7% 🔺) 9.559s (+83.1% 🔺) 7.496s 10 1.00x
▲ Vercel Express 2.078s (+9.9% 🔺) 3.546s (+9.5% 🔺) 5.423s (+231.1% 🔺) 9.486s (+77.4% 🔺) 7.407s 10 1.01x
▲ Vercel Next.js (Turbopack) 3.838s (+20.4% 🔺) 4.391s (+25.5% 🔺) 5.361s (+268.2% 🔺) 10.975s (+70.5% 🔺) 7.137s 10 1.86x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.537s (-5.7% 🟢) 2.004s (~) 0.006s (+6.4% 🔺) 2.027s (~) 0.490s 30 1.00x
💻 Local Nitro 1.579s (~) 2.009s (-1.5%) 0.013s (-2.2%) 2.026s (-1.6%) 0.446s 30 1.03x
💻 Local Express 1.581s (~) 2.039s (+1.4%) 0.012s (+3.9%) 2.059s (+1.7%) 0.478s 30 1.03x
💻 Local Next.js (Turbopack) 1.684s (+5.2% 🔺) 1.967s (~) 0.014s (+14.1% 🔺) 2.030s (~) 0.346s 30 1.10x
🐘 Postgres Express ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.558s (-2.3%) 7.654s (+16.1% 🔺) 0.194s (-16.6% 🟢) 8.385s (+13.1% 🔺) 2.827s 8 1.00x
▲ Vercel Express 5.710s (+5.2% 🔺) 7.460s (+5.8% 🔺) 0.096s (-57.0% 🟢) 8.025s (+3.2%) 2.316s 8 1.03x
▲ Vercel Next.js (Turbopack) 9.376s (-1.4%) 10.558s (~) 1.070s (+389.3% 🔺) 12.346s (+6.9% 🔺) 2.970s 5 1.69x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.765s (-9.7% 🟢) 1.044s (-7.0% 🟢) 0.000s (+174.1% 🔺) 1.060s (-7.2% 🟢) 0.295s 58 1.00x
💻 Local Express 1.334s (-1.5%) 1.949s (+1.6%) 0.000s (+80.6% 🔺) 1.952s (+1.6%) 0.618s 31 1.74x
💻 Local Nitro 1.334s (-1.1%) 1.982s (+1.7%) 0.000s (+33.3% 🔺) 1.985s (+1.7%) 0.651s 31 1.74x
💻 Local Next.js (Turbopack) 1.490s (+6.4% 🔺) 1.975s (~) 0.001s (-5.3% 🟢) 2.018s (~) 0.528s 30 1.95x
🐘 Postgres Express ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.983s (-27.4% 🟢) 5.018s (-4.5%) 0.000s (+Infinity% 🔺) 5.529s (-3.4%) 2.546s 11 1.00x
▲ Vercel Express 3.326s (-36.4% 🟢) 4.680s (-29.3% 🟢) 0.000s (-100.0% 🟢) 5.361s (-24.9% 🟢) 2.035s 12 1.11x
▲ Vercel Next.js (Turbopack) 4.895s (+8.8% 🔺) 5.805s (+7.4% 🔺) 0.000s (+Infinity% 🔺) 6.619s (+7.2% 🔺) 1.724s 10 1.64x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

fan-out fan-in 10 streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.884s (+5.8% 🔺) 2.606s (+7.8% 🔺) 0.000s (NaN%) 2.619s (+7.6% 🔺) 0.735s 23 1.00x
💻 Local Express 3.280s (-1.2%) 3.901s (~) 0.001s (+500.0% 🔺) 3.906s (~) 0.625s 16 1.74x
💻 Local Nitro 3.288s (+1.4%) 3.901s (~) 0.001s (-20.0% 🟢) 3.904s (~) 0.616s 16 1.75x
💻 Local Next.js (Turbopack) 3.901s (+12.8% 🔺) 4.349s (+9.0% 🔺) 0.001s (-18.1% 🟢) 4.394s (+9.0% 🔺) 0.493s 14 2.07x
🐘 Postgres Express ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 4.575s (+5.2% 🔺) 6.251s (+19.0% 🔺) 0.000s (NaN%) 6.807s (+20.2% 🔺) 2.233s 9 1.00x
▲ Vercel Express 4.731s (+5.4% 🔺) 6.054s (+6.3% 🔺) 0.000s (NaN%) 6.638s (+7.7% 🔺) 1.907s 10 1.03x
▲ Vercel Next.js (Turbopack) 7.108s (-3.4%) 7.730s (-1.0%) 0.000s (NaN%) 8.799s (-1.6%) 1.691s 7 1.55x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Express 11/21
🐘 Postgres Nitro 21/21
▲ Vercel Nitro 13/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 💻 Local 15/21
Next.js (Turbopack) 💻 Local 19/21
Nitro 🐘 Postgres 19/21
Column Definitions
  • Workflow Time: Runtime reported by workflow (completedAt - createdAt) - primary metric
  • TTFB: Time to First Byte - time from workflow start until first stream byte received (stream benchmarks only)
  • Slurp: Time from first byte to complete stream consumption (stream benchmarks only)
  • Wall Time: Total testbench time (trigger workflow + poll for result)
  • Overhead: Testbench overhead (Wall Time - Workflow Time)
  • Samples: Number of benchmark iterations run
  • vs Fastest: How much slower compared to the fastest configuration for this benchmark

Worlds:

  • 💻 Local: In-memory filesystem world (local development)
  • 🐘 Postgres: PostgreSQL database world (local development)
  • ▲ Vercel: Vercel production/preview deployment
  • 🌐 Turso: Community world (local development)
  • 🌐 MongoDB: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Jazz: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Redis + BullMQ: Community world (local development)
  • 🌐 Cloudflare: Community world (local development)
  • 🌐 MySQL: Community world (local development)
  • 🌐 Azure: Community world (local development)
  • 🌐 NATS JetStream: Community world (local development)
  • 🌐 Upstash: Community world (local development)
  • 🌐 Platformatic: Community world (local development)

📋 View full workflow run

@VaguelySerious VaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

workflow-web preview doesn't load runs on this PR, but did on #2752

@VaguelySerious

Copy link
Copy Markdown
Member

^ actually seems to have broken some other commit, ignore

@VaguelySerious VaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It'd be nice if we could unify the logic here between CLI/web since it'll invariable create drift, but otherwise LGTM

@TooTallNate TooTallNate left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed and validated the fix live. Approving.

Bug confirmed reproducible: I ran the web dev server on this branch against a local-world project (WORKFLOW_TARGET_WORLD=local, WORKFLOW_OBSERVABILITY_CWD pointed at a project dir), then swapped in main's version of workflow-server-actions.server.ts — main fails every RPC with exactly the static-injection error from the description, this branch returns successful responses. Also exercised the dynamic-resolution error path (WORKFLOW_TARGET_WORLD=@acme/world-missing) and got the clear "Make sure the package is installed in the inspected project" message.

Correctness checks:

  • The env dance holds together: ensureLocalWorldDataDirEnv() still runs before construction and before the WORKFLOW_*-derived cache key is computed, and @workflow/world-local's createWorld() reads WORKFLOW_LOCAL_DATA_DIR — so the arg-less createLocalWorld() call picks up the inspected project's data dir, matching the CLI.
  • The dynamic path is a faithful mirror of the CLI's createPostgresCliWorld() (createRequire(join(cwd, 'package.json')).resolve + import(pathToFileURL(...))), generalized to any backend id — which correctly restores pre-#2752 community-world support for the web UI. @workflow/world-postgres is "type": "module", so the named createWorld export resolves without interop concerns.
  • No remaining call sites of the core stub in packages/web; @workflow/world-local properly added to dependencies with lockfile update; changeset present and accurate (patch).
  • 85/85 web tests pass locally.

CI: 101 pass; the 2 fails are the nextjs-webpack canary HMR fuzz timeout (hmrFuzzAddedStep manifest wait) and its downstream required-check aggregator — a known flaky lane, and this PR touches only web server actions, nothing in the Next integration or manifest rebuild path.

Two non-blocking thoughts:

  1. For community worlds shipped as CJS, import()'s named-export detection depends on cjs-module-lexer; a mod.createWorld ?? mod.default?.createWorld fallback would make the dynamic path a bit more forgiving. The CLI has the same shape today, so fine to defer or do both together.
  2. The CLI's world setup now lags this implementation — it hard-throws on backends other than vercel/postgres/local, while this generalizes to any package exporting createWorld(). A follow-up unifying both on a shared helper (this version) would fix that asymmetry and remove the duplication.

karthikscale3 added a commit that referenced this pull request Jul 7, 2026
Review feedback on #2804: import() of a require-resolved CJS entry relies
on cjs-module-lexer to surface named exports; fall back to
mod.default.createWorld when detection fails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review feedback: import() of a require-resolved CJS entry relies on
cjs-module-lexer to surface named exports; fall back to
mod.default.createWorld when detection fails. Mirrored in the CLI in #2806.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@karthikscale3

Copy link
Copy Markdown
Contributor Author

Addressed the review feedback:

@karthikscale3 karthikscale3 merged commit cdfac39 into main Jul 7, 2026
177 of 184 checks passed
@karthikscale3 karthikscale3 deleted the karthik/web-fix-local-world-static-injection branch July 7, 2026 22:47
karthikscale3 added a commit that referenced this pull request Jul 7, 2026
* cli: restore dynamic world loading for community backends

Since #2752 moved world selection to static injection, setupCliWorld only
constructed the vercel, local, and postgres worlds explicitly and threw
'Unsupported workflow backend' for anything else — breaking community
worlds (e.g. @workflow-worlds/turso) that previously loaded through the
dynamic createWorld() in @workflow/core/runtime.

Generalize the postgres-only dynamic path: any backend other than
vercel/local is now resolved from the user's project directory and loaded
via its createWorld() export, matching @workflow/web's world construction
(#2804), with clear errors when the package is missing or does not export
createWorld().

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* cli: fall back to default.createWorld for CJS world packages

Review feedback on #2804: import() of a require-resolved CJS entry relies
on cjs-module-lexer to surface named exports; fall back to
mod.default.createWorld when detection fails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Update .changeset/cli-generic-world-backends.md

Signed-off-by: Peter Wielander <mittgfu@gmail.com>

---------

Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

No backport to stable for cdfac39 (AI decision).

This commit works around the static-injection createWorld() stub introduced on main by #2752. On stable, createWorld() in packages/core/src/runtime/world.ts is still the older dynamic-selection implementation that resolves worlds at runtime, so the bug being fixed does not exist there and applying this change would be unnecessary (and could regress the working behavior).

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

cdfac39e07e2d15c95f7ab9ff8d244b8677931bd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants