overtrue/laravel-versionable
Add lightweight version history to Laravel Eloquent models. Track only changed attributes, control fields via whitelist/blacklist, keep a set number of versions, browse versions and revert to any saved point in time with simple APIs and migrations.
versions table (configurable), decoupling versioning logic from business models. This adheres to Laravel’s convention of "one model per table."DIFF (default): Stores only changed attributes (space-efficient, ideal for large datasets).SNAPSHOT: Stores full attribute copies (simpler queries, useful for complex objects).jfcherng/php-diff for human-readable deltas, enabling UX features like side-by-side comparisons in admin panels (e.g., Filament integration).isForceDeleting() checks).use Versionable).$versionable or $dontVersionable).php artisan vendor:publish).$versionModel).$versionStrategy).save() triggers a version check (configurable via withoutVersion()).with('versions')).| Risk Area | Severity | Mitigation |
|---|---|---|
| Version Table Bloat | Medium | Use DIFF strategy; limit retained versions via config ($keepVersions). |
| Query Complexity | Low | Avoid deep version queries in high-traffic endpoints; use eagerLoad(). |
| Diff Accuracy | Low | Test edge cases (e.g., nested arrays, JSON fields) with stripTags option. |
| Migration Conflicts | Low | Publish migrations early; use --force cautiously. |
| Laravel Version Lock | Medium | Pin to ^5.5 for stability; monitor Laravel 13+ compatibility. |
| Concurrency Issues | Low | Use database transactions for critical revert operations. |
| Custom Model Inheritance | Low | Extend \Overtrue\LaravelVersionable\Version for custom logic. |
$keepVersions)? Auto-purge old versions?Versionable trait or use a dedicated test model?FeatureTest examples.filament-versionable integration.X-Version-ID header).Post, UserProfile).composer require overtrue/laravel-versionable
php artisan vendor:publish --provider="Overtrue\LaravelVersionable\ServiceProvider"
php artisan migrate
DIFF or SNAPSHOT)./posts/{id}/versions/{version}/revert).| Component | Compatibility | Notes |
|---|---|---|
| Eloquent Models | ✅ Full support | Works with standard and custom models. |
| Relationships | ⚠️ Limited | Versioning does not track relationships (e.g., belongsTo). |
| Observers/Events | ✅ Supported | Triggers saving/saved events; can hook into reverting. |
| Scopes | ✅ Supported | Respects global/local scopes (e.g., SoftDeletes). |
| API Resources | ✅ Manual | Extend JsonResource to include version metadata. |
| Queues/Jobs | ✅ Supported | Versioning works in queued jobs (no async-specific logic). |
| Caching | ⚠️ Caution Required | Avoid caching versioned models; use Cache::forever() sparingly. |
| Replication | ✅ Supported | Version tables replicate like any other table. |
$keepVersions, $versionStrategy) in a config file or environment variables.attributesToArray() method in v5.2.4).^5.5 for stability; test upgrades against Laravel minor versions.revert, removeVersion) for debugging:
\Log::info('Reverted model', ['model' => $model->class, 'version' => $versionId]);
$versionable attributes; check withoutVersion() blocks.stripTags: true for HTML content.with('versions') or loadMissing('versions').tinker to inspect versions:
$post = Post::find
How can I help you explore Laravel packages today?