rrule

A JavaScript/TypeScript library for computing iCalendar (RFC 5545) recurrence rules for calendar dates.

Library
npm
v2.8.1
3,743stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
50/100Fair
Development Activity0
Maintenance20
Community80
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
65/100Good
Architecture78
Code Quality82
Innovation55
Learning Curve45

rrule is a JavaScript/TypeScript port of Python’s python-dateutil recurrence engine, implementing the iCalendar RFC 5545 RRULE specification for computing recurring calendar dates. It exposes an RRule class for single recurrence rules, an RRuleSet class for combining multiple rules with explicit inclusion/exclusion dates, and an rrulestr parser that turns an iCalendar RRULE string directly into a usable rule object.

Beyond RFC compliance, the library adds natural-language conversion in both directions: toText()/fromText() translate a rule like “every 5 weeks on Monday, Friday until January 31, 2013” into RRule options and back, which is useful for building human-facing recurrence pickers without hand-rolling the parsing logic. It ships as pure TypeScript with a single runtime dependency (tslib), targeting both browser and Node environments, and is widely used as the recurrence engine behind calendar and scheduling UIs.

What You Get

  • An RRule class covering the full RFC 5545 option set (freq, interval, count, until, byweekday, bymonth, bymonthday, byyearday, byweekno, bysetpos, byhour/minute/second, byeaster)
  • An RRuleSet class for composing multiple RRULEs plus explicit RDATE/EXDATE inclusion and exclusion dates into one combined occurrence set
  • An rrulestr() parser that converts an iCalendar RRULE/RRuleSet string directly into a working rule object, and toString()/optionsToString() for the reverse
  • Natural-language conversion via toText()/fromText() and parseText(), translating rules to and from human-readable phrases like “every 5 weeks on Monday, Friday until January 31, 2013”
  • IANA timezone support via the Intl API through the tzid option, plus a datetime() helper for constructing dates in the library’s expected UTC-based format
  • Built-in occurrence caching so repeated all()/between() calls on the same rule don’t re-run the iteration algorithm

Common Use Cases

  • Powering recurrence pickers in calendar and scheduling UIs, where a user picks “every 2 weeks on Tue/Thu” and the app needs the resulting occurrence dates
  • Parsing and re-serializing iCalendar RRULE strings when importing/exporting .ics calendar data
  • Computing the next N occurrences of a recurring task, billing cycle, or reminder for background job scheduling
  • Converting recurrence rules to and from human-readable text for calendar UIs that display rules in plain language

Under The Hood

Architecture Execution flows from the public RRule class (src/rrule.ts), which parses and normalizes constructor options via parseOptions/initializeOptions (src/parseoptions.ts) into a ParsedOptions object, then delegates all query methods (all, between, before, after) to a shared _iter call into the standalone iter() function (src/iter/index.ts). That iterator walks calendar periods year-by-month using an Iterinfo helper (src/iterinfo/index.ts, with easter/month/year-specific submodules) to build day masks and time sets, filtering days against every by* constraint before emitting accepted dates through an IterResult/CallbackIterResult accumulator (src/iterresult.ts, src/callbackiterresult.ts). RRuleSet (src/rruleset.ts) layers on top by merging multiple RRule/EXRULE instances with explicit RDATE/EXDATE arrays and de-duplicating the combined output, while rrulestr/parsestring/optionsToString (src/rrulestr.ts, src/parsestring.ts, src/optionstostring.ts) handle iCalendar string round-tripping and a separate src/nlp/ module handles natural-language conversion — a clean layered separation between option parsing, core iteration, set composition, string serialization, and natural-language translation, with a Cache class (src/cache.ts) memoizing repeated queries per rule instance. The core abstraction to protect is the day/time-mask iteration in iter() and Iterinfo; changing it touches every query method and both serialization paths at once.

Tech Stack The library is authored entirely in TypeScript (98%+ of source bytes) with a single runtime dependency, tslib, keeping the published bundle dependency-free for consumers. The build pipeline compiles with tsc against tsconfig.build.json and bundles with Webpack 5 (webpack.config.js) plus terser-webpack-plugin for minification, publishing both an ES5 CommonJS build (dist/es5) and an ESM build (dist/esm) with generated .d.ts types. Linting runs through ESLint 8 with @typescript-eslint and eslint-plugin-jsdoc/eslint-plugin-import, formatting through Prettier 2, both wired into husky + lint-staged pre-commit hooks. There is no database or network layer — the library is pure computation over JS Date objects, with the Intl API used for IANA timezone resolution (tzid option) rather than a timezone library dependency.

Code Quality Testing uses Jest with ts-jest (jest.config.js) plus mockdate for deterministic date-based assertions, and the test/ directory mirrors the src/ module layout with a dedicated test file per module (rrule, rruleset, rrulestr, parseoptions, parsestring, cache, datetime, helpers, nlp) plus shared fixtures in test/lib. CI (.github/workflows/nodejs.yml) runs the full suite across three Node versions and, notably, across five different LANG/TZ combinations (including Pacific/Kiritimati and Africa/Nairobi) specifically to catch timezone- and locale-sensitive date bugs, then reports coverage to Codecov via nyc. Source files carry substantial inline JSDoc-style comments on public methods (parameter/return documentation on every RRule query method), and the constructor/option-parsing path validates inputs and throws explicit Errors (e.g. RRule.between/before/after reject invalid Date arguments) rather than silently returning bad data.

API Design The public surface is intentionally small and RFC-mirroring: a single RRule constructor takes an options object whose keys map directly to iCalendar RRULE parameters (freq, interval, byweekday, etc.), so anyone already familiar with the RFC or with Python’s dateutil.rrule (which this library is explicitly ported from) can use it with minimal ramp-up. Constants like RRule.MO/RRule.WEEKLY avoid magic numbers, and the datetime() helper sidesteps a documented JavaScript Date/timezone footgun that the README calls out at length. The main friction point for newcomers is exactly that UTC-handling caveat — the README devotes a long, explicit section to it because getting it wrong silently produces off-by-hours results — and the natural-language toText()/fromText() conversion is explicitly approximate rather than complete, which the library documents rather than hides.

Used by 10 apps in this directory

TypeScript
96%
Other

Cal.diy

Scheduling

48,218

The 100% MIT-licensed, community-driven scheduling platform — self-host your own booking infrastructure with no enterprise strings attached.

View details
95
Repo Health
86
Technical
65
Dependency
Built with
TypeScript96%
Updated yesterday
Ruby
60%
GPL 2.0

Discourse

Community

47,793

Open-source community platform with dynamic trust levels, real-time chat, and a powerful plugin architecture for self-hosted forums.

View details
89
Repo Health
89
Technical
67
Dependency
Built with
Ruby60%
JavaScript32%
Updated today
TypeScript
50%

Kener

Monitoring · Devops

5,148

Stunning, self-hosted status pages with real-time uptime monitoring, incident management, and multi-channel notifications in a single Docker container.

View details
88
Repo Health
76
Technical
67
Dependency
Built with
TypeScript50%
Svelte47%
Updated yesterday
TypeScript
99%
AGPL 3.0

Manage

Project Management · Collaboration

70

Self-hosted, open-source project management with tasks, calendars, docs, and real-time team collaboration.

View details
41
Repo Health
57
Technical
71
Dependency
Built with
TypeScript99%
Updated 1 months ago
TypeScript
92%
Other

n8n

Automation · No Code Platforms

203,555

Code when you need it, UI when you don't — the workflow automation platform built for technical teams who refuse to choose.

View details
95
Repo Health
87
Technical
66
Dependency
Built with
TypeScript92%
Updated today
TypeScript
98%
Other

Novu

Developer Tools

39,870

Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.

View details
93
Repo Health
80
Technical
64
Dependency
Built with
TypeScript98%
Updated yesterday
Python
54%
Other

PostHog

Analytics · Monitoring · Developer Tools

39,612

The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.

View details
92
Repo Health
80
Technical
65
Dependency
Built with
Python54%
TypeScript36%
Updated today
TypeScript
50%
Other

SigNoz

Monitoring · Analytics

32,028

Self-host your entire observability stack — logs, metrics, traces, and LLM monitoring — in one OpenTelemetry-native platform, without the Datadog bill.

View details
92
Repo Health
83
Technical
67
Dependency
Built with
TypeScript50%
Go39%
Updated today
TypeScript
92%
Apache 2.0

superset

AI Code Assistants · AI Development

13,825

Orchestrate an army of AI coding agents—Claude Code, Codex, Gemini CLI, and more—running simultaneously in isolated git worktrees from a single Electron desktop app.

View details
85
Repo Health
80
Technical
67
Dependency
Built with
TypeScript92%
Updated today

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search