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

Uid Keys Laravel Package

brokeyourbike/uid-keys

Laravel package that swaps auto-incrementing integer primary keys for unique UID keys on your Eloquent models. Add the trait and new records get collision-resistant string IDs automatically—ideal for APIs, distributed systems, and hiding sequential IDs.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package addresses a narrow, well-understood concern: swapping the primary-key strategy of Eloquent models from auto-incrementing integers to UUIDs or ULIDs. Idiomatic Laravel implementations of this are trait-based (overriding getIncrementing(), getKeyType(), and hooking creating/boot to assign the key), which is additive and low-coupling — it does not alter the query builder, routing, or serialization layers. That makes it architecturally safe in principle: it composes with existing models rather than imposing a base class or repository layer. The risk is not architectural, it is duplicative: Laravel 9+ ships HasUuids and HasUlids in Illuminate\Database\Eloquent\Concerns, covering the same ground with framework-level support and no third-party dependency. For any application on a currently supported Laravel version, the package's core value proposition is largely redundant.

Integration feasibility. Mechanically trivial — a Composer require plus one trait per model. The real cost sits outside the package: schema changes, foreign-key type changes, route-model-binding behavior, and API contract shifts (string keys vs. integer keys). Those costs are identical whether we use this package or the native traits, so the package choice itself is not the gating factor. Verify before committing: Laravel and PHP version constraints in composer.json; whether it depends on symfony/uid and at what version; whether it uses ordered UUIDs (v7-style, index-friendly) or random v4; and whether it publishes a config file or migrations.

Technical risk. High relative to the value delivered, driven almost entirely by project health rather than code quality:

  • 0 stars, 0 dependents, single-maintainer project with no visible community, no security disclosure policy, and no third-party audit signal.
  • MPL-2.0 is file-level copyleft. Consuming it unmodified as a dependency is generally acceptable for commercial use, but any patches we apply to package files must be released under MPL — this needs a legal sign-off, and it raises friction if we need to fork to patch.
  • Bus factor of one. Abandonment risk is the default assumption for packages at this adoption level.
  • Redundancy risk: the framework may render the package obsolete on our next major upgrade, stranding a dependency we no longer need.

Key questions.

  1. What Laravel/PHP versions are supported, and does the package work on our current target and the next major?
  2. Does it generate ordered UUIDs (v7/sequential) or random v4? This materially changes index behavior at scale.
  3. Does it handle ULID storage portably (CHAR(26) vs. native uuid/binary(16) on Postgres/MySQL)?
  4. Are IDs assigned on the creating event only — i.e., does DB::table()->insert(), bulk insert, or insertOrIgnore bypass generation entirely?
  5. What is the maintainer's stated support commitment, and is there a documented security contact?
  6. Does the native HasUuids/HasUlids trait already satisfy the requirement? If yes, this evaluation terminates with a "no adopt."

Integration Approach

Recommendation. Default to framework-native traits on Laravel 9+. Adopt this package only if we are pinned to Laravel 8 or earlier and need ULID support that the framework does not provide, or if we need a uniform trait interface across a mixed-version fleet. In either case, treat it as a thin, pinned, vendorable utility — not a strategic dependency.

Stack fit. Fits all standard Laravel deployments (MySQL, PostgreSQL, SQLite). Two fit considerations drive real work:

  • Storage type. ULIDs as CHAR(26) are compact; UUIDs as CHAR(36) are not. On PostgreSQL prefer native uuid; on MySQL 8 prefer BINARY(16) with uuid_to_bin/bin_to_uuid conversion, or accept CHAR(36) and budget the index growth. Confirm the package is agnostic here — it almost certainly delegates storage decisions to our migrations, which means the decision is ours, not the package's.
  • Ordering. Insist on time-ordered identifiers (ULID or UUIDv7). Random v4 primary keys fragment InnoDB clustered indexes and inflate write amplification on high-insert tables.

Migration path. Do not attempt an in-place PK swap on existing tables. Use an expand/contract sequence:

  1. Add a new nullable uuid/ulid column with a unique index alongside the existing integer PK.
  2. Dual-write via a model observer or trait so new rows populate both keys; backfill historical rows in batches.
  3. Repoint route-model-binding (getRouteKeyName) and API serialization to the new column.
  4. Optionally promote the new column to PK in a later, separate change — or leave the integer PK in place and expose only the opaque key externally. This last option captures most of the benefit at a fraction of the risk and is the recommended default.

Tables with high foreign-key fan-in (users, accounts, tenants) should be last, or never converted.

Compatibility. Audit for integer-key assumptions before writing any code: Filament/Nova resources, Spatie packages, queue payload serialization, cache keys, analytics/warehouse ingestion, mobile clients parsing IDs as int, and any raw SQL with whereIn('id', [...]) on untyped values. Also confirm Model::find() callers tolerate string keys and that json responses change shape — this is a breaking API change, not an internal refactor.

Sequencing.

  1. Spike: one greenfield, low-traffic table, one engineer, one sprint. Validate trait behavior, bulk-insert gaps, and serialization.
  2. Legal review of MPL-2.0 obligations.
  3. Pin the exact version and composer.lock-freeze; vendor or mirror the source internally.
  4. Roll the pattern to new tables only; hold existing-table conversions until the spike yields evidence.
  5. Re-evaluate against native traits at the next Laravel major upgrade.

Operational Impact

Maintenance. Near-zero day-to-day effort once integrated — it is a small, stable concern. The real maintenance burden is upstream risk: no committed maintainer, no release cadence guarantees, and a plausible abandonment horizon. Mitigate by pinning the version, mirroring the repository internally, and treating an in-house fork (MPL-permitted, with license retention) as a pre-approved contingency. Budget roughly half a day per Laravel major upgrade to verify the trait still composes with framework changes to getKeyType/getIncrementing.

Support. Community-only, effectively self-support. There is no SLA, no vendor, and at 0 stars, no meaningful pool of prior adopters to draw incident experience from. Any production issue is ours to diagnose. This is acceptable for a utility of this size and unacceptable if ID generation ever becomes load-bearing for correctness across many services.

Scaling. Identifier choice, not the package, determines scaling characteristics:

  • Ordered ULIDs/UUIDv7 keep B-tree inserts append-heavy and index-friendly at high write volume.
  • Random UUIDv4 on a clustered index causes page splits and cache churn — avoid on high-insert tables.
  • Storage: CHAR(36) UUIDs are ~2–4× the index footprint of BIGINT; on tables in the hundreds of millions of rows this is a real capacity and memory decision. Use BINARY(16) or native uuid types where the database supports them.
  • Join performance degrades measurably with string keys on large fact tables — keep integer keys on high-volume internal/join tables and expose opaque IDs only at the API boundary.

Failure modes.

  • Bypassed generation. Bulk insert() / upsert() / raw SQL skip model events, producing rows with null or empty keys. Highest-probability real defect; add a DB-level NOT NULL and unique constraint so it fails loudly.
  • Mixed key types post-migration, causing silent whereKey mismatches and 404s in route binding.
  • Serialization drift — IDs flipping from int to string in JSON breaks typed clients, mobile apps, and downstream consumers.
  • Collision — cryptographically negligible for ULID/UUID; not a practical concern, though worth a one-line note in the ADR.
  • Third-party package incompatibility — some ecosystem packages assume integer keys; failure is usually a type error at runtime, not a silent data issue.
  • Abandonment — no upstream fix path for a future framework incompatibility; the fork contingency is the mitigation.

Ramp-up. Engineering ramp-up is minimal — one trait line, one line in the model. The organizational ramp-up is the actual cost: the team must internalize why an opaque key is being exposed, how route binding resolves it, why bulk operations need explicit ID assignment, and why integer keys may still exist internally. Plan a short design note and one working session; schedule the migration work as a distinct epic rather than an incidental refactor, because the schema and API blast radius dwarfs the integration effort.

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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast