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

Uuid Laravel Package

ramsey/uuid

ramsey/uuid is a PHP library for generating and working with universally unique identifiers (UUIDs). Install it via Composer, then generate, parse, and validate UUIDs across versions, with support for version 3, 4, 5, 6, 7, and 8.

View on GitHub
Deep Wiki
Context7

Getting Started

Laravel already ships ramsey/uuid (via laravel/framework), so composer show ramsey/uuid is usually enough to confirm the version. If you need it standalone or pinned, run composer require ramsey/uuid. Check the installed version against the changelog — v4.5+ gives you RFC 9562 UUIDv6/v7/v8, which is what most Laravel work now wants.

Where to look first:

  • Ramsey\Uuid\Uuid — the static factory (uuid1(), uuid4(), uuid5(), uuid7(), fromString(), fromBytes(), isValid(), NIL, MAX).
  • Ramsey\Uuid\UuidInterface — what you actually type-hint; exposes toString(), getBytes(), getVersion(), equals(), compareTo().
  • Illuminate\Support\Str::uuid() / Str::orderedUuid() — thin Laravel wrappers you'll see in existing code; both return UuidInterface objects, not strings.
  • The docs at https://uuid.ramsey.dev for the version semantics (v4 vs v7 vs v5).

First use case — a UUID primary key on an Eloquent model:

use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;

class Invoice extends Model
{
    use HasUuids; // Laravel 9+; generating in the `creating` event
}

Migration:

Schema::create('invoices', function (Blueprint $table) {
    $table->uuid('id')->primary();
    $table->foreignUuid('customer_id')->constrained();
    $table->timestamps();
});

If you need the ID before insert (e.g. to build a URL or dispatch a job referencing it), call $invoice->newUniqueId() or set $invoice->id = (string) Uuid::uuid7(); yourself.

Implementation Patterns

Pick the UUID version by intent, not by habit. v4 is random and fine for public-facing identifiers/tokens. v7 is time-ordered (leading 48 bits are a Unix millisecond timestamp), which means inserts stay roughly sequential and B-tree indexes don't fragment — this is the right default for primary keys on high-write tables. v5 (name-based, SHA-1) is for determinism.

Prefer v7 for primary keys. Newer Laravel releases expose HasVersion7Uuids; on older versions roll it yourself or use Str::orderedUuid():

use Ramsey\Uuid\Uuid;

class Order extends Model
{
    public $incrementing = false;
    protected $keyType = 'string';

    protected static function booted(): void
    {
        static::creating(function (self $model) {
            $model->id ??= Uuid::uuid7()->toString();
        });
    }
}

Be explicit about string vs bytes. CHAR(36) is convenient and human-debuggable; BINARY(16) saves ~20 bytes per row and indexes faster but needs a cast. Don't mix the two on a join column — MySQL will happily let you create a foreign key between char(36) and binary(16) and then fail at runtime.

// migration
$table->binary('id', 16)->primary();

// cast
class UuidBinaryCast implements CastsAttributes
{
    public function get($model, $key, $value, $attributes): ?string
    {
        return $value === null ? null : Uuid::fromBytes($value)->toString();
    }

    public function set($model, $key, $value, $attributes): ?string
    {
        return $value === null ? null : Uuid::fromString((string) $value)->getBytes();
    }
}

Use v5 for idempotency and dedupe keys. Deterministic UUIDs let you re-run a job or webhook handler without duplicating rows:

$id = Uuid::uuid5(Uuid::NAMESPACE_URL, "https://app.test/webhooks/stripe/{$eventId}");
Payment::firstOrCreate(['id' => $id->toString()], $payload);

Normalize on the way in, stringify on the way out. Uuid::fromString() accepts hex, URN (urn:uuid:...), and braced forms. Store the canonical toString() form (lowercase, hyphenated) and never store user input verbatim. In API resources and JSON, always emit (string) $uuid — the object implements JsonSerializable, but you don't want version-dependent output shapes leaking into your API contract.

Validation: Laravel's uuid rule is fine for the common case; uuid:4 or uuid:7 narrows by version. For nil/max or nonstandard values, drop down to Uuid::isValid($value) inside a closure rule. Validate before fromString() — it throws InvalidArgumentException, which you don't want surfacing as a 500.

Foreign keys and route bindings work unchanged; just keep $keyType = 'string' and $incrementing = false on both sides, and consider a whereUuid() route constraint so malformed URLs 404 instead of hitting the DB.

Testing: seed with fixed UUIDs (Uuid::fromString('0192f0c4-...')) rather than random ones so assertions are stable; use Uuid::NIL/Uuid::MAX for edge cases. Remember that v7's timestamp comes from microtime() (as of 4.9.1+), so Carbon::setTestNow() will not pin a v7 UUID's timestamp — assert on ordering or inject a generator instead of asserting exact values.

Gotchas and Tips

  • Str::uuid() returns an object, not a string. Str::uuid()->toString() or cast. Assigning the object to a string column works via __toString but breaks strict typing and confuses static analysis. UuidInterface now extends Stringable, so (string) is safe.
  • === never works for comparison. Two Uuid instances for the same value aren't identical. Use $a->equals($b) or compare toString().
  • Don't hand-roll UUID generation. uniqid(), md5(random_bytes()), and friends produce non-RFC values that fail your own validator later. If you're on Str::orderedUuid() in an older Laravel, know that it's a COMB-style UUID (v4 with a timestamp prefix), not a real v7 — and the underlying OrderedTimeCodec/CombGenerator are deprecated for removal in 5.0. Migrate to Uuid::uuid7() now.
  • v7 monotonicity is per-process. The library guards against same-millisecond collisions (fixed in 4.7.5), but don't assume globally monotonic ordering across queue workers — rely on the database's ORDER BY created_at or an explicit sequence if strict ordering matters.
  • Lazy UUIDs surprise you. Uuid::fromString() may return a LazyUuidFromString that defers parsing; it's fine but shows up oddly in var_dump and some serializers. Call ->toString() when crossing a boundary (queues, cache, API).
  • Uuid objects in queued jobs serialize fine but bloat payloads. Cast to string before putting them in a job's public properties.
  • Unique constraint collisions still need handling. They're vanishingly rare for v4/v7, but import scripts and retried jobs deserve a try/catch on QueryException with a regenerate-and-retry, rather than a hard failure.
  • v1 leaks your MAC address via the node field. If you ever use uuid1(), configure a random node provider; better, don't use v1 at all.
  • Watch the brick/math constraint. Recent releases churn on ^0.8 → ^0.18; if another package pins an incompatible range you'll get a resolver conflict that looks unrelated to UUIDs. Keep ramsey/uuid current — 4.9.2 and 4.9.3 exist mainly to widen that range and silence PHP 8.5 cast warnings.
  • ext-ctype is required since 4.3. Rare in modern images, but if you're on a stripped Alpine build, add symfony/polyfill-ctype.
  • Check getVersion() defensively when reading UUIDs from external systems — you may receive v3/v5 name-based values, nil, or max, and your code should not assume v4.
  • Extension points, if you need them: UuidFactory (swap the validator, codec, or generator), NodeProviderInterface (v1 node source), and ValidatorInterface (custom accepted formats). Most Laravel apps never touch these — reach for them only when integrating with a legacy system that has its own UUID dialect.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager