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

Device Detector Laravel Package

matomo/device-detector

Universal device detection library that parses User Agents and Browser Client Hints to identify devices (desktop, tablet, mobile, TV, console), browsers and other clients, operating systems, brands, and models.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • This is a single-purpose, framework-agnostic library: instantiate DeviceDetector with a UA string plus optional ClientHints, call parse(), read normalized accessors (isBot(), getClient(), getOs(), getDeviceName(), getBrandName(), getModel()). It is a pure in-process dependency with no service, no network hop, and no schema of its own — it slots cleanly underneath any Laravel service layer without dictating architecture.
  • It is not a Laravel package in the first-party sense (no auto-discovered provider, no config file, no facade). A TPM should budget a thin internal wrapper — provider binding, config, facade or typed helper, and a value object — rather than letting new DeviceDetector(...) leak across controllers and jobs.
  • Fit is strongest where the product already stores or forwards UA strings: analytics/telemetry, bot mitigation, adaptive rendering, audit logs, marketing attribution, fraud/abuse signals, and session fingerprint enrichment.

Integration feasibility

  • Composer-only install, PSR-4 autoloaded, no PHP extensions strictly required (a YAML parser is: bundled-default Spyc, with Symfony YAML and PECL yaml as opt-ins). Laravel's Symfony dependency set makes DeviceDetector\Yaml\Symfony the pragmatic choice.
  • A first-party DeviceDetector\Cache\LaravelCache bridge exists, plus PSR-6/PSR-16/Doctrine bridges — this is the single most important integration lever, since the default cache is per-process only and therefore near-useless under PHP-FPM.
  • Low integration cost: realistically 1–3 engineer-days for provider + config + middleware + cached wrapper + tests, before any product surface work.

Technical risk

  • Heuristic accuracy, not ground truth. Detection is regex/YAML rule matching over a spoofable, increasingly frozen header (UA reduction in Chrome/Safari/Edge). Client Hints materially improve accuracy but require the server to advertise Accept-CH/Permissions-Policy — meaning hints arrive only from the second request onward. Any feature that hard-depends on exact model/brand will be partially wrong in production; treat output as a probability signal, not identity.
  • Input is attacker-controlled. Unbounded UA strings hitting thousands of regexes is a ReDoS/memory surface. Mandate an input length cap and a normalization step before parsing; do not pass raw headers straight through.
  • License. LGPL-3.0-or-later. Fine for ordinary use as an unmodified dependency, but it is copyleft-adjacent — legal should confirm the position, particularly if code is redistributed, bundled into a shipped binary/app, or the regex data is forked and modified.
  • Metadata quality flag. The supplied repository URL points at the Matomo core monorepo rather than the standalone matomo-org/device-detector repository, stars are blank, and "Dependents: 0" contradicts the Packagist download volume. This is almost certainly ingestion error, not a real signal — but confirm the canonical repo and release tags before locking a version policy. The 9.6 score with a 55.25 opportunity score reads as "low-risk utility, not a differentiator" — consistent with the assessment above.

Key questions

  • What decision does detection actually change — routing, pricing, fraud score, content variant, or just analytics segmentation? If it only feeds reporting, cache and accuracy requirements drop sharply.
  • Do we need brand/model granularity, or only device class (mobile/tablet/desktop/bot)? Restricting to the cheap checks (isBot(), isMobile(), coarse device type) avoids most accuracy and performance risk.
  • Are we willing to send Accept-CH and store Client Hints? Without them, modern Safari/Firefox traffic is materially less precise.
  • What is the acceptable false-positive rate on bot detection, given it gates access or blocks traffic?
  • Will parsed attributes be persisted, or derived per request? Persistence raises retention/privacy obligations.

Integration Approach

Stack fit

  • Laravel 9/10/11 on PHP 8.x: no compatibility concerns; the library is actively CI-tested across modern PHP.
  • Choose the Symfony YAML parser (already in the dependency graph) over Spyc and set version truncation explicitly at bootstrap — the default truncates to X.Y, which silently breaks any feature expecting full version comparison.
  • Bind a single configured detector factory as a singleton; inject per-request through a scoped wrapper so the parsed result is memoized once per request rather than re-parsed in each view/controller.

Migration path

  • If the estate currently uses jenssegers/agent / mobile-detect (the common Laravel default), plan a parallel-run migration: implement an internal DeviceContext interface, back it with device-detector, and keep the old adapter behind a config flag for one release cycle. Compare outputs on sampled traffic before cutover.
  • The library's cache-bridge design means you can swap the backing store (array → Laravel cache → Redis) without touching call sites, so start with array/file in dev and Redis in production without code churn.
  • For existing stored UA strings, treat backfill as an offline batch job (queued, chunked, rate-limited) writing into new nullable columns — never a synchronous migration.

Compatibility

  • Cache bridge requires the Laravel cache contract; confirm the Redis store is shared across the fleet, or each pod warms independently (cold-start latency on deploy).
  • The ClientHints::factory($_SERVER) signature is superglobal-based; in Laravel use $request->server()/header accessors instead, and add a response middleware to emit Accept-CH so hints populate on subsequent requests. Sequence this before any accuracy-sensitive feature ships.
  • Pin a minor version range and treat regex-database updates as a deliberate upgrade, not an automatic composer update side effect.

Sequencing

  1. Spike: parse a sampled corpus of real production UA strings; measure device-class accuracy against a hand-labelled set (~500–1,000 rows) and record a baseline.
  2. Ship the provider + config + cached DeviceContext wrapper + facade, with unit tests over a fixed UA fixture set.
  3. Add the Accept-CH response middleware and start capturing hints (cheap, reversible, improves everything downstream).
  4. Introduce read-only consumers first — analytics dimensions, admin reporting, log enrichment. No gating behavior.
  5. Only then layer decisioning: bot filtering, adaptive rendering, or adaptive pricing, each behind a feature flag with a rollback to the pre-existing path.
  6. Backfill historical records asynchronously; publish an accuracy dashboard alongside.

Operational Impact

Maintenance

  • The library ships a bundled regex/YAML database that decays. Browser and device churn means an 12–18-month-old pin will visibly misclassify new devices. Budget a quarterly upgrade ritual: bump version, replay the golden UA corpus, diff results, ship if the regression delta is acceptable. This is the dominant ongoing cost and it needs an owner.
  • Upstream is Matomo-team-maintained with an active release cadence and CI gates (PHPUnit, PHPStan, PHPCS, regex validation) — low abandonment risk. Do not fork.

Support

  • Community support via GitHub issues; no vendor SLA. Acceptable for non-critical enrichment; unsuitable as the sole control for security decisions without an internal fallback.
  • Internal support burden is low if the wrapper is disciplined — one place to upgrade, one place to instrument. It rises sharply if the raw library is called from many call sites.

Scaling

  • Cold parse is a few milliseconds; cached lookups are sub-millisecond. On high-QPS traffic the cache is not optional — without it you pay full regex cost on every request.
  • Cache key should be a hash of UA + relevant hint values, with a TTL bounded by the library version so upgrades invalidate naturally. Watch Redis memory: UA cardinality in the long tail is high (bots, scrapers), so set a max size or a short TTL for low-frequency keys.
  • Memory per parse is modest, but the loaded rule sets are non-trivial; avoid holding many detector instances alive in a single long-running worker, and be careful in Octane/Swoole where the "static cache" persists across requests and can grow unboundedly — reset or bound it explicitly.

Failure modes

  • Pathological or oversized UA strings causing regex backtracking or memory spikes — mitigate with a hard input length cap and a timeout guard around parsing.
  • Missing or stale cache producing latency spikes on deploy (cold caches across all pods simultaneously) — pre-warm or stagger rollouts.
  • Silent accuracy regressions after an upgrade — mitigate with the golden-corpus diff gate in CI.
  • Hint absence mistaken for hint values: features that assume Client Hints exist will degrade for the first request of every session, and permanently for clients that ignore Accept-CH.
  • Privacy/compliance: UA + IP + hints is a fingerprinting vector. Persisted parsed attributes can constitute personal data; confirm retention windows, consent posture, and that detection results are not used to re-identify opted-out users.

Ramp-up

  • Very low for any PHP developer: an hour with the README produces a working parse. The real ramp is institutional, not individual — establishing the accuracy baseline, the upgrade ritual, and the caching discipline. A TPM should own those three artifacts from day one, since they are what separates a useful signal from a quietly degrading one.
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.
marcelgwerder/laravel-api-handler
firebrikdotcom/conveyor-laravel-broadcaster
kanata-php/conveyor-laravel-broadcaster
alish/short-message
sonrac/lumen-league-oauth2
pushery/sanctum-hardening-for-laravel
evanschleret/laravel-uuidable
yigit-serin/laravel-openvidu
adachsoft/command-executor-lib
tagixo/document-builder
tagixo/page-builder
tagixo/mail-builder
tagixo/form-builder
primix/primix
tagixo/core
alesima/laravel-azure-service-bus
tomshaw/shopcart
likyly/laravel
darthsoup/shoppingcart
tdt/core