Skip to content

Introduction

rrule-ts is an RFC 5545 recurrence rule (RRULE) library for TypeScript. It provides:

  • parse(): convert an RRULE string (with optional DTSTART) to a typed RRuleOptions object
  • validate(): enforce RFC 5545 cross-field rules, returning all errors with stable rule IDs
  • stringify(): convert RRuleOptions back to a canonical RRULE string, with round-trip guarantee
  • expand() / iterate(): materialize or lazily stream the occurrence sequence as Temporal values
  • RRuleSet: combine multiple RRULEs, RDATEs, EXRULEs, and EXDATEs into one sorted sequence
  • toText() / fromText(): human-readable rendering and parsing, EN and DE locale packs included

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.

Terminal window
npm i rrule-ts

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:

Terminal window
npm i temporal-polyfill

No setup is required. globalThis.Temporal is available natively and rrule-ts picks it up automatically.

  • Quickstart: parse a DTSTART+RRULE string, expand to occurrences, and convert to a human-readable sentence
  • Parsing guide: all input formats, the Result type, and the full RRuleOptions shape
  • Validation guide: all stable rule IDs and how to use them in error maps
  • toText and fromText guide: human-readable rendering and locale packs