Recurr

PHP library for RRULE recurrence rules, transforming them into concrete recurring calendar dates.

Library
Composer
vv6.0.0
1,601stars
MIT License

Repository Health

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

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
71/100Good
Architecture75
Code Quality78
Innovation62
Learning Curve68

Recurr is a PHP library for working with iCalendar RRULE recurrence rules (RFC 5545), the same rule format used by calendar systems like Google Calendar and Outlook to express “every weekday,” “every other Tuesday,” or “the last Friday of the month.” It lets developers build a Rule object either from an RRULE string or programmatically via chained setters, then transform that rule into a concrete collection of Recurrence DateTime instances within a given range.

Originally developed as the recurrence engine behind a calendar application and inspired by JavaScript’s rrule.js, Recurr handles the full complexity of the RRULE spec — frequencies, intervals, by-day/by-month/by-set-position rules, exceptions, and inclusions — so applications don’t have to reimplement RFC 5545’s date math themselves. With 1,599 GitHub stars and 46 contributors, it is a long-standing, widely used solution for recurring-event scheduling in PHP.

What You Get

  • A Rule class that parses RRULE strings or builds rules via chained setters (setFreq, setByDay, setUntil, setInterval, etc.)
  • An ArrayTransformer that expands a Rule into a RecurrenceCollection of concrete Recurrence objects, each with getStart()/getEnd() DateTime accessors
  • Support for the full RFC 5545 RRULE surface: frequencies, intervals, by-day/by-month/by-month-day/by-set-position constraints, COUNT and UNTIL bounds
  • Date exclusions and inclusions (DateExclusion/DateInclusion) for handling one-off cancelled or added occurrences within a recurring series
  • Timezone-aware date handling throughout rule construction and transformation
  • Translation support for human-readable rule descriptions in multiple languages (translations/ directory)

Common Use Cases

  • Implementing recurring calendar events (e.g. “every Monday and Wednesday until year-end”) in a scheduling or booking application
  • Parsing RRULE strings imported from iCalendar (.ics) files or synced from Google Calendar/Outlook and expanding them into concrete occurrence dates
  • Generating the next N occurrences of a recurring task, reminder, or billing cycle
  • Handling exceptions to a recurring series, such as a single cancelled or rescheduled meeting instance

Under The Hood

Architecture - The core model is a Rule class (src/Recurr/Rule.php) representing one RRULE plus its start/end dates and timezone, paired with DateExclusion/DateInclusion for one-off overrides. Transformation is handled by classes under src/Recurr/Transformer/, most notably ArrayTransformer, which walks the rule’s frequency/interval/by-* constraints (implemented via DateUtil, DaySet, and DateInfo helper classes) to materialize a RecurrenceCollection of Recurrence value objects, each exposing getStart()/getEnd().

Tech Stack - Modern PHP (requires PHP 8.4+) with a single production dependency on doctrine/collections for the recurrence collection type. Development tooling is thorough: PHPUnit for tests, PHPStan for static analysis, PHP-CS-Fixer for style, and Rector for automated upgrades, all wired into GitHub Actions CI.

Code Quality - The tests/ directory contains 29 PHP test files exercising rule parsing, transformation, and edge cases across the RRULE spec, and the project maintains an UPGRADE-6.0.md documenting breaking changes between major versions — a sign of deliberate semantic versioning discipline. PHPStan and PHP-CS-Fixer configs enforce static-analysis and style consistency, and the codebase cleanly separates rule representation from transformation logic.

API Design - The Rule class supports both a compact RRULE-string constructor and a fluent, chainable builder ((new Rule)->setFreq('DAILY')->setByDay([...])), covering both “I have an RRULE string from iCal” and “I want to build a rule programmatically” entry points with equally low friction. The transform step is a single method call ($transformer->transform($rule)) that returns typed collection/value objects rather than raw arrays, keeping the resulting API ergonomic for further date manipulation.

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