Netlify
Netlify's scheduled functions are native — each cron handler becomes its own function with a static
config.schedule export, registered the moment you deploy. No drain cron, no polling: Heximon's Netlify
support is strictly better here than the generic Nitro preset, which emits no scheduled functions at all.
Configure the strategy
import { defineHeximonConfig } from "@heximon/build";
import { NetlifyFunctionsStrategy } from "@heximon/netlify";
import { HttpPlugin } from "@heximon/http/compiler";
export default defineHeximonConfig({
platform: new NetlifyFunctionsStrategy(),
plugins: [new HttpPlugin()],
});
NetlifyFunctionsStrategy is a node-class strategy, platform name "netlify" — Netlify Functions 2.0 run an
AWS-Lambda-backed Node.js runtime. NetlifyEdgeStrategy is the opt-in edge-class alternative, running on Deno.
compatibilityDate >= 2024-05-07 in your
netlify.toml — without it Netlify falls back to the legacy v1 function format.What vp build emits
vp build writes a Netlify deploy tree at the project root .netlify/, so netlify deploy runs the
compiled app with no Nitro:
.netlify/functions-internal/
server/
index.mjs # the compiled bundle
server.mjs # export { default } from "./index.mjs" + the static `config` const
scheduled-0/
scheduled-0.mjs # one scheduled function per cron
Netlify statically analyzes a function file for its top-level config const, so the catch-all routing config
({ path: "/*", preferStatic: true, excludedPath: ["/.netlify/*"] }) lives in the explicit server.mjs wrapper
rather than being re-exported through the compiled bundle.
Netlify Functions deploy externalized — the
platform bundles node_modules itself — so the strategy keeps the standard Node SSR externalization; only
node:* builtins are forced external.
The Edge tier (NetlifyEdgeStrategy) writes .netlify/edge-functions/ instead — a self-contained bundle (Deno
doesn't load node_modules) routed by a manifest.json catch-all, with no config wrapper and no scheduled
functions.
Scheduled work (cron)
List SchedulePlugin and the plugin selects NetlifyScheduleDriver — a clockless driver the platform triggers
by invoking a scheduled function directly. Each discovered cron gets its own function with a static
config.schedule export as its registration:
import { scheduled as heximonScheduled } from "../server/index.mjs";
export const config = { schedule: "0 3 * * *" };
export default async () => {
await heximonScheduled({ cron: "0 3 * * *", scheduledTime: Date.now() });
return new Response(null, { status: 202 });
};
import type { ScheduledHandler } from "@heximon/schedule";
export class NightlyCleanup implements ScheduledHandler<"0 3 * * *", { name: "Nightly cleanup" }> {
public handle(scheduledAt: Date): void {
// …
}
}
Cron works only on the Functions target — Netlify Edge has no scheduled-function support at all, and a
scheduled handler compiled against NetlifyEdgeStrategy is rejected at build time with a clear diagnostic.
Queue transport (Netlify Async Workloads)
List QueuePlugin and bind NetlifyAsyncWorkloadsQueue (from @heximon/queue/netlify) as your Queue
provider. The strategy binds NetlifyAsyncWorkloadsQueueConsumer as the push consumer, and vp build emits a
consumer function:
import { asyncWorkloadFn } from "@netlify/async-workloads";
import { queueConsumer } from "../server/index.mjs";
export const asyncWorkloadConfig = { events: ["orders-placed"] };
export default asyncWorkloadFn(async (event) => {
await queueConsumer(event);
});
import { NetlifyAsyncWorkloadsQueue } from "@heximon/queue/netlify";
import type { QueueEventTypes } from "@heximon/queue";
export interface OrderEventMap extends QueueEventTypes {
"orders-placed": { orderId: string; total: number };
}
export class OrderQueue extends NetlifyAsyncWorkloadsQueue<OrderEventMap> {}
import { Module } from "@heximon/runtime";
import { OrderQueue } from "./orders/order-queue.js";
import { OrderPlacedHandler } from "./orders/order-placed.handler.js";
import { Queue } from "@heximon/queue";
export class AppModule extends Module({
providers: [{ provide: Queue, useClass: OrderQueue }],
queue: { handlers: [OrderPlacedHandler] },
}) {}
@netlify/async-workloads is not a declared peer dependency of @heximon/queue — its pre-release dependency
tree is too heavy to force into the toolchain — so a real Netlify-queue deploy adds it to the app's owndependencies. Netlify Async Workloads has no built-in delay feature, so there's no publishWithDelay: reach
for a durable timer or a polling queue transport for delayed delivery instead.
Mixed-runtime split
NetlifyFunctionsStrategy owns both a node tier (Functions) and an edge tier (Edge Functions), so it declares
supportsRuntimeSplit = true.
Mark a controller runtime: "edge" and vp build partitions the DI graph,
bundling the edge partition into a self-contained dist/edge.js and emitting both a
.netlify/functions-internal/server/ node catch-all and a prefix-routed Netlify Edge Function in
.netlify/edge-functions/. Netlify Edge runs before Functions, so the edge function intercepts its own
prefixes and the node function serves everything else.
Because Netlify Edge runs on Deno (broad native node: compatibility), the edge tier here needs no unenv
polyfill layer — that complexity is specific to Vercel's V8-isolate Edge tier.
Dev
Netlify has no local micro-VM emulator either. The strategy's dev host returns the browser channel unchanged — development runs as a standard Node HTTP server on both the Functions and Edge targets, with the full build experience preserved.
Ship it
netlify deploy # add --prod for production
A manual prebuilt deploy needs a committed netlify.toml pinning
[functions] directory = ".netlify/functions-internal" and a no-op [build] command.
Both host strategies
implement the @heximon/deploy capability, so heximon deploy runs the same command for you —
plus a netlify api getCurrentUser preflight and a first-deploy site-linkage gate (halting with the one-time
netlify sites:create / netlify link command on a fresh site).
Netlify's cron is a native scheduled function,
not a public route, so there's no CRON_SECRET gate the way there is on Vercel.
See also
- Queue — the
Queueport and channel handler discovery. - Schedule —
ScheduledHandlerand the cron discovery mechanism. - Mixed-runtime split — the shared
runtime: "edge"controller partitioning. heximon deploy— the CLI's Netlify-specific preflight,--create, and--provisionflags.