Looking to hire Laravel developers? Try LaraJobs

laravel-phantom maintained by skycoder

Description
Zero-config database activity tracking, timeline & automation for Laravel.
Author
Last update
2026/07/06 21:50 (dev-main)
License
Links
Downloads
3

Comments
comments powered by Disqus

Laravel Phantom 👻

Zero-config database activity tracking, timeline & automation for Laravel.

Installation

composer require skycoder/laravel-phantom

That's it. No configuration. No traits. No setup. Phantom hooks into DB::listen() on boot and starts tracking every INSERT/UPDATE/DELETE across your whole database.

Dashboard

Visit yourdomain.com/phantom to see the activity dashboard.

  • Tracked Tables — every table Phantom has logged activity for, with entry counts
  • Browse all tables — every table in the database (searchable/sortable), even ones with no activity yet
  • Per-table live data — the actual current rows in a table, paginated and searchable
  • Per-record timeline — full history for one row: created → updated (field-by-field, old → new) → deleted, grouped by day, infinite-scroll

⚠️ Security

None of the /phantom routes ship with authentication. Anyone who can reach that URL can browse the live contents of every table in your database (only password/remember_token columns are masked). Before deploying to anything but local development, protect the routes yourself, e.g. in your app's RouteServiceProvider or a wrapping route group:

Route::middleware(['web', 'auth', 'can:view-phantom'])
    ->group(base_path('vendor/skycoder/laravel-phantom/routes/phantom.php'));

or gate the whole thing behind your admin panel's existing middleware stack. This is on the roadmap to make config-driven; for now it's the integrator's responsibility.

Features

  • ✅ Tracks ALL database operations (Eloquent, Query Builder, Raw)
  • ✅ INSERT / UPDATE / DELETE detection
  • ✅ Field-level change tracking (old vs new values on UPDATE)
  • ✅ Per-table timeline & per-record history, grouped by day with infinite scroll
  • ✅ Who, when, what — full audit trail (resolves user_id to a name from your users table when possible)
  • ✅ Browse every table's live data with search/sort/pagination, drill into any row's timeline
  • ✅ Beautiful built-in dashboard with light/dark theme (follows system, toggleable, persisted)
  • ✅ No-op updates aren't logged — an UPDATE that doesn't change any tracked field never hits phantom_logs
  • ✅ Sensitive fields (password, remember_token) never stored in the audit trail
  • ✅ File/upload fields (name matches file, image, photo, avatar, attachment, document, upload, thumbnail, banner, logo, video, audio, media) never stored
  • 🔜 Email & notification automation
  • 🔜 Conditional triggers
  • 🔜 Config-driven route protection

How it works

Phantom listens to every query via DB::listen() and keeps two tables:

  • phantom_logs — one row per INSERT/UPDATE/DELETE: table, record id, operation, who/when, and (for updates) modified_data — only the fields that actually changed, as {"field": {"old": ..., "new": ...}}.
  • phantom_snapshots — the last known full state of each record (excluding id, created_at, updated_at, password, remember_token, and file/upload-looking fields), used to diff against on the next update.

Tables phantom_logs, phantom_snapshots, sessions, cache, migrations, record_timelines, and timelines are always ignored.

Programmatic use

The Phantom facade (bound to the same instance used internally) exposes:

use Skycoder\Phantom\Facades\Phantom;

Phantom::phantomTimelineUrl('orders', 42);
// -> https://yourdomain.com/phantom/table/orders/records/42

Requirements

  • PHP 7.2+ or 8.0+
  • Laravel 5.8, 6.x, 7.x, 8.x, 9.x, 10.x, 11.x, 12.x, or 13.x

Compatibility

Laravel PHP
5.8.x 7.2+
6.x 7.2+
7.x 7.2.5+
8.x 7.3+
9.x 8.0+
10.x 8.1+
11.x 8.2+
12.x 8.2+
13.x 8.3+

License

MIT