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

Revisionable Laravel Package

rhyanrandolph/revisionable

Laravel package that keeps a revision history for Eloquent models, automatically logging create, update, and delete changes with user context. Easily inspect past versions, compare field changes, and restore or revert records when needed.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Pure Eloquent trait plus a single side table (revisions), so it slots into any Laravel model layer without new infrastructure — no queue, cache, search index, or external service.
  • Storage model is EAV/delta, not snapshot: one row per changed attribute per save (revisionable_type, revisionable_id, user_id, key, old_value, new_value, timestamps, optional IP/additional fields). This is optimal for "who changed field X from A to B at time T" and weak for "give me the full entity state at revision N," which requires replaying deltas.
  • Hooking is via trait boot methods on saved / deleted / restored; opt-in/opt-out per model via $keepRevisionOf / $dontKeepRevisionOf and $revisionEnabled. Fits a domain-model-per-aggregate design; does not fit CQRS/event-sourced designs where revisions should be projections of a real event log.

Integration feasibility

  • Low effort: publish migration + config, run migration, add use RevisionableTrait, declare the relationship usage in controllers/views. A mid-level Laravel developer is productive in under a day.
  • The material friction is identity, not code. The package is rhyanrandolph/revisionable but points at jarektkaczyk/revisionable, while virtually all public documentation and Stack Overflow answers target VentureCraft\Revisionable\RevisionableTrait. Namespace, config key names, and publish tags likely diverge. Every tutorial snippet copied into the codebase must be re-validated.
  • 0 dependents and 256 stars on a personal fork is a signal of low verified adoption — treat the star count as inherited reputation, not a compatibility guarantee.

Technical risk

  • Intrinsic risk is low: small surface area, MIT, no runtime dependencies beyond Eloquent, failures are contained to one table.
  • Supply-chain and longevity risk is high: single-maintainer fork, last release Jan 2023, no upstream SLO, no published Laravel 11/12 support statement. If a future Laravel major changes model event or migration internals, you own the fix.
  • Audit-completeness risk: Eloquent events are bypassed by Model::query()->update(), bulk inserts, raw SQL, and seeded data. Any compliance use case must assume coverage gaps and be designed around them.
  • Attribution risk: user_id and additional_fields typically resolve from the auth/request context; in console commands, queue workers, and scheduled jobs these resolve to null or throw. Silent nulls become an audit finding later.

Key questions

  1. What are the exact composer.json constraints (PHP, illuminate/*) and the actual root namespace of this fork versus VentureCraft?
  2. Does the fork diverge structurally from upstream, and can we return to the maintained upstream (or owen-it/laravel-auditing) without a data migration?
  3. Is the requirement audit trail (compliance: immutable, complete, attributable) or version history (UX: show diffs, revert)? The package serves the second well and the first only partially.
  4. Who is the internal owner if the maintainer disappears tomorrow — and does procurement accept an internally vendored fork?
  5. Expected write volume: how many models, how many updates per minute, and how many fields change per update? That single number drives the whole scaling answer.

Integration Approach

Stack fit

  • Laravel + Eloquent with MySQL/Postgres/SQLite. Compatible with existing auth (uses whatever user model the config names), soft deletes, morphMap, and standard model observers. No conflict with Spatie packages or Octane, provided the trait does not hold request state.
  • Fits monoliths and modular monoliths. In a service-oriented estate, keep revisions local to the owning service's database — do not centralize them into a shared audit store; the EAV schema is not portable.

Migration path

  • Greenfield: vendor:publish migration + config, migrate, add trait to a pilot model with an explicit whitelist ($keepRevisionOf) rather than defaulting to all attributes.
  • Brownfield with existing history: the package cannot backfill. Historical revisions must be reconstructed from binlogs, CDC streams, or nightly snapshots into the same schema, or accepted as a cut-over date with a documented "history begins on X" note.
  • Add an index review on day one: composite index on (revisionable_type, revisionable_id, created_at), plus user_id and created_at if the admin UI filters by actor or date range. The default migration does not necessarily give you this.

Compatibility

  • Pin to an exact version/SHA, not a floating constraint. Verify against your actual PHP and Laravel versions in a spike branch before any rollout commitment.
  • Wrap access behind a thin RevisionRepository / presenter interface in your own namespace. Because the storage schema is vendor-specific, this is the difference between a two-day swap and a two-sprint rewrite when the fork is abandoned. Do not let revisionHistory() calls spread into Blade templates and controllers directly.
  • Note the morphMap trap: if you alias class names, set the map before the first revision is written, or historical revisionable_type values become unreadable.

Sequencing

  1. Timeboxed spike (1–2 days) on one low-risk model: validate namespace, publish tags, migrations, diff rendering, and behaviour under ::query()->update().
  2. Architecture Decision Record comparing this package against owen-it/laravel-auditing and spatie/laravel-activitylog, with an explicit statement of which requirement (audit vs. versioning) you are buying for. Given the low opportunity score, this comparison is the highest-leverage step — the market for this capability is crowded and this fork is not differentiated.
  3. Schema hardening + retention policy design before the second model is wired up.
  4. Rollout by model priority — content/configuration entities first; high-churn tables (counters, status machines, session-like rows) last or excluded via $dontKeepRevisionOf.
  5. Attribution hardening: explicit actor resolution for CLI/queue paths, and a lint rule or code-review checklist item forbidding bulk updates on revisionable models.
  6. Admin surface: diff viewer + actor/date filters, gated behind existing authorization; revisions are sensitive (they expose historical PII and pre-edit values), so apply the same access control as the underlying record, not less.

Operational Impact

Maintenance

  • No vendor maintenance contract. Budget a modest standing allocation (~1–2 engineer-days per Laravel major upgrade, plus reactive fixes) and designate an owner in the platform team.
  • Mitigate supply chain risk by vendoring: internal Composer mirror or a hard SHA pin, with a documented procedure to fork privately. MIT permits this; do it before you need it, not after a package disappears.
  • Track it in the dependency register as "single-maintainer, unreleased-for-18-months, zero dependents" — that classification should trigger the same review as any unmaintained transitive dependency.

Support

  • Community-only. Upstream is effectively dormant; the fork's issue tracker is a single person's attention span. Escalation path is internal, so the internal owner must be able to read the trait (~a few hundred lines) and patch it.
  • Documentation debt is real: your team will read upstream docs while running fork code. Record the actual namespace and pinned version in the internal wiki on day one.

Scaling

  • Dominant cost is write amplification: one insert per changed field per save. A 30-column model with 8 changed fields per update generates 8 rows. Multiply by update frequency and by the number of revisionable models to size the table.
  • The revisions table typically becomes the largest table in the schema. Plan partitioning or archival (e.g., move >12 months to cold storage) from the start; rely on $historyLimit / $revisionCleanup for coarse trimming, but verify the cleanup path is actually triggered and does not contend with OLTP traffic.
  • Reads do not scale for point-in-time reconstruction: rebuilding a full entity state at revision N is O(changed fields) per record and unacceptable in list views. Render diffs per record, and precompute current state from the live table as the package intends.
  • Exclude volatile columns aggressively. Revisioning a last_seen_at or login_count column is a pure cost with no audit value.

Failure modes

  • Silent under-capture — bulk updates, raw SQL, and imports bypass events. This is the failure mode that matters: nothing errors, the audit trail is simply wrong. Detect via periodic reconciliation on a high-value model.
  • Attribution gaps — null user_id from queue/console contexts; additional_fields reading the Request facade throwing outside HTTP. Fail loudly in non-HTTP contexts rather than storing nulls.
  • Namespace drift — a Composer update or a "helpful" refactor to the upstream namespace silently changes which trait is booted.
  • Forced deletes bypass the deleted hook, so hard-deleted records lose their final revision.
  • Type coercion on read — old_value/new_value are text; JSON/array casts and dates come back as strings and will render incorrectly in a naive diff view.
  • PII retention — revisions preserve values users believe they deleted. GDPR/DSAR erasure must extend to the revision table, which the package does not do for you.

Ramp-up

  • Individual contributor: ~half a day to first successful diff, ~2 days to be safe with cleanup, exclusion lists, and attribution.
  • Team cost is mostly process, not learning: the code-review checklist item for bulk updates and the internal ADR are what prevent the silent-capture failure mode. Allocate ~1 sprint-week total for pilot, ADR, schema hardening, and rollout to the first three models before declaring the capability production-ready.
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.
mydnic/volet-feature-board-filament-plugin
wmde/email-address
refinery29/test-util
dees040/laravel-api-responses
teamzac/geocoder
ideatica/config-writer
keaton-php/pipe-dream
jacksonwebservices/laravel-user-suite
maksimru/conditional-laravel-debugbar
gismatul/nova-support-chat
gismatul/laravel-support-chat
networkrailbusinesssystems/oracle-api
alphabalex/messaging-made-easy
rawphp/warp
shootkiran/merobug
narakode/fineauth
numencode/wn-syncops-plugin
ibnnajjaar/mib-global-pay
refinery29/php-cs-fixer-config
parsnick/steak