📅 ical-rs

iCalendar parser, validator, editor and builder library for Rust
Table of contents
Features
- Both iCalendar flavours: read and write vCalendar 1.0 and iCalendar 2.0 through a single, version-agnostic model, with no dialect to pick up front.
- Nested structure, preserved: a calendar is a tree of events, to-dos, journals, free/busy blocks, time zones and alarms, parsed and round-tripped whole.
- Byte-faithful editing: change one field and every other byte comes back unchanged, line endings and fold points included.
- Forgiving parser: accept any real calendar, and a recovering mode that keeps going through the lines a strict reading throws the whole file away for.
- Strict building and validation: construct calendars checked against the standard, with an escape hatch when you need to step outside it.
- Recurrence and time zones: expand a rule, or the whole set of occurrences an event denotes, and resolve a time zone from the calendar's own rules.
- Small and portable: no_std compatible, with an allocation-only core that pulls in no dependencies.
- Optional content decoding: quoted-printable text, inline base64 binary and foreign character sets, each behind its own feature.
- Three-way merge: reconcile two divergent edits of a calendar against their common base, matched by UID and RECURRENCE-ID, with every action and every conflict reported and the untouched bytes kept.
- Optional JSON: read and write a calendar as jCal, or convert it to and from the JSCalendar data model a JMAP server exchanges.
[!TIP] ical-rs uses cargo features to gate optional support. The default feature set is declared in Cargo.toml or on docs.rs.
RFC coverage
| Spec | What is covered |
|---|---|
| 1.0 | vCalendar 1.0: the original versit format, including its quoted-printable and charset conventions |
| 5545 | iCalendar 2.0: the current standard, with its full component tree, property set, value types and parameters, its recurrence rules and its time zones |
| 5546 | iTIP: whose the properties of a scheduled component are, which the merge enforces |
| 6638 | CalDAV scheduling: the parameters a server reads and writes on an attendee |
| 7265 | jCal: the JSON representation of a calendar |
| 7529 | Non-Gregorian recurrence: SKIP is expanded for the Gregorian scale; another scale is carried, not expanded |
| 7953 | Availability: the availability window and the periods inside it |
| 7986 | Calendar extensions: the newer calendar-level properties |
| 8984 | JSCalendar: the JSON data model a JMAP calendar server exchanges, converted both ways |
| 9073 | Event publishing extensions: participants, locations, resources and structured data |
| 9074 | Alarm extensions: acknowledgement, proximity and the alarm relations |
| 9253 | Relationships: typed links, reference identifiers and concepts |
Usage
The whole API is documented on docs.rs, from parsing and byte-faithful editing to the strict builder, validation, recurrence expansion, the three-way merge and the optional jCal and JSCalendar conversions.
Examples
Complete runnable programs live in ./examples; the tests also demonstrate real usage.
AI disclosure
This project is developed with AI assistance. This section documents how, so users and downstream packagers can make informed decisions.
- Tools: Claude Code (Anthropic), invoked locally with a persistent project-scoped memory and a small set of repo-specific rules.
- Used for: Refactors, mechanical multi-file edits, boilerplate (feature gates, error enums, derive macros, trait impls), test scaffolding, doc polish, exploratory design conversations.
- Not used for: Engineering, critical code, git manipulation (commit, merge, rebase…), real-world tests.
- Verification: Every AI-assisted change is read, compiled, tested, and formatted before commit. Behavioural correctness is verified against the relevant RFC or upstream spec, not assumed from the model output. Tests are never adjusted to fit AI-generated code; the code is adjusted to fit correct behaviour.
- Limitations: AI models occasionally produce code that compiles and passes tests but is subtly wrong. The verification workflow catches most of this; it does not catch all of it. Bug reports are welcome and taken seriously.
- Last reviewed: 08/08/2026
License
This project is licensed under either of:
at your option.
Social
- Chat on Matrix
- News on Mastodon or RSS
- Mail at pimalaya.org@posteo.net
Contributing
Contributions are welcome: start with CONTRIBUTING.md, which opens with the Pimalaya-wide guides to read first.
Sponsoring
Special thanks to the NLnet foundation and the European Commission that have been financially supporting the project for years:
- 2022 → 2023: NGI Assure
- 2023 → 2024: NGI Zero Entrust
- 2024 → 2026: NGI Zero Core
- 2027 in preparation…
If you appreciate the project, feel free to donate using one of the following providers:
