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

Hashid Bundle Laravel Package

pgs-soft/hashid-bundle

Symfony bundle that integrates Hashids to encode and decode numeric IDs, helping obfuscate database identifiers in URLs. Provides a configurable service and Twig filters for generating short, unique hashes in templates and routes, with simple bundle configuration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The first thing to flag is a naming mismatch: pgs-soft/hashid-bundle is a Symfony bundle, not a Laravel package. There is no ServiceProvider, no config/hashid.php publishable config, and no Laravel facade. In a Laravel codebase this package cannot be dropped in as-is; it would need a thin adapter (service provider + config + facade) around the underlying hashids/hashids library. The underlying library itself is framework-agnostic, PSR-friendly, and trivial to wire into Laravel's container, so the capability fits a Laravel stack well even though the package does not.

Integration feasibility. High, if we treat the bundle as a reference implementation rather than a dependency. The bundle is essentially a DI wrapper, a Twig extension, and a route-parameter converter around hashids/hashids. In Laravel the equivalent work is: bind a singleton hasher in a service provider, add a Hashid cast or route-binding resolver, and override getRouteKey()/resolveRouteBinding() on affected models. That is roughly 1–3 days of work for a competent engineer, most of it spent on tests and URL-generation audit rather than the hashing itself.

Technical risk.

  • Security semantics are frequently misunderstood. Hashids is obfuscation, not encryption. It is symmetric and reversible with the salt. Anyone who obtains the salt (leaked .env, repo history, logs, error pages) can enumerate every ID. This must not be positioned as an access-control or anti-IDOR control; authorization must remain server-side.
  • Maintenance/bus factor. 13 stars, 0 dependents, last release April 2023, effectively a single-maintainer project. The Symfony bundle is the thinnest part of the stack; the transitive dependency hashids/hashids is the real long-term surface and should be assessed separately (it is more established but still low-velocity).
  • Salt lifecycle is the real operational hazard. Rotating the salt invalidates every previously issued URL — bookmarks, emails, sitemaps, partner integrations, and any cached pages. There is no migration path except keeping the old salt alive for a dual-verify window.
  • Entropy/collision trade-offs. Minimum hash length, alphabet, and salt determine collision probability. Defaults are usually fine for internal IDs but should be explicitly set and tested, not left implicit.
  • Integer range. Large BIGINT IDs (beyond 2^53) and 32-bit PHP builds are a real edge case; verify against the largest ID we expect in each table.
  • Licensing. MIT — no legal blocker, and vendoring/forking is explicitly permitted, which materially de-risks the low-maintenance concern.

Key questions.

  1. Is the requirement cosmetic (nicer URLs, hide sequential IDs), anti-enumeration (raise cost of scraping), or compliance-driven? Only the first two are legitimately served by Hashids.
  2. What is the threat model, and does it already require signed URLs (URL::signedRoute) or UUID/ULID primary keys instead?
  3. Is the salt permitted to live in an env var / secret manager, and who owns rotation?
  4. Which entities and routes are in scope — a bounded set (invoices, users, orders) or "all integer params"?
  5. Are there external consumers (partners, emails, sitemaps, mobile deep links) whose URLs we would break?
  6. Do we need decode-on-read for inbound links, or is generation only sufficient?
  7. Given 0 dependents and last release 2023, are we prepared to fork and own a ~300-line library?

Integration Approach

Stack fit. Poor as a package, good as a pattern. Recommendation: do not install the Symfony bundle in a Laravel app. Instead, depend on hashids/hashids directly and implement a small in-house HashidService plus a route-binding trait. If the team is actually on Symfony, the bundle is a reasonable convenience wrapper, but with 13 stars and stale releases the same fork-and-own calculus applies.

Migration path.

  1. Spike (1–2 days). Prove out hashing/unhashing, min-length, salt handling, and Laravel route-model binding in a branch. Confirm behavior for BIGINT-scale IDs.
  2. Introduce the service layer. HashidService::encode() / ::decode(), bound as a singleton, config in config/hashid.php, salt from env. No route changes yet.
  3. Add a HasHashidRouteKey trait applied per model (not globally — blast radius matters). Override getRouteKey() and resolveRouteBinding(); keep integer resolution as a fallback so inbound integer URLs continue to work during transition.
  4. Sweep URL generation. Every route() call, url(), Blade link, API resource, email template, sitemap generator, and PDF export that embeds a model ID. This is the largest and least glamorous work item; budget accordingly.
  5. Dual-read window. Accept both legacy integer and new hashed params for at least one release cycle, with 301 redirects from integer URLs to hashed ones to consolidate SEO and preserve old links.
  6. Remove fallback. Only after logs show negligible integer traffic.

Compatibility.

  • Pin PHP and Laravel version constraints explicitly; the bundle's 2023-era composer.json will not know about current Laravel releases, and even the underlying library has had major-version naming churn (Hashids vs Hashids\Hashids).
  • Test against the oldest and newest framework versions in the support matrix.
  • If we keep the Symfony bundle in a Symfony service, verify its DI compiler pass against the current Symfony minor — config semantics changed across 5.x/6.x/7.x.

Sequencing. Salt/config and service first → per-model trait → URL generation sweep → dual-read + redirects → fallback removal. Keep it behind a feature flag per entity so a single bad model doesn't take down checkout or auth flows. Do the sweep before enabling generation, not after — otherwise you ship half-hashed, half-integer URLs and break nothing visibly until a customer clicks a bookmark.

Operational Impact

Maintenance. We will effectively own this code. With 0 dependents and a 2023 last release, upstream responsiveness is not something to plan around. MIT allows vendoring; vendoring a ~300-line library into app/Support (or an internal Composer package with a replace) removes the supply-chain question entirely and costs us nothing but a composer update. Treat the underlying hashids/hashids dependency as the thing to watch, not the Symfony wrapper.

Support. Community-only, no SLA, no vendor. Internal ownership is the only realistic support model. Document the salt, the alphabet, the min-length, and — critically — the reversibility property in the runbook so no one later mistakes this for a security boundary during a threat model review or a pen test debrief.

Scaling. Negligible compute cost — Hashids is a cheap arithmetic/string transform, microseconds per call, no I/O, no external service. It scales linearly with app servers and is safely cacheable. The scaling risk is not CPU; it is URL cardinality and cache-key churn: every cached page, CDN entry, and search index entry keyed by URL becomes tied to a salt that we may need to rotate. If the app is heavily cache-keyed on URLs, salt rotation becomes a cache-invalidation event, not just a link-breaking event.

Failure modes.

  • Salt rotation / leak remediation → all previously issued URLs 404. Mitigation: dual-salt verification window, redirect map, and a documented rotation runbook.
  • Salt missing or default in production → hashes are trivially reproducible; silent and dangerous. Mitigation: fail-fast config validation at boot.
  • Min-length or alphabet change → same class of breakage as salt rotation, but easier to do accidentally via config drift. Mitigation: change control on the config file and a startup assertion.
  • decode() on malformed input → returns empty array; naive code that assumes $decoded[0] will throw or, worse, silently bind to ID 0/null. Mitigation: always guard, and return 404 on decode failure.
  • Enumeration still possible → sequential hashes are still sequential-looking to the trained eye and trivially decodable if the salt leaks. This is a perception control only; authorization checks must remain the actual control.
  • Broken external links → partner integrations, emailed receipts, and sitemaps silently degrade. Mitigation: dual-read window plus monitoring on 404s with decode failures.

Ramp-up. Low for the hashing itself; the real onboarding cost is organizational. Engineers need roughly half a day to learn the library and the trait, and then a recurring reminder in code review that Hashids ≠ encryption. The riskiest ramp-up failure is a well-meaning engineer "improving security" by using the hash as an authorization token. Given the low package score (1.59) and zero dependents, I would not adopt the Symfony bundle directly, but the pattern is cheap, reversible, and worth the opportunity score of 4.41 if and only if the requirement is genuinely cosmetic or anti-scraping — and if the team is prepared to own a small vendored utility rather than depend on a dormant third-party bundle.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
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