PATTERN Cited by 1 source
Virtual handler via Nitro for bundlerless frameworks¶
Virtual handler via Nitro for bundlerless frameworks is the pattern used to integrate a cross-framework SDK with bare-HTTP frameworks (Express, Hono, Fastify, Koa) that don't ship with a build system. The pattern uses Nitro (UnJS) as a build-system shim: esbuild bundles the SDK handlers, Nitro mounts them as "virtual handlers" injected into the user's HTTP server at runtime.
Canonical verbatim¶
From Vercel's 2026-04-21 WDK post: "For frameworks without a bundler like Express or Hono, we use Nitro instead. Nitro is a server toolkit that provides file-based routing, a build system, and other quality-of-life features such as virtual handlers that can be mounted to a server at runtime. This brings the same workflow capabilities to bare HTTP servers."
And in the framework-integration-taxonomy section: "These frameworks don't ship with a build system, i.e. they don't have a bundler, and just expose a bare HTTP server. This is where Nitro comes in. For these frameworks, WDK uses esbuild to bundle workflows, then Nitro mounts them as virtual handlers. At runtime, Nitro wraps your HTTP server and injects the virtual handlers, exposing the workflow endpoints so they're reachable from your HTTP server."
Why bundlerless frameworks need the shim¶
File-based-routing frameworks (Next.js, SvelteKit, Nuxt) have a built-in integration seam: drop a file into a magic directory, the framework auto-discovers it as an HTTP endpoint. The SDK's build-time phase outputs handler files into the right directory and the runtime is done.
Bare-HTTP frameworks have no such seam:
- Express:
app.get("/path", handler)is imperative; the SDK can't inject routes without the user wiring them manually. - Hono: same imperative model on top of the Web Fetch API.
The SDK needs a mechanism to get its handlers into the
user's running HTTP server without requiring the user to
write app.post("/workflow/start", wdk.start).
How Nitro bridges the gap¶
Nitro provides:
- File-based routing — the SDK can output handlers to a Nitro-recognised directory just like it would with a file-based-routing framework.
- Build system — esbuild orchestration for bundling the handlers (WDK's step-mode + workflow-mode outputs).
- Virtual handlers — handlers that aren't files on disk but virtual in-memory routes Nitro mounts at runtime.
- Server wrapping — at runtime Nitro "wraps your HTTP server and injects the virtual handlers" — the user's Express/Hono app runs as normal but with additional routes injected by Nitro's wrapper.
The net effect: the user installs WDK + its Nitro-based
integration package, adds one config line, and the workflow
endpoints appear — no manual app.post(...) wiring.
When to use¶
- Integrating an SDK with bare-HTTP JS frameworks that have no built-in routing-as-file-system seam.
- When manual endpoint wiring would push framework-specific knowledge into user code.
- When you already use esbuild for the SDK's build-time bundle output and want to avoid adding a second bundler.
When NOT to use¶
- When the framework has file-based routing already (use its native seam directly — don't add Nitro overhead).
- When the SDK ships as a library only (no HTTP handlers to inject).
- When Nitro's dependency weight / runtime cost is unacceptable for the target deployment shape.
Canonical instance¶
Vercel Workflow DevKit (WDK)
uses this pattern for its Express +
Hono integrations. Both frameworks are
launch-supported (2026-04-21) via the Nitro shim; the user
adds a Nitro-based WDK plugin to their server config and
workflow endpoints appear under the usual
.well-known/workflow/v1 path.
Seen in¶
- sources/2026-04-21-vercel-inside-workflow-devkit-how-framework-integrations-work — canonical wiki instance. WDK integrates with Express + Hono via this pattern; Nitro is chosen because it provides file-based routing + esbuild + virtual handlers in one package.
Related¶
- systems/nitro-unjs — the substrate.
- systems/express, systems/hono — bare-HTTP frameworks using this integration.
- systems/esbuild — the bundler inside the shim.
- concepts/file-based-routing-vs-bare-http-framework-taxonomy — the taxonomy this pattern applies to.
- patterns/two-phase-framework-integration-pattern — the broader pattern this is a runtime-bridge variant of.
- systems/vercel-workflow — the 2026-04-21 canonical instance.