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

Orderly Laravel Package

baril/orderly

Orderly adds orderable/sortable behavior to Laravel Eloquent models. Add a position column and the Orderable trait to reorder records with methods like moveToOffset, using a custom order column if needed.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

Feature-level decisions this package touches directly

  • User-curated ordering of content. Any roadmap item that says "let admins/editors reorder X" — homepage carousels, featured products, navigation links, FAQ entries, onboarding steps, curated collections, playlists, dashboard widgets — maps onto an orderable Eloquent model. This is where the package earns its keep: it's the difference between a two-day ticket and a two-week ticket.
  • Scoped ordering, not global ordering. Orderable groups ($groupColumn, including multi-column groups) let us ship "reorder items within a section/category/board" without inventing a bespoke scoping scheme per feature. This unlocks roadmap items like per-section CMS ordering, per-board card ordering, or per-tenant custom ordering — and it's the single most valuable capability in the package for a typical B2B SaaS roadmap.
  • Ordering across relationships. belongsToManyOrderable / morphToManyOrderable support ordering of pivot rows (e.g., tags on a post, contributors on a project, attachments on a record), including ordered attach/sync/detach semantics. This replaces a genuinely error-prone hand-rolled pattern — pivot position columns are where in-house implementations usually break.
  • Bulk reordering / "apply this sort" flows. saveOrder(), setOrder(), and the static/query-builder setOrder() variants support roadmap features like "re-sort by publication date," "import a CSV and apply its order," "reset to default ordering," or "merge two lists." These are the flows that generate the worst support tickets and the most data corruption when written by hand.
  • Operational self-healing. The orderly:fix-positions artisan command (models and pivot relations, with a proper exit code) is a real ops affordance: it makes "positions drifted after a manual DB delete" a scripted remediation instead of a data-migration incident. This is a genuine argument for the package over an in-house trait.

Build vs. buy

  • Buy (adopt): when the ordering requirement is "manual, user-defined, per-group, on Eloquent models" and the alternative is a bespoke trait. The correct implementation involves gap-free position maintenance on create/delete, mass-reorder batching to avoid N+1 writes, collection helpers, and DB-portable renumbering. That's a small but real piece of infrastructure with subtle failure modes; re-deriving it on every team is not a good use of engineering capacity.
  • Build (don't adopt): if we only need a one-off orderBy('created_at') or a single editorial list that a product manager can reorder weekly. A position column plus orderBy is ~10 lines and the package's surface area isn't earned.
  • Defer: if ordering is entangled with a richer domain concept — nested hierarchies, dependency graphs, or per-user-per-entity personalization at scale — where the right model is a tree, a closure table, or a separate ranking service, not an integer column.

Sequencing implication for the roadmap

  • Because adoption cost is low (one column, one trait, one $guarded entry), this is a good "unblock three features cheaply" decision: it can be folded into whichever of the ordered-list features lands first, rather than meriting its own initiative. Treat it as an enabler inside the first CMS/catalog/board feature, not a standalone workstream.

When to Consider This Package

Strong fit — adopt

  • The stack is Laravel 6 through 13 and the models are Eloquent. Version mapping is explicit and the package has kept pace with every Laravel major (up to v3.4.x for Laravel 13), which is a meaningfully better maintenance signal than the star count suggests.
  • We need manual, human-controlled ordering — i.e., the sort order is data a user edits, not a derived value. Derived sorting is a job for orderBy.
  • We need scoped ordering within a parent (one-to-many or multi-column groups), or ordered many-to-many / morph-to-many relationships. These are the two areas where in-house code most reliably goes wrong, and where the package's value is highest.
  • We need mass reordering primitives (saveOrder, setOrder, collection helpers) for import, re-sort, or merge flows.
  • We are on a multi-DB reality or a non-MySQL production target. v3.3.0 added SQLite/PostgreSQL/SQL Server support, so an app developing on SQLite and deploying on Postgres is not a problem — but note this support is recent, so it deserves explicit test coverage on our side rather than assumption.
  • We want a repair path in ops tooling for position drift.

Proceed with caution — pilot behind an interface

  • Low community signal. 2 stars and 0 dependents means effectively no third-party validation: no blog posts, no Stack Overflow corpus, no crowd-sourced bug discovery. Every edge case is ours to find. Mitigate by wrapping the package behind a thin internal Sortable contract and owning tests for reorder, delete-gap-closing, grouped reorder, and pivot reorder.
  • Bus factor of one. A single maintainer, MIT-licensed, with no commercial backing. The release history is steady and the changelogs are honest (bug fixes, DB portability, exit codes), which is a positive signal about care — but it is not a support commitment. Budget for the possibility of vendoring or forking the trait (small enough to own if needed).
  • Write amplification on reorder. Position-shifting semantics mean a single move can update many rows. Fine for editorial lists of tens to low hundreds; a different story for high-cardinality lists reordered frequently or concurrently.
  • Concurrency is not a stated guarantee. The README documents fresh-model semantics for safe reordering and provides batch APIs, but there's no discussion of transactional isolation or row locking around concurrent reorders. If two editors drag-and-drop simultaneously, assume last-write-wins unless we add locking at the application layer.
  • No UI. This is backend only. Drag-and-drop is a separate frontend decision (SortableJS or similar) plus an endpoint that calls setOrder. Scope it that way from the start, or the estimate will be wrong.

Look elsewhere

  • Hierarchies, trees, nesting, "move this page under that page." Position columns don't model depth. Use a nested-set or closure-table package.
  • Ordering as a ranked/scored system (recommendations, search relevance, feed ranking) — that's derived and computed, not an editable integer.
  • Very large ordered sets with frequent inserts/edits where every reorder rewrites half the table — fractional/lexicographic ordering on a decimal or string key is the better pattern; this package is not that.
  • Ordering that must be versioned, audited, or scheduled ("this order goes live Friday"). Integer positions give you current state only; you'd need a draft/publish layer on top.
  • Non-Laravel services in the same product surface — the order semantics then need to live somewhere shared, not in one app's Eloquent trait.
  • A requirement for vendor support, SLA, or security review depth that a two-star, single-maintainer package cannot satisfy.

How to Pitch It (Stakeholders)

For executives / product leadership (one paragraph)

There's a small, free, MIT-licensed Laravel library that provides the "let users reorder things" capability we keep re-specifying: ordered lists, reordering within a category or section, ordered tags and attachments, bulk re-sorts, plus a repair command if the data ever drifts. The realistic alternative is a bespoke trait we build, test, and maintain ourselves — roughly a week of engineering up front plus ongoing bug surface every time a new ordered feature ships. Adopting this reduces that to a schema column and a one-line trait, and it already tracks Laravel versions through 13 and supports MySQL, Postgres, SQLite, and SQL Server. The tradeoff is real but bounded: it's a low-adoption, single-maintainer project with no commercial support, so we should treat it as a dependency we're prepared to own. Recommended posture: adopt it behind a thin internal interface with our own regression tests, which caps the worst case at "we fork a few hundred lines" rather than "we're stuck."

For engineering (the actual ask)

  • Add an unsigned integer position column and use Orderable on the models that need it; expose reorder actions as an endpoint that calls setOrder([...ids]) on the query builder. Keep the drag-and-drop UI decoupled from the backend primitive.
  • Set $groupColumn where ordering is per-parent rather than global — this is the right default for most of our list features and the cheapest way to avoid per-feature scoping code.
  • Use belongsToManyOrdered for ordered pivots instead of adding our own pivot position logic; sync and detach maintain positions for us.
  • Prefer saveOrder() / setOrder() over looping moveToOffset(); the README explicitly documents that naive loops cause both N+1 queries and data corruption. Review any PR that loops move methods.
  • Wrap the trait behind an internal interface and write our own tests for: create-appends, delete-closes-gap, grouped reorder, pivot attach/sync/detach ordering, and fix-positions after manual deletion. These are our insurance against the bus-factor risk, not a reflection of the package's quality.
  • Add application-level locking or a queue around reorder endpoints if more than one editor can reorder the same list. The package doesn't promise concurrency safety.
  • Run orderly:fix-positions as a documented runbook step after any manual data surgery on ordered tables. Note that the position column must be $guarded.
  • Watch two things in review: the position column should never be mass-assignable from request input, and unordered code paths should call unordered() rather than relying on orderBy to win.

Bottom line for the go/no-go conversation: the capability is a clear buy — the cost of building it is real and the cost of adopting it is a migration and a trait. The package is a considered bet on a small, well-maintained, low-visibility project rather than a safe default. Approve adoption with the interface wrapper and our own test coverage; revisit if we hit a scale profile where position-shifting reorders become a bottleneck, or if the maintainer goes quiet across a Laravel major release.

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.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
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