Vercel
Deploying to Vercel gets you Functions by default — a real Node.js runtime, cron, queues, and durable workflows — with Edge Functions available as an opt-in tier for latency-sensitive routes. One line picks the strategy:
import { defineHeximonConfig } from "@heximon/build";
import { VercelFunctionsStrategy } from "@heximon/vercel";
import { HttpPlugin } from "@heximon/http/compiler";
export default defineHeximonConfig({
platform: new VercelFunctionsStrategy(),
plugins: [new HttpPlugin()],
});
VercelFunctionsStrategy is a node-class strategy, platform name "vercel". VercelEdgeStrategy is the
edge-class alternative for a V8 isolate tier — swap it in for a controller-level split (edge reads next to a
node tier that owns the database) rather than the whole platform; see
Mixed-runtime split.
Build and deploy
vp build writes a complete Vercel Build Output API v3 tree at the project root — no Nitro in between:
.vercel/output/
config.json # { version: 3, routes, crons[] }
functions/__server.func/
index.js # self-contained bundle (deps bundled, no node_modules)
.vc-config.json # nodejs22.x + handler + launcherType
static/
By default the function is self-contained (bundleDependencies, on by default): every JS dependency is
bundled into index.js, so there's no node_modules symlink to resolve — a vercel deploy --prebuilt .func
can't follow one anyway. Opt out with new VercelFunctionsStrategy({ bundleDependencies: false }) to keep the
standard externalized Node SSR shape instead.
Ship it with either command:
vercel deploy --prebuilt # add --prod for production
Both host strategies implement the @heximon/deploy capability, so heximon deploy runs the
same command for you — plus a vercel whoami preflight, a first-deploy linkage gate (halting with the
one-time vercel link command on a fresh project), and a fail-closed CRON_SECRET gate that halts the deploy
before upload if your app declares any cron route but no CRON_SECRET is set.
Cron
List SchedulePlugin and the plugin selects VercelScheduleDriver — a clockless driver the platform triggers
over HTTP. Each discovered cron gets its own config.json entry, guarded by Authorization: Bearer <CRON_SECRET>:
{ "crons": [{ "path": "/_vercel/cron/0", "schedule": "0 3 * * *" }] }
import type { ScheduledHandler } from "@heximon/schedule";
export class NightlyCleanup implements ScheduledHandler<"0 3 * * *", { name: "Nightly cleanup" }> {
public handle(scheduledAt: Date): void {
// …
}
}
Cron works on both Functions and Edge — the route is plain HTTP either way.
Queues
List QueuePlugin and bind VercelQueue (from @heximon/queue/vercel) as your Queue provider. The queue
plugin selects VercelQueueConsumer as the push-drain consumer and emits it as a separate, isolated function
(a Build Output API .func can't import across a .func boundary, so the consumer ships its own copy of the
server bundle):
import { Module } from "@heximon/runtime";
import { Queue } from "@heximon/queue";
import { VercelQueue } from "@heximon/queue/vercel";
export class AppModule extends Module({
providers: [{ provide: Queue, useValue: new VercelQueue() }],
queue: { handlers: [OrdersHandler] },
}) {}
Vercel Queues (V3) topic names allow only [A-Za-z0-9_-] — no dots — and vp build fails with a clear message
if an emitted channel name violates that. VercelEdgeStrategy.supportedFeatures.queue stays false — edge
isolates have no durable queue support. Vercel Queue delivers back to the same deployment only; for fan-out to
other services see Cross-service events.
Durable workflows and saga timers
Vercel Functions freeze between invocations — there's no long-lived process to run a poller on — so a
workflow's step.sleep and a saga's
TimeoutHandler deadline need a wakeup that doesn't depend on one.
The default is a once-per-minute drain cron vp build folds into config.json; each tick, the generated
entry (guarded by CRON_SECRET) re-enters every run whose sleep has elapsed — sub-minute precision on Pro+,
but Hobby caps cron at once a day and rejects a * * * * * schedule at deploy time.
The opt-in alternative swaps the drain cron for a delayed Vercel Queue message that wakes each timer at (roughly) its exact deadline instead — sub-second precision, works on Hobby, no minute-cron gate:
export default defineHeximonConfig({
platform: new VercelFunctionsStrategy({ timerWakeup: "queue" }),
plugins: [
new HttpPlugin(),
new QueuePlugin(),
new SchedulePlugin(),
new SagaPlugin(),
new WorkflowPlugin(),
// …
],
});
The switch governs both consumers at once and the app binds a DeferredWakeupQueue satisfier per environment
(MemoryDeferredWakeupQueue in dev/CI, VercelDeferredWakeupQueue in production). For the replay engine, the
durable_timers mechanics, and the generated drain entry, see
Workflows.
Database
Vercel Functions freeze between invocations and don't hold an in-memory connection pool, so your database needs
to be edge-capable: a persistent, edge-reachable store like Turso (@libsql/client, bundled to its pure-JS
web build) or Neon's serverless Postgres driver. A native TCP driver that can't bundle into a self-contained
.func, or an in-memory store that won't survive the freeze, doesn't work here.
Verification
Per the live-deploy verification ledger: the durable Vercel Queue round-trip (POST →
platform push → Turso write → GET), the timerWakeup: "queue" wakeup for both workflow step.sleep and saga
timeouts, and the drain-cron leg re-entering a suspended workflow run are each verified on a real vercel deploy.
Everything else on this page — cron triggers, the Build Output API shape, the mixed-runtime routing — is build-tested and expected to work but not separately live-verified.
See also
- Workflows —
Workflow,step.do,step.sleep, and the replay engine. - Sagas —
TimeoutHandlerdeadlines andDurableTimer. - Cross-service events — fan an integration event out past one deployment.
- Mixed-runtime split — the
runtime: "edge"controller partitioning in depth. heximon deploy— the CLI's Vercel-specific preflight,--create, and--provisionflags.
Cloudflare
CloudflareWorkersStrategy, CloudflarePlugin, wrangler.json as a build artifact, dist/worker.js, Durable Object migrations, the Miniflare vp dev host.
Netlify
NetlifyFunctionsStrategy, NetlifyEdgeStrategy, .netlify/ deploy tree, scheduled functions, Netlify Async Workloads queue, mixed-runtime split.