Introduction
rrule-ts is an RFC 5545 recurrence rule (RRULE) library for TypeScript. It provides:
parse(): convert an RRULE string (with optionalDTSTART) to a typedRRuleOptionsobjectvalidate(): enforce RFC 5545 cross-field rules, returning all errors with stable rule IDsstringify(): convertRRuleOptionsback to a canonical RRULE string, with round-trip guaranteeexpand()/iterate(): materialize or lazily stream the occurrence sequence as Temporal valuesRRuleSet: combine multiple RRULEs, RDATEs, EXRULEs, and EXDATEs into one sorted sequencetoText()/fromText(): human-readable rendering and parsing, EN and DE locale packs included
Temporal-native design
Section titled “Temporal-native design”rrule-ts is built on the TC39 Temporal proposal, the modern datetime API now shipping natively in Node.js 26 and modern browsers.
Existing RRULE libraries rely on Date, moment.js, or custom date math. This causes known
failures at DST transitions (spring-forward gaps, fall-back ambiguities), and requires workarounds
for timezone-aware expansion. Temporal resolves these issues by design: every date/time operation
has explicit semantics.
rrule-ts reads globalThis.Temporal when available. When it is not (Node 22 and below), it uses
any Temporal implementation injected via setTemporal(). No polyfill is bundled, so library size
stays near zero.
Installation
Section titled “Installation”npm i rrule-tspnpm add rrule-tsyarn add rrule-tsPolyfill setup (Node versions below 26)
Section titled “Polyfill setup (Node versions below 26)”On Node.js 22 and below, inject a Temporal polyfill before calling any expansion function:
import { setTemporal } from 'rrule-ts'import { Temporal } from 'temporal-polyfill'
setTemporal(Temporal)Install the polyfill separately:
npm i temporal-polyfillpnpm add temporal-polyfillyarn add temporal-polyfillOn Node 26 and above
Section titled “On Node 26 and above”No setup is required. globalThis.Temporal is available natively and rrule-ts picks it up
automatically.
What comes next
Section titled “What comes next”- Quickstart: parse a DTSTART+RRULE string, expand to occurrences, and convert to a human-readable sentence
- Parsing guide: all input formats, the
Resulttype, and the fullRRuleOptionsshape - Validation guide: all stable rule IDs and how to use them in error maps
- toText and fromText guide: human-readable rendering and locale packs