Cron
Cron runs schedule-driven work. Cron fits recurring tasks such as digests, cleanup tasks, syncs, and reports that should start from a cron schedule instead of a request or queue message.
ViteHub discovers crons from server/crons/**.
Define a cron with createCron(options?)(handler) or defineCron(handler, options?), then trigger it manually with runCron().
Getting started
Install the package
pnpm add https://pkg.pr.new/nuxt-hub/agent/@vitehub/cron@main
Cron does not require an extra provider SDK. The provider behavior comes from Nitro runtime integration and generated scheduler output.
Configure a provider
Set the top-level cron key for the scheduler backend.
export default defineNuxtConfig({
modules: ['@vitehub/cron/nuxt'],
cron: {
provider: 'node',
},
})
export default defineNuxtConfig({
modules: ['@vitehub/cron/nuxt'],
cron: {
provider: 'cloudflare',
},
})
export default defineNuxtConfig({
modules: ['@vitehub/cron/nuxt'],
cron: {
provider: 'vercel',
},
})
Define a cron
Declare the schedule next to the cron. Start with a plain cron string. Move to schedule objects when you need Node-specific controls such as timezone or maxRuns.
import { createCron } from '@vitehub/cron'
export default createCron({
schedules: ['0 12 * * 1'],
})(async (event) => {
const headlines = Array.isArray(event.payload?.headlines) ? event.payload.headlines : []
return {
count: headlines.length,
}
})
Run the same cron manually
Manual execution uses the same handler. This is useful for preview routes, backfills, and admin actions.
import { readBody } from 'h3'
import { runCron } from '@vitehub/cron'
export default defineEventHandler(async (event) => {
const body = await readBody(event)
return await runCron('daily-digest', {
payload: body,
})
})
Public API
| Function | Use it for |
|---|
| createCron(options?)(handler) | Register one named cron under server/crons/** and declare its schedules. |
| defineCron(handler, options?) | Compatibility wrapper for createCron(options?)(handler). |
| runCron(name, { payload?, context? }) | Trigger that cron manually from a route, task, or webhook. |
| startScheduleRunner(options?) | Start the in-process Node scheduler for all registered crons. |
| getCronsForExpression(cron) | Return the cron names registered under a given cron expression. |
| runCronsForExpression(cron, { payload?, context? }) | Run every cron registered under a given cron expression. |
Type reference
CronEvent<TPayload>
The handler receives a CronEvent object with these fields:
| Field | Type | Description |
|---|---|---|
name | string | The cron name derived from the file path. |
payload | TPayload | Data passed via runCron() or the scheduled trigger. |
context | CronContext | Execution context from the runtime. |
The handler can return any value or nothing at all. ViteHub does not enforce a return type.
CronDefinitionOptions
The options object passed to createCron() or the second argument to defineCron() accepts:
| Option | Type | Description |
|---|---|---|
schedules | Array<string | CronSchedule> | One or more cron expressions. |
Each schedule can be a plain five-field cron string like '0 12 * * 1' or a CronSchedule object for Node-specific controls:
| Field | Type | Description |
|---|---|---|
cron | string | Five-field cron expression (required). |
timezone | string | IANA timezone. Node provider only. |
overlap | 'allow' | 'prevent' | Overlap behavior. Node provider only. |
startAt | string | ISO date to start scheduling. Node provider only. |
stopAt | string | ISO date to stop scheduling. Node provider only. |
maxRuns | number | Maximum number of runs. Node provider only. |
How configuration works
Cron configuration is intentionally small:
- Top-level
cronconfig innitro.config.tsselects the scheduler provider for the app. createCron(options?)(handler)configures one cron file. Put schedules here.defineCron(handler, options?)remains available as a compatibility wrapper.
runCron() is only for manual execution. It does not define schedules or provider behavior.
export default defineNitroConfig({
cron: {
provider: 'vercel',
},
})
export default createCron({
schedules: ['0 12 * * 1'],
})(async (event) => {
return {
count: Array.isArray(event.payload?.headlines) ? event.payload.headlines.length : 0,
}
})