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

Laravel Drafts Laravel Package

oddvalue/laravel-drafts

A simple, drop-in drafts and revisions system for Laravel models. Add a trait to your model, update the database, and get published revisions, current revisions, auto drafts, and preview mode via middleware, with minimal changes to your existing code.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy for editorial workflow. The draft/publish/revision layer is undifferentiated plumbing that most content products need and few teams want to own. This package puts it at roughly one composer require plus a migration call, which reframes the decision from "can we afford two sprints of versioning work?" to "do we accept a dependency and seven columns?"
  • Roadmap sequencing of publishing features. Three capabilities that usually get separate epics are available as toggles: scheduled publishing (schedulePublishing() + drafts:publish artisan command on the scheduler), autosave/draft recovery (opt-in auto drafts, quietly upserted in place and excluded from revision history), and preview mode (a facade flag that flips the default scope to current-revision regardless of publish state). Each can ship independently and each is off by default, so we can commit to a date without committing to the whole surface.
  • What "published" means in the product. The package forces an explicit decision: content has a published revision (public), a current revision (what the admin edits), and historical revisions (default retention: 10, configurable). That distinction should be reflected in the admin UX, in preview links, and in the API contract — deciding it now prevents a later retrofit.
  • Data model and downstream system decisions. Drafts are duplicated rows, not column-level versioning, sharing a uuid. This has product consequences worth deciding deliberately: search indexes, sitemaps, analytics counts, exports, and reporting must all exclude non-published rows; storage grows with edit frequency, bounded by the retention setting. If we run a search engine or data warehouse, the sync job needs a publish filter.
  • Scope boundary on approvals. The package models who published (a publisher morph) but not approval state. If the roadmap includes draft → review → approved → publish, or editor/approver role separation, that is custom work on top — budget it separately rather than assuming it is included.
  • Rollback and audit expectations. Revision rows are retrievable via revisions(), but a documented "restore this revision" affordance is not part of the stated API. If stakeholders expect one-click revert, treat it as a small build item; if they expect field-level legal-grade audit history, treat it as a different product decision entirely.
  • Feature-flag posture. Auto drafts and scheduled drafts are additive and disabled by default — no query references is_auto or will_publish_at until enabled, and the API throws a LogicException when off. That is a genuinely low-risk way to trial a roadmap item in production.

When to Consider This Package

Adopt when most of these hold:

  • The app is Laravel 9–12 and content lives in Eloquent models you control (the version matrix maps Laravel 11 to v2.x, Laravel 12 to v2.1+/v3.x — pin deliberately).
  • You need row-level versioning plus a publish flag, not a full CMS. This is infrastructure; there is no UI. It pairs with an admin framework (Filament/Nova) or your own screens.
  • You can accept the schema cost: is_current, is_published, is_auto, published_at, uuid, publisher_type, publisher_id (plus will_publish_at if scheduling), added via $table->drafts() and removable via dropDrafts() — a clean migration path, and column names are overridable per model via constants.
  • The team has audited existing queries for the default global scope, which returns only published rows. This is the single biggest hidden cost of "drop-in": every report, count, admin list, and relationship load on a drafted model changes behavior unless it opts into withDrafts() / onlyDrafts() / current().
  • Relations are basic — HasOne/HasMany are duplicated on publish, BelongsToMany/MorphToMany are synced, and you must declare $draftableRelations. Fine for a post/tags model; thin for deep content graphs.
  • Single-locale or per-model drafting is acceptable. Draft-per-locale combined with a translation package is not addressed and will be bespoke work.
  • A single-maintainer, MIT, ~438-star dependency is tolerable for non-critical-path content. Signals are reasonable — tests, code style, changelog, releases through 2026, coverage badge — but dependents are effectively zero, so ecosystem validation is thin.

Look elsewhere when:

  • You need compliance-grade audit trail (per-field diffs, immutable log, retention policy), multi-step editorial approval, or real-time collaborative editing — that is a different class of product.
  • You need localized drafts, granular per-locale publishing, or content branching/merging.
  • The content graph is heavy: nested children, polymorphic trees, or relations beyond the supported four types.
  • You require vendor support or SLAs, or your procurement treats single-maintainer packages as unacceptable on revenue-critical paths.
  • You are not on Laravel, or you would rather avoid mutating core tables with seven columns and a global scope.
  • Your team cannot absorb the next major upgrade: the docs already state a future major will require the Draftable contract. New models should implement it now to avoid the migration.

How to Pitch It (Stakeholders)

For executives (one paragraph). We need drafts, publishing, and revision history for content. Building that ourselves is roughly two to four engineering sprints of undifferentiated work plus permanent maintenance. oddvalue/laravel-drafts is a focused, MIT-licensed Laravel package that provides it as a drop-in on our existing models — including scheduled publishing, autosave-based draft recovery, revision retention, and a preview mode that lets non-technical stakeholders review unpublished content via a link. Cost is a composer dependency and an additive database migration; there is no new service, no vendor contract, and it is reversible (the migration helper has a matching drop method). The trade-offs are honest ones: it is an infrastructure layer with no admin interface, it assumes simple content models, and it is maintained by a single author, so we should confine it to content paths rather than revenue-critical flows.

For engineering (the short version). Add HasDrafts (and implement Draftable now, ahead of the next major), run $table->drafts(), declare $draftableRelations. Be aware that the trait installs a global scope returning published rows only — audit every existing query and admin list on those models; opt in explicitly with withDrafts(), onlyDrafts(), current(), or the WithDraftsMiddleware / Route::withDrafts() helper for management routes. Publishing duplicates HasOne/HasMany and syncs pivot relations; revisions cap at 10 by default and cascade on delete/soft-delete/restore; withoutRevision() exists for metadata-only updates. Auto drafts and scheduled drafts are opt-in flags — enabling them on existing tables requires adding is_auto and will_publish_at first, and the related APIs throw until enabled, so they cannot silently affect current behavior. Scheduled publishing needs PublishScheduledDrafts registered per model in the scheduler. The main risks to size in the estimate are: search-index and analytics filtering, any per-revision restore UI we decide to build, and the absence of approval-state and localization support.

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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log