muhammadsadeeq/laravel-activitylog-ui
Beautiful modern UI for Spatie Laravel Activity Log. Browse activities in table, timeline, and analytics views; filter by date, event, user, or subject; save views; export CSV, Excel, PDF, or JSON; and control access via gates and middleware. Built with Tailwind and Alpine, no build step.
Architecture fit. The package is a presentation layer, not a logging system. It assumes spatie/laravel-activitylog v5 is already installed, configured, and writing to activity_log, and it reads that table. That boundary is the right one for us: it adds no write path, no new domain model, and no data duplication, so the blast radius of adopting or removing it is a route, a config file, and a handful of Blade views. The one place it reaches past a read-only boundary is an opt-in migration that adds indexes to activity_log — a table Spatie owns, not this package. That single migration is the only structural change we are accepting.
Integration feasibility. Mechanically trivial: one composer require, optional config/views/assets publish, a route prefix, a gate. Critically, there is no front-end build step — Tailwind and Alpine ship as a package-served versioned stylesheet (~6KB over the wire per the v3 notes) and the Play CDN/Chart.js/webfont loads were removed. For a Laravel app with a locked-down Vite/npm pipeline or a strict CSP, that removes the usual integration tax for UI packages.
Technical risk. The gating constraint is version alignment, not code quality: PHP ≥ 8.4, Laravel 12 or 13, Spatie activitylog ≥ 5.0. That is a very narrow slice of the installed base and will disqualify the package outright for most current estates. Secondary risks:
422 instead of being silently clamped. Anything we script against these endpoints must be written to v3 semantics.maatwebsite/excel / barryvdh/laravel-dompdf are absent. Silent degradation will be reported as a defect by users.Key questions.
spatie/laravel-activitylog already on v5 with attribute_changes populated, or are we pre-v5?activity_log, and can we obtain a DDL window for the index migration?activity_log? The UI exposes everything within that window to whoever holds the gate.Stack fit. Only proceed if the version matrix already matches or a platform upgrade to Laravel 12/13 + PHP 8.4 is independently committed. Do not upgrade the platform for this package — treat adoption as a rider on an upgrade we'd do anyway. The package's own value proposition (self-serve audit visibility for non-engineers) is real but not worth a platform migration on its own.
Migration path.
attribute_changes column exist. The UI ships legacy fallbacks that read properties.old / properties.attributes, so no backfill is required for readability — but pre-v5 rows will render under "Custom Properties" rather than "Attribute Changes." Decide explicitly whether that historical inconsistency is acceptable or whether a backfill is in scope.activity_log table. This is the only way to size the query and index work honestly.config/activitylog-ui.php line by line. Verify authorization.enabled, because v3 flips the default to true for installs that never published the config, while published configs retain their own value. Confirm access.allowed_users / allowed_roles are now actually enforced even when authorization.enabled is false — that combination was previously a no-op.viewActivityLogUi gate in application code rather than relying on the package's email/role defaults.activity_log while it runs; the upstream benchmark (350ms → 21ms on ~205k rows) tells us this is not optional above roughly six figures.route.middleware bypasses auth. In v3 it replaces the base stack only; the security middleware is appended afterward. Mount the UI behind the admin guard.Compatibility. Beyond the version matrix, the two compatibility surfaces to test are (a) the JSON API contract — clients we write must expect 422 on bad params and anchor_id+anchor_time as a pair on the list endpoint; and (b) export URLs, which are now scoped to the creating user, so any shareable-export workflow we've assumed breaks.
Sequencing. Version verification → staging install with prod data copy → config and gate review → index migration in a window → pilot with a narrow audience (security/compliance/support leads) behind auth → broaden. Do not expose to the general user base before the gate and access lists are proven in the pilot.
Maintenance. Single maintainer, MIT, zero dependents — there is no downstream ecosystem acting as a compatibility canary. Pin exact versions and read UPGRADING.md before every bump; two breaking majors in roughly a year is the observed cadence. Mitigant: with no build step, the view layer is plain Blade + Alpine, so an internal fork is genuinely tractable if upstream stalls. Budget a named owner either way.
Support. Documentation is hosted off-repo (sadeeq.dev), not in the repository — a third-party availability dependency. No vendor, no SLA, no commercial support path. All support is internal.
Scaling. This is a read-heavy UI against the audit table: paginated list, timeline, analytics aggregation, a search that spans attribute_changes, properties, and description, plus exports. Concretely:
analytics.cache_duration to the freshness the audience actually needs, and expect the first request after each expiry to be slow.exports.max_records deliberately and enable exports.queue with a threshold well below the default. A synchronous 10k-row PDF export is a request-timeout and memory incident waiting to happen, and the queue is off by default.Failure modes.
ACTIVITYLOG_UI_AUTHORIZATION=false. Add a startup/config assertion and a periodic unauthenticated-request check.422 on previously tolerated parameters — dashboards, saved bookmarks, or internal scripts written against v2 break loudly rather than degrading.403 across users — shared export links stop working by design; communicate before rollout.activity_log during a live deploy.Ramp-up. Near-zero for end users — it is a self-serve interface with filters, saved views, and timeline/table/analytics modes. Low for developers (composer + publish + gate). Moderate for ops (DDL window, queue worker, auth verification). The real ramp-up cost is not learning the tool; it is independently verifying a security posture that upstream only reached in v3, which is work we own regardless of what the README claims.
How can I help you explore Laravel packages today?