freeze-clock
v1.0.0
Published
Freeze Date and drive setTimeout/setInterval in tests — tiny, zero-dependency fake clock.
Maintainers
Readme
freeze-clock
Freeze Date and drive setTimeout / setInterval yourself — a tiny,
zero-dependency fake clock for tests.
No Sinon. No Jest. Just install, tick, uninstall.
import { install, uninstall } from "freeze-clock";
const clock = install({ now: "2024-01-01T00:00:00.000Z" });
setTimeout(() => console.log("done", Date.now()), 1000);
clock.tick(1000); // → "done" 1704067201000
uninstall();Install
npm install freeze-clockUsage
Basic
import { install } from "freeze-clock";
const clock = install({ now: 0 });
assert.equal(Date.now(), 0);
let fired = false;
setTimeout(() => {
fired = true;
}, 500);
clock.tick(499);
assert.equal(fired, false);
clock.tick(1);
assert.equal(fired, true);
assert.equal(Date.now(), 500);
clock.uninstall();With node:test / any runner
import { afterEach, test } from "node:test";
import { install, uninstall } from "freeze-clock";
afterEach(() => uninstall());
test("retries after a backoff", () => {
const clock = install({ now: Date.parse("2024-06-01") });
// ... schedule work that uses setTimeout / Date ...
clock.tick(5_000);
});API
install(options?) → Clock
Patches Date, setTimeout, clearTimeout, setInterval, clearInterval,
and (by default) performance.now.
| Option | Default | Description |
| --- | --- | --- |
| now | real now | Initial fake time (number, ISO string, or Date) |
| toFakePerformance | true | Also patch performance.now |
| loopLimit | 10000 | Max timer firings per tick / runAll (infinite-loop guard) |
Throws if a clock is already installed.
uninstall() → boolean
Restores the real globals. Returns whether a clock was active.
getClock() → Clock | null
The currently installed clock, if any.
Clock methods
| Method | Description |
| --- | --- |
| now | Current fake epoch ms (getter) |
| tick(ms) | Advance ms, firing due timers in order |
| next() | Fire the next timer only; returns ms advanced (or undefined) |
| runAll() | Fire every pending timer (including ones scheduled during the run) |
| runToLast() | Advance to the last timer that existed when called |
| setSystemTime(time) | Jump the clock without firing timers |
| countTimers() | Pending timer count |
| clearAll() | Cancel every pending timer |
| uninstall() | Restore globals |
How it behaves
- Timers fire in due-time order; ties break by schedule order.
- Timeouts scheduled during a
tickfire in the same tick if still due. setIntervalkeeps a fixed cadence from its previous due time.Date.parse/Date.UTCstay real; only “current time” is faked.performance.now()starts at0on install and trackstick.
License
MIT
