cronlet
v0.2.0
Published
The simplest way to add scheduled tasks to your Node.js app
Maintainers
Readme
cronlet

The simplest way to add scheduled tasks to a Node.js application. A typed, fluent API with file-based job discovery, stable file-based IDs, built-in retries, and a local dev dashboard. Just write functions and say when they should run.
// jobs/weekly-digest.ts
import { schedule, weekly } from "cronlet"
export default schedule(weekly("fri", "09:00"), async (ctx) => {
await sendWeeklyDigest()
})Quick Start
npm install cronlet cronlet-cliCreate a job file:
// jobs/hello.ts
import { schedule, every } from "cronlet"
export default schedule(every("1m"), async (ctx) => {
console.log(`Hello from ${ctx.jobName}!`)
})Run the dev server:
npx cronlet devSchedule API
Intervals
schedule(every("30s"), handler) // every 30 seconds
schedule(every("15m"), handler) // every 15 minutes
schedule(every("2h"), handler) // every 2 hours
schedule(every("1d"), handler) // every day
schedule(every("1w"), handler) // every weekDaily
schedule(daily("09:00"), handler) // daily at 9:00 AM
schedule(daily("09:00", "17:00"), handler) // daily at 9 AM and 5 PMWeekly
schedule(weekly("fri", "09:00"), handler) // every Friday at 9 AM
schedule(weekly(["mon", "wed", "fri"], "09:00"), handler) // MWF at 9 AMMonthly
schedule(monthly(1, "09:00"), handler) // 1st of month at 9 AM
schedule(monthly(15, "12:00"), handler) // 15th of month at noon
schedule(monthly("last-fri", "17:00"), handler) // last Friday of monthmonthly("last-...") uses cron L syntax (for example 5L). Cronlet supports this locally, but some hosted cron platforms do not.
Raw Cron
schedule(cron("0 9 * * 1-5"), handler) // 9 AM on weekdaysConfiguration
schedule(
daily("09:00"),
{
name: "daily-report",
retry: {
attempts: 3,
backoff: "exponential",
initialDelay: "30s"
},
timeout: "5m",
onSuccess: async (ctx) => {
console.log("Report sent!")
},
onFailure: async (error, ctx) => {
await alertOps(error)
}
},
async (ctx) => {
await generateAndSendReport()
}
)timeout and retry.initialDelay support ms, s, m, h, d units.
Job IDs
For jobs discovered from files:
config.namebecomes the job ID if set.- Otherwise the ID is the file path relative to your jobs directory (for example
billing/sync-stripe).
Job Context
Every handler receives a context object:
interface JobContext {
jobId: string // unique job identifier
jobName: string // human-readable name
runId: string // unique run identifier
scheduledAt: Date // when this run was scheduled
startedAt: Date // when the handler started
attempt: number // current attempt (1-based)
signal: AbortSignal // for cancellation
}CLI
Install cronlet-cli for the dev server and tooling:
cronlet dev # Start dev server with hot reload
cronlet list # List all discovered jobs
cronlet run <job-id> # Manually trigger a job
cronlet validate # Validate job configurationsLicense
MIT
