Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ical Laravel Package

eluceo/ical

eluceo/ical is a PHP library that lets you create RFC 5545-compliant .ics calendar files through a clean domain abstraction, with a separate presentation layer handling output. Install via Composer.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. eluceo/ical is a pure, framework-agnostic PHP library built around a clean Domain / Presentation split: Domain\Entity\{Calendar, Event, TimeZone} plus value objects (Date, DateTime, SingleDay, MultiDay, Duration, Location, Geo, EmailAddress) describe what the calendar is; Presentation\Factory\CalendarFactory renders how it serializes as RFC 5545 output. This is effectively a hexagonal core in miniature and plays well with a Laravel codebase that already favours thin controllers, service classes, and testable domain objects. The package has zero runtime framework coupling — no service provider, no facade, no config — so it slots in as a library, not an opinionated module. That is a TPM advantage: low blast radius, easy to isolate behind an adapter, trivial to replace later.

Integration feasibility. Composer-installable with a single require. The canonical usage is four lines (build event → build calendar → factory → cast to string), which means a Laravel integration is genuinely a wrapper, not a project: a CalendarService that maps your internal models (e.g., Appointment, Shift, Subscription) into Eluceo domain objects, plus a controller returning text/calendar with Content-Disposition: attachment. No queue, no migration, no database touch. This is days of work, not sprints.

Technical risk. The dominant risk is the PHP support window, which is unusually aggressive. The changelog shows a pattern of removing support in the same release that adds support: 2.15.0 dropped PHP 7.4–8.2 to move to 8.3–8.4; 2.16.0 dropped 8.3 to support 8.4–8.5. A typical Laravel LTS estate on PHP 8.2/8.3 will therefore be pinned to an older minor (<2.15 / <2.16) and will not receive fixes — acceptable for a serializer, but it must be a conscious decision, not a composer update surprise. Secondary risks: the package writes ICS only (no parsing/validation), so inbound calendar ingestion is out of scope; and calendar-client quirks (Outlook, Google, Apple) are a real-world compatibility surface the library cannot fully own. Note the Dependents: 0 figure appears to be a metadata artifact — the README tracks monthly Packagist downloads — and should not be used to infer adoption or abandonment.

Key questions.

  1. What PHP minor is our target platform on, now and at next major upgrade? This alone determines whether we run current or pinned.
  2. Do we need read/parse as well as write? If yes, this package is half the solution.
  3. Are recurrence rules (RRULE, BYSETPOS, multiples) in scope, or is this one-off event export?
  4. Which consumers must render our .ics — Outlook/Exchange, Google, Apple, or all three? Their tolerances differ on timezone and all-day handling.
  5. Do we need the ATTENDEE/ORGANIZER/METHOD:REQUEST invite flow, or just a published feed?
  6. What is our exit cost if the single maintainer steps away? (Low — MIT, small surface, adapter boundary.)

Integration Approach

Stack fit. Works with any Laravel version that satisfies the Composer PHP constraint — no Laravel-specific pinning. The clean seam is a dedicated app/Calendar/ namespace containing a mapper (your model → Eluceo domain) and a renderer (domain → string/response). Bind it as a singleton service; expose a download() and a feed() method. Because it is a library rather than a package with a publishable config, there is nothing to vendor:publish and no upgrade ceremony beyond composer update.

Migration path. Two realistic starting points:

  • From v0.x of this same package: this is a full rewrite, not an upgrade. 2.0.0 explicitly split domain and presentation; property classes were removed and the fluent builder API changed. There is an official upgrade guide — read it before estimating.
  • From another ICS library (e.g., kigkonsult/icalcreator or a Spatie generator): map your event constructs to the domain vocabulary first, then rebuild output. Expect the timezone and all-day semantics to be the fiddly part, not the data mapping.

If migrating to something else later, the adapter boundary means only the mapper is rewritten.

Compatibility. Pin deliberately, e.g. "eluceo/ical": "^2.14" for a PHP 8.2 estate or ^2.16 for PHP 8.4+. Add a platform requirement check in CI so a future PHP bump prompts a review of the pin rather than silently breaking. Verify the mbstring extension is present — it is used for line folding and has been an explicit perf dependency since 0.13.

Sequencing.

  1. Confirm PHP version and pick the major/minor pin; record the rationale.
  2. Build the domain mapper in isolation with unit tests against string output (assert BEGIN:VCALENDAR, DTSTART;TZID=, folding at 75 octets).
  3. Add the thin HTTP layer (headers, filename, streaming vs. echo).
  4. Validate output against real clients — Outlook, Google Calendar, Apple Calendar — before wiring the UI.
  5. Only then add recurrence, TTL (X-PUBLISHED-TTL, useful for feed refresh cadence), categories, and attendee/organizer fields if required.
  6. Add a golden-file regression test so future library bumps surface output diffs.

Operational Impact

Maintenance. MIT licence, actively released (a 2026-07-12 release), documented changelog per version, CI + codecov + Psalm + Infection mutation testing badges — the quality signals are better than most single-maintainer PHP packages. The maintenance burden on us is genuinely low: no runtime services, no schema, no daemon. The one recurring chore is the PHP-version coupling described above; budget an hour per major PHP upgrade to re-evaluate the pin. Watch the deprecation noted in 2.1.0 around TimeZone::createFromPhpDateTimeZone defaults — it signals a future major-version break.

Support. Community-only: GitHub issues, Discussions Q&A, and a dedicated docs site (ical.poerschke.nrw). No vendor SLA. That is acceptable for a format serializer; it would not be for payments or auth. The practical mitigation is our own regression tests — they, not the upstream project, are what guarantee our output stays valid.

Scaling. Rendering is CPU/string-bound and linear in event count. For large feeds, the concerns are memory (whole calendar built then cast to string) and line-folding cost. Mitigations: cache the rendered ICS and serve it from cache with X-PUBLISHED-TTL set so clients re-poll on a schedule you control; stream generation for very large calendars; avoid rebuilding on every request. Calendar payloads are small relative to typical JSON APIs, so this rarely becomes the bottleneck — but a public "subscribe" feed can be polled by many clients and is a cheap CDN/cache win.

Failure modes. Expect problems in this order:

  1. Timezone handling — historically the richest bug surface (multiple fixes across 0.11–2.10, including UTC offset formatting and TZOFFSETFROM -0000). Test explicitly with DateTimeImmutable in non-UTC zones.
  2. All-day event semantics — DTEND is exclusive; off-by-one day is the classic bug (fixed back in 0.11.1 but easy to reintroduce in our mapper).
  3. Text escaping and line folding — a \n escaping bug existed as recently as 2.14.0; long descriptions fold at 75 octets. Assert on raw output.
  4. Client tolerance drift — a file that is technically RFC-correct may still render oddly in Outlook. Only real-client testing catches this.
  5. Pinned-version drift — staying on an older minor means missing fixes; track this as tech debt with an owner.

Ramp-up. Low for a competent PHP developer: the README example is copy-paste runnable, the examples/ folder covers common cases, and the four-step mental model (event → calendar → factory → string) is learnable in an afternoon. The actual learning curve is RFC 5545 literacy — DTSTART/DTEND exclusivity, VTIMEZONE blocks, RRULE grammar — not the library. Front-load that knowledge in the mapper's tests and comments; it is the thing that will actually break in production.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
marcelgwerder/laravel-api-handler
firebrikdotcom/conveyor-laravel-broadcaster
kanata-php/conveyor-laravel-broadcaster
alish/short-message
sonrac/lumen-league-oauth2
pushery/sanctum-hardening-for-laravel
evanschleret/laravel-uuidable
yigit-serin/laravel-openvidu
adachsoft/command-executor-lib
tagixo/document-builder
tagixo/page-builder
tagixo/mail-builder
tagixo/form-builder
primix/primix
tagixo/core
alesima/laravel-azure-service-bus
tomshaw/shopcart
likyly/laravel
darthsoup/shoppingcart
tdt/core