PHPackages                             justinholtweb/craft-owl - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. justinholtweb/craft-owl

ActiveCraft-plugin

justinholtweb/craft-owl
=======================

A comprehensive events and calendar plugin for Craft CMS 5 with recurrence, multisite, ICS feeds, and Commerce ticketing.

5.1.0(yesterday)00proprietaryPHP &gt;=8.2

Since Jul 19Compare

[ Source](https://github.com/justinholtweb/craft-owl)[ Packagist](https://packagist.org/packages/justinholtweb/craft-owl)[ Docs](https://craft-owl.com)[ RSS](/packages/justinholtweb-craft-owl/feed)WikiDiscussions Synced today

READMEChangelog (1)Dependencies (8)Versions (2)Used By (0)

Owl 🦉
=====

[](#owl-)

A comprehensive events and calendar plugin for **Craft CMS 5** — recurrence, multisite, ICS feeds, a frontend query API, GraphQL, and native Commerce ticketing.

Owl is a maintained, fairly-priced alternative to Solspace Calendar: the recurrence, ICS, and front-end submission features other plugins paywall are included in the **free Lite** edition, and the **Pro** edition ($149) adds first-class Craft Commerce ticketing.

Requirements
------------

[](#requirements)

- Craft CMS 5.6.0 or later
- PHP 8.2 or later
- Craft Commerce 5.0+ (optional — only for the Pro edition's ticketing features)

Editions
--------

[](#editions)

Lite (free)ProEvent element, unlimited calendars, per-calendar field layouts✓✓Recurrence (RRULE) + exceptions + single-occurrence overrides✓✓Month/week/day/list views, FullCalendar demo templates✓✓Twig query API + GraphQL✓✓ICS export + subscription feeds✓✓Front-end event submission✓✓Multisite✓✓Commerce ticketing (tickets, ticket types, capacity)—✓Architecture
------------

[](#architecture)

Owl stores each event's canonical RRULE and **materialises occurrences** into an indexed table (generated to a rolling horizon by a queue job), so calendar range queries and pagination are plain, fast SQL — and per-occurrence ticketing/inventory has a real row to attach to. See [`PLAN.md`](PLAN.md) for the full design.

The recurrence engine (`src/recurrence`) is deliberately framework-agnostic and unit-tested in isolation, including DST spring-forward/fall-back correctness.

Front-end
---------

[](#front-end)

Query events in Twig:

```
{% set upcoming = craft.owl.events
    .startsAfter(now)
    .orderBy('startDate ASC')
    .limit(10)
    .all() %}
```

Feed a JS calendar (FullCalendar) from the JSON endpoint, which returns only the occurrences overlapping the requested range:

```
GET /owl/events.json?start=2026-07-01&end=2026-08-01&calendar=concerts

```

Subscribe to or download ICS:

```
/owl/calendar/.ics   # a calendar's subscribable feed
/owl/event/.ics          # a single event

```

Tickets (Pro)
-------------

[](#tickets-pro)

With the **Pro** edition and Craft Commerce installed, events can sell tickets. Enable "Sell tickets" on a calendar, then **Manage tickets** on an event to add ticket types (name, price, optional capacity). Each ticket is a Commerce purchasable:

```
{% for ticket in craft.owl.tickets.getTicketsForEvent(event.id) %}
    {{ ticket.ticketName }} — {{ ticket.price|commerceCurrency(ticket.store.currency) }}
    {% if ticket.remaining is not null %}({{ ticket.remaining }} left){% endif %}
{% endfor %}
```

Capacity is enforced by Owl: a sold-out ticket reports `getIsAvailable()` as `false`, and the sold count is incremented transactionally when an order completes.

Maintenance
-----------

[](#maintenance)

Occurrences are materialised up to a rolling horizon (default 24 months). Run the regenerate command from a daily cron so open-ended recurrence rules keep extending forward:

```
0 3 * * * cd /path/to/project && php craft owl/maintenance/regenerate >> /dev/null 2>&1
```

Add `--queue` to push the work onto Craft's queue instead of running it inline (recommended for sites with many recurring events).

Development
-----------

[](#development)

PHP and Composer run inside DDEV:

```
ddev start
ddev composer install --no-plugins   # --no-plugins: the craft-plugin installer expects a host app
ddev exec vendor/bin/pest --testsuite=Unit   # framework-agnostic unit tests (recurrence, ICS)
```

The recurrence engine and ICS builder are framework-agnostic and covered by the Pest unit suite.

The Craft layer (elements, services, queries, occurrence materialisation, timezone/DST storage) is covered by an integration harness that runs inside a real Craft install:

```
ddev craft owl/test/run   # exits non-zero on failure
```

> `markhuot/craft-pest` is not yet compatible with Craft 5.9's Symfony 7 dependencies, so the integration coverage is provided via this console harness rather than Pest feature tests.

License
-------

[](#license)

This plugin is licensed under the [Craft License](LICENSE.md) — the standard license for commercial Craft CMS plugins. A commercial license is required for use in a production environment. © 2026 Justin Holt.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/035cb655c55af0e9e5b96754b80fd9703e195c32dbdfc49ae9a43ab9cf8db560?d=identicon)[justinholtweb](/maintainers/justinholtweb)

---

Tags

eventscmsrecurrenceicscalendarCraftcraftcmscraft-plugincommercetickets

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/justinholtweb-craft-owl/health.svg)

```
[![Health](https://phpackages.com/badges/justinholtweb-craft-owl/health.svg)](https://phpackages.com/packages/justinholtweb-craft-owl)
```

###  Alternatives

[verbb/formie

The most user-friendly forms plugin for Craft.

102393.6k72](/packages/verbb-formie)[verbb/events

A full-featured plugin for event management and ticketing.

2311.9k](/packages/verbb-events)[verbb/comments

Add comments to your site.

13753.9k](/packages/verbb-comments)[verbb/vizy

A flexible visual editor field for Craft.

4250.4k](/packages/verbb-vizy)[verbb/hyper

A user-friendly links field for Craft.

24147.8k12](/packages/verbb-hyper)[verbb/social-poster

Automatically post entries to social media.

918.5k](/packages/verbb-social-poster)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
