liberusoftware/notifications
A Laravel notifications package offering a unified API to send alerts across multiple channels, with templating, queued delivery, and flexible configuration. Integrates with Laravel's queue, mail, and database systems for app-wide messaging.
Architecture fit. The package targets a well-known gap in Laravel's first-party notification stack. Illuminate\Notifications gives you channels, queued delivery, and Notifiable routing, but it deliberately leaves preference management, quiet hours, inbox persistence, and delivery-state tracking to the application. This module claims to fill exactly that layer — localized templates, per-user channel preferences, inbox state, retries, delivery status, quiet hours — which maps to roughly four to six weeks of in-house work in a typical product. Architecturally it should slot in as a service-provider package that decorates or replaces the NotificationSender binding, adds migrations for templates/preferences/inbox/delivery records, and hooks the queue lifecycle for retries.
The caveat is the "module" framing: module-notifications implies membership in a larger proprietary-ish ecosystem with house conventions (module registry, shared abstract classes, possibly a custom module loader). That convention layer is the real integration surface, and it is the part least likely to be documented for outsiders.
Integration feasibility. Feasible for a team already standardized on Laravel notifications, but not a drop-in. Two shapes of migration exist: (a) the package wraps existing Notification classes and only adds preference/quiet-hours gating, or (b) it replaces class-defined notifications with DB-stored localized templates. Shape (b) is a much larger change — it moves notification content out of version control and into rows, which changes your review, rollback, and localization workflows. This must be confirmed by reading the source before any estimate is credible.
Technical risk. High, and concentrated in adoption signals rather than code quality. Zero stars, zero dependents, and a single maintainer mean no community scrutiny, no third-party bug reports, no security disclosure history, and no evidence of production use at scale. A last-release date of 2026-10-26 is anomalous relative to the current date and should be verified — it may indicate a mistagged release, a force-pushed tag, or a metadata error, any of which argues for pinning to a commit SHA rather than a version constraint. MIT licensing is favorable: it permits vendoring and forking, which is the mitigation for every other risk here.
Key questions.
Notifiable/NotificationSender or replace them? What happens to existing notification classes?Stack fit. Best fit is a Laravel 10–12 monolith or modular monolith on PHP 8.1+, with Redis or SQS-backed queues and a scheduler already running. It is a poor fit for teams on older Laravel versions, for event-driven architectures where notifications are emitted from multiple services, or for anyone who has already built a bespoke preference layer — in that last case you would be replacing working code with unproven code, which is a bad trade.
Migration path. Do not adopt wholesale. Run a parallel-path pilot: keep native Laravel notifications as the control, enable this module for one low-stakes notification category (e.g. product digest or non-transactional alerts), and compare rendered output, delivery timing, and suppression behavior against the control for two to four weeks. Transactional and security-sensitive notifications (password reset, payment receipts, fraud alerts) stay on the native path until the pilot is clean. Treat the package as vendored source under a fork you control from day one — pin to a commit SHA, not a semver range.
Compatibility. The main collision risk is an application that already customizes the Notifiable trait, overrides the notification sender binding, or wraps Notification::send() in its own dispatch layer. Audit those three surfaces before the spike. Migrations should be inspected for table-name collisions and for foreign keys into users (which assumes a standard table name — a problem in multi-tenant or custom-auth setups). Template localization will also collide with any existing lang/ workflow; decide early whether translations live in files or rows, because running both is worse than either.
Sequencing. (1) Source audit and vendor fork, ~2–3 days. (2) Sandbox spike: publish config and migrations, send one notification through one channel with quiet hours active, ~3–5 days. (3) Staging pilot on a non-critical category with parallel-run comparison, 2–4 weeks. (4) Decide: promote, extend, or build a thin in-house layer on native notifications (the fallback is genuinely viable and should be priced alongside the pilot). (5) If promoting, migrate categories one at a time with a per-category kill switch.
Maintenance. Assume you own this code. With one maintainer and no dependents, upstream responsiveness is unpredictable and the package may be abandoned without notice. Budget roughly 10–15% of one engineer's time for periodic rebases against new Laravel majors, plus the initial fork cost. MIT makes this legally clean; it does not make it operationally free.
Support. No vendor SLA, no paid support, no track record. Escalation path is "read the source yourself." For a TPM this means the package cannot sit behind a business-critical guarantee — it must sit behind an internal owner who can debug it.
Scaling. Every send now writes more: delivery-status rows, inbox rows, retry attempt records. Inbox tables grow with users × notifications and need a retention and pruning policy designed up front, not bolted on at 10M rows. Retries multiply queue throughput on the failure path specifically, which is exactly when you can least afford it — cap retry concurrency per channel or a single upstream provider outage becomes a self-inflicted queue backlog. Quiet hours also introduce deferred sends through the scheduler; verify the delay mechanism handles windows longer than your queue's max delay.
Failure modes. The ones to design against: (a) timezone bugs in quiet hours silently dropping or badly delaying transactional notifications — mitigate with an explicit bypass list for security-critical types; (b) retry storms against a hard-down provider with no circuit breaker; (c) inbox state diverging from actual delivery because status is inferred locally rather than confirmed by provider callback; (d) template changes shipped without a review path, removing the code-review safety net that class-based notifications provide; (e) migration conflicts on tables you don't control; (f) silent abandonment by upstream, mitigated by the fork.
Ramp-up. Low mechanical ramp for a Laravel developer — a day to send a notification, a week to understand the preference and quiet-hours model. The real cost is organizational: product and support teams need to learn a new suppression model, because "the user didn't get the email" now has four possible causes (preference, quiet hours, retry exhaustion, template error) instead of one. Build the observability for that question before you turn the feature on, or support load will absorb the difference.
Recommendation. High feature value, low maturity. The capability set justifies a time-boxed spike (two engineer-weeks maximum including audit), gated on the source actually being readable and the Laravel version matrix being workable. If the spike surfaces the ecosystem-convention coupling described above, fall back to a thin in-house preference and quiet-hours layer on native notifications — with zero dependents and zero stars, this package's ceiling is "useful reference implementation" until someone else proves it in production.
How can I help you explore Laravel packages today?