Getting started

Quick start

Schedule a job, check on it, and shut it down cleanly. This takes about five minutes.

On this page

Add a job

Create a Baker, then give it a job. A job needs a unique name, a cron schedule and a callback.

scheduler.ts
import Baker from "cronbake";

const baker = Baker.create();

baker.add({
  name: "heartbeat",
  cron: "*/5 * * * * *", // every 5 seconds
  callback: () => {
    console.log("Still here at", new Date().toLocaleTimeString());
  },
});

Adding a job doesn’t start it. That lets you register everything first and start it all together.

Start it

bakeAll() starts every job. To start a single job, use bake() with its name.

baker.bakeAll();

Run the file and you should see a line every five seconds, on the seconds that divide by five.

bun run scheduler.ts

On Node 24 you can run the same file with node scheduler.ts. Older versions need a TypeScript runner such as tsx.

Check on it

Everything you might want to know about a job is available by name.

setTimeout(() => {
  console.log(baker.getStatus("heartbeat")); // "running"
  console.log(baker.nextExecution("heartbeat")); // the Date of the next tick
  console.log(baker.remaining("heartbeat")); // milliseconds until then
  console.log(baker.getMetrics("heartbeat")); // totals, failures, average duration
}, 12_000);

Handle failures

A callback that throws won’t crash your app or stop the job. By default, Cronbake logs a warning and carries on at the next tick. Pass onError to report failures your own way, either per job or for the whole baker.

const baker = Baker.create({
  onError: (error, jobName) => {
    console.error(`${jobName} failed: ${error.message}`);
  },
});

Shut down

A running job’s timer keeps the process alive, so a script with a running job won’t exit by itself. Stop your jobs when the process is told to quit.

process.once("SIGINT", () => {
  baker.stopAll();
  process.exit(0);
});

The whole file

scheduler.ts
import Baker from "cronbake";

const baker = Baker.create({
  onError: (error, jobName) => {
    console.error(`${jobName} failed: ${error.message}`);
  },
});

baker.add({
  name: "heartbeat",
  cron: "*/5 * * * * *",
  callback: () => {
    console.log("Still here at", new Date().toLocaleTimeString());
  },
});

baker.bakeAll();

process.once("SIGINT", () => {
  baker.stopAll();
  process.exit(0);
});

From here, Cron expressions explains the schedule format, and Job lifecycle covers what each state and control method does.

esc

Try overlap, restore or timezone.