lara-zeus/quantity
Lara Zeus Quantity is a Laravel package for working with quantities and units of measure. Define units, convert values between them, and format quantities cleanly, making it easy to handle product weights, lengths, and other measurements in your applications.
Build vs. buy on the quantity input for Filament admin surfaces. A number field with increment/decrement controls, a step, bounds, precision, and a unit label looks trivial and isn't. Hand-rolled steppers accumulate clamping bugs, decimal-rounding drift, and out-of-range states, and each resource fixes them separately. This package collapses that to one composer require plus a fluent field definition (minValue, maxValue, default, step, precision). The buy case is narrow but real: days saved rather than months, low regret, and the blast radius of a swap is a single form control.
Feature scoping for back-office and operations tooling. The documented use cases — stock levels, measurements, order quantities — map to a cluster of screens most internal panels eventually need: inventory adjustments, receiving and purchase-order forms, order-line editors, provisioning/seat counts, material or recipe quantities. If the roadmap has more than one Filament resource that needs "a number plus a unit," this is one decision covering all of them, with identical interaction across the panel.
A consistency lever, not a differentiator. The product value is convention: one component with one documented option set means every squad renders and validates quantities the same way. That's a quality argument — fewer inconsistent admin screens, fewer "why does this accept 0.0001 units?" tickets — and it belongs in engineering standards, not on a customer-facing roadmap slide.
Scoping the boundary between input and domain logic. This package captures how a quantity is entered. It does not know what a quantity means. Reservations, tiered pricing, per-warehouse availability, unit-of-measure conversion, and stock enforcement stay in your domain layer regardless of which stepper renders the input. Making that boundary explicit early prevents a product team from shipping a screen that accepts a quantity the warehouse can't fulfil because "the field had a max."
Maintenance posture as a planning input. Release 3.0.2 is housekeeping: docs restructuring, two Dependabot CI-action bumps, and exactly one behavioural change — increment/decrement now delays the live update so rapid clicking doesn't fire a request per tap. Read that as stable and cared for, not actively expanding. Plan against the feature set visible today; do not schedule roadmap items assuming upstream will deliver unit conversion, per-warehouse rules, or richer UX on request.
Sequencing risk into the delivery plan. The one behavioural change in 3.0.2 means dependent UI — line subtotals, cart badges, running totals — may now observe batched rather than per-click updates. That's a QA line item and a UX expectation to set, not a surprise to discover in UAT.
Adopt when:
composer.json diff cleanly against your panels. A Filament 4 panel is a hard stop, not a warning — verify this before anyone writes a ticket.StockQuantity extends Quantity) so product teams consume a stable internal API and you retain a fork-shaped escape hatch.Look elsewhere when:
lockForUpdate() or an atomic decrement() regardless of the field.Migration and schema note worth deciding at kickoff, not later: if you use the unit selector, store the unit as its own queryable column rather than packing value and unit into a string, and decide now whether unit participates in any pricing or stock key. Confirm the field's precision default agrees with your column type and Eloquent cast — a decimal(10,3) column behind a two-decimal field truncates silently, and nobody notices until a report is wrong.
To executives: We can stop hand-building quantity inputs across our admin panel. This is a small MIT-licensed component that gives us one consistent, validated number-plus-unit field for inventory, order lines, and seat counts — a days-not-months saving, with a fallback we can build ourselves in one to two days if it ever goes stale. It is infrastructure, not a product differentiator, and it does not change what our customers see.
To engineering: It is a single Filament Field subclass plus a Blade view with no service provider or config to publish. We wrap it in one internal component so the rest of the codebase depends on our API, not upstream's; upgrading later or replacing it with an Alpine stepper with wire:model.live.debounce is confined to that one file. Pin the version, put it on the dependency-review list, and note the two sharp edges: 3.0.2 batches live updates on rapid clicking, so dependent totals and any per-click assertions need re-verification; and bounds are UX only, so server-side validation and a DB constraint stay our responsibility.
To design and ops: Every quantity field in the panel will look and behave the same — same steppers, same bounds, same number formatting, same unit presentation in read-only views. That is fewer inconsistent screens and fewer support tickets about decimals and out-of-range values.
The honest caveat to say out loud: single maintainer, 19 stars, no dependents, no SLA, and a roadmap that is housekeeping rather than expansion. The mitigations are cheap — wrapper component, pinned version, documented fallback — and because the surface area is one field, "fork and vendor" is genuinely viable. This is a low-regret bet, not a strategic commitment.
How can I help you explore Laravel packages today?