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 Easy Enum Laravel Package

sakanjo/laravel-easy-enum

Simplify PHP enums in Laravel with sakanjo/laravel-easy-enum. This lightweight package provides helpers for labels, values, options, validation rules, and Eloquent/Blade integration, reducing boilerplate and keeping enum-driven code clean and readable.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a thin convenience layer over PHP 8.1 backed enums — no service provider config, no migrations, no facade. Install it and you get a trait/base class that adds the helpers you'd otherwise rewrite in every project: values(), labels(), options(), toArray(), and an enum-aware validation rule.

composer require sakanjo/laravel-easy-enum

Before writing code, do two things:

  1. Open the README and copy the exact trait/base-class FQCN — the surface area is small and the namespace is the part most likely to drift between releases (the package ships no config file, so there's nothing to publish and inspect).
  2. Skim vendor/sakanjo/laravel-easy-enum/src — it's a handful of files, and reading them takes less time than debugging a wrong assumption about method behaviour.

First use case — kill magic strings in a model:

enum OrderStatus: string
{
    use Sakanjo\EasyEnum\Concerns\HasEnum; // verify FQCN in README

    case Pending   = 'pending';
    case Paid      = 'paid';
    case Cancelled = 'cancelled';
}
class Order extends Model
{
    protected $casts = [
        'status' => OrderStatus::class, // native Laravel cast, not package-specific
    ];
}
<select name="status">
    @foreach (OrderStatus::options() as $value => $label)
        <option value="{{ $value }}">{{ $label }}</option>
    @endforeach
</select>

If that Blade snippet works, the package has already paid for itself. If it doesn't, check whether your version returns ['pending' => 'Pending'] or an array of ['value' => ..., 'label' => ...] — that's the single most common point of friction.

Implementation Patterns

Keep native casts, use the package for presentation and validation. Eloquent's enum cast is first-party and well-tested; don't route it through a third-party trait. The package's value is the read-side helpers.

Validation. Laravel ships Illuminate\Validation\Rules\Enum since 9.x. Use it, and only reach for the package rule if it adds something you actually want (typically label-aware messages):

$request->validate([
    'status' => ['required', Rule::enum(OrderStatus::class)],
]);

Query building. Always unwrap before hitting the query builder, and lean on values() for whereIn:

Order::whereIn('status', OrderStatus::values())->get();

// single value
Order::where('status', OrderStatus::Paid->value)->first();

State transitions belong on the enum, not the package. Add your own methods to the enum directly — this is where backed enums earn their keep:

public function canTransitionTo(self $next): bool
{
    return match ($this) {
        self::Pending   => $next === self::Paid || $next === self::Cancelled,
        self::Paid      => $next === self::Cancelled,
        self::Cancelled => false,
    };
}

API responses. Laravel serialises a backed enum to its value inside toArray()/json(), so API resources need nothing extra. If you want labels in the payload, map explicitly — don't rely on the package's toArray() leaking into your API contract.

Filament / Nova / Livewire. options() is the natural feed for select fields. Wire it once in a form schema and reuse. Note that Livewire needs the enum cast on the model property to round-trip correctly.

Grouping related enums. Once you have three or four of these, add a small app/Enums convention and a base enum class of your own that uses the package trait, so a future swap is one file, not twenty.

Gotchas and Tips

  • Backed enums only. Pure (non-backed) enums can't be cast to columns and can't be validated against. If options() returns empty, check you declared : string or : int.
  • Don't invent a __toString(). It's tempting for Blade, but it breaks match, json_encode, and any code that expects ->value. Use ->value and ->name explicitly; let options() handle display.
  • Method-name collisions are silent until they aren't. labels(), options(), values(), toArray() all sit on the trait. If you also define toArray() on the enum for a custom payload, you'll shadow the trait method and get confusing results. Pick one source of truth.
  • Labels are derived, not declared. The package almost certainly humanises name (PaidLate → Paid late or similar). The moment you need Paid late (overdue) or translations, stop using the derived helper and implement label(): string yourself with a match. Mixing both styles in one codebase is the main readability cost here.
  • Low bus factor. Ten stars and a single maintainer means the dependency should be cheap to remove. It is: copy the trait into app/Support/ and you're done. Don't let it creep into your domain layer — keep it at the edges (views, form options, validation messages).
  • Pin the version. With a small package, a patch release changing an array shape in options() is a real risk. "sakanjo/laravel-easy-enum": "^1.0" with a committed composer.lock is the sane default.
  • Debugging tip: dd(OrderStatus::cases(), OrderStatus::options()) in a Tinker session settles 90% of "the helper doesn't do what I expected" questions faster than reading the README twice.
  • Test the enum, not the package. A single test asserting OrderStatus::options() keys cover a select is enough; you don't need coverage of the vendor trait itself.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo