Skip to content

Getting Started

TaskTimer runs periodic tasks on a single timer. You set one base interval, then add tasks that run on tick multiples of it — each with its own interval, run limit, delay, or date window.

Terminal window
npm i tasktimer

TaskTimer is ESM-only and ships with TypeScript types.

import { TaskTimer } from 'tasktimer';

Create a timer with a base interval (milliseconds), add a task, and start it. The task’s callback receives the Task instance.

import { TaskTimer } from 'tasktimer';
const timer = new TaskTimer(1000); // tick every 1000 ms
timer.add(task => {
console.log(`Run #${task.currentRuns}`);
});
timer.start();

The base interval is the tick resolution shared by every task. A task’s tickInterval is counted in ticks, not milliseconds — see Ticks & Intervals.

Add many tasks at once, each on its own schedule. Here one runs every 5 ticks (5s) ten times, another waits a tick then runs every 10 ticks (10s) twice.

const timer = new TaskTimer(1000);
timer.add([
{
id: 'sync-users',
tickInterval: 5, // every 5 ticks → 5s
totalRuns: 10, // stop after 10 runs
callback(task) {
console.log(`${task.id}: run ${task.currentRuns}`);
}
},
{
id: 'send-digest',
tickDelay: 1, // wait 1 tick before the first run
tickInterval: 10, // every 10 ticks → 10s
totalRuns: 2,
callback: sendDigest
}
]);
timer.start();

A TaskTimer is an event emitter. Event is a named export — import it alongside TaskTimer. Each listener receives a typed event object ({ name, timer, task, error }); the timer is always event.timer, and the related task is always event.task.

import { TaskTimer, Event } from 'tasktimer';
timer.on(Event.TICK, event => {
const { tickCount, time } = event.timer;
console.log(`tick ${tickCount} · elapsed ${time.elapsed} ms`);
});
timer.on(Event.TASK, event => {
console.log(`${event.task.id}: run ${event.task.currentRuns}`);
});

See Events for the full list of lifecycle events.

By default a task waits a full interval before its first run. Set lead: true to also run it once on the leading edge — the moment the timer starts. Attach your own typed payload with data, available as task.data in the callback and in event listeners.

timer.add({
id: 'poll',
lead: true, // run once at start, then on the schedule
tickInterval: 30, // and every 30 ticks after
data: { url: '/health' },
callback(task) {
console.log(`polling ${task.data.url} (run ${task.currentRuns})`);
}
});