Skip to content

RFC 5545 recurrence rules. Correct by construction.

Parse, validate, stringify, and expand RRULE strings using the TC39 Temporal API. Differentially proven against both python-dateutil and rrule.js. Temporal-native, zero runtime dependencies.

Temporal-native

Built on the TC39 Temporal proposal. Uses globalThis.Temporal on Node 26+ and modern browsers. Falls back to any Temporal polyfill via setTemporal(). No date math hacks.

Zero runtime dependencies

The library has no bundled dependencies. Temporal is accessed via globalThis.Temporal or an injected polyfill. Your bundle only pays for what you import.

TypeScript-first

Every function has precise return types. parse() returns Result<RRuleOptions, string>. validate() returns Result<RRuleOptions, ValidationError[]>. No silent failures.

Differential conformance suite

Every expansion result is compared against python-dateutil 2.9.0 as the ground-truth oracle, and rrule.js as a known-divergence reference. Behavior is provably correct, not just tested in isolation.


rrule-tsrrulerrule-temporal
Temporal-nativeYesNoPartial
Zero runtime dependenciesYesNoNo
TypeScript-firstYesTypes via @typesYes
Differential conformance suiteYesNoNo
Strict RFC 5545 validationYesPartialPartial
Subpath tree-shakingYesNoNo

Terminal window
npm install rrule-ts

On Node.js versions below 26, inject a Temporal polyfill before using date-expansion features:

import { setTemporal } from 'rrule-ts'
import { Temporal } from 'temporal-polyfill'
setTemporal(Temporal)

On Node.js 26 and above, globalThis.Temporal is used automatically.


import { parse, validate, stringify } from 'rrule-ts'
const result = parse('RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10')
if (!result.ok) {
console.error(result.error)
process.exit(1)
}
const validation = validate(result.value)
if (!validation.ok) {
for (const e of validation.error) {
console.error(`${e.ruleId}: ${e.message}`)
}
process.exit(1)
}
console.log(stringify(validation.value))
// RRULE:FREQ=WEEKLY;COUNT=10;BYDAY=MO,WE,FR

Introduction

Understand the design, install the library, and set up the Temporal polyfill. Read the introduction

Quickstart

Go from a RRULE string to validated, expanded occurrences in minutes. Read the quickstart

GitHub

Source code, issues, and the differential conformance corpus. View on GitHub