hibit-dev/geodetect
Laravel package for detecting a visitor’s location from their IP address. GeoDetect offers configurable geolocation drivers, caching, and a simple API for resolving country, region, and city data in your application.
Architecture fit. hibit-dev/geodetect is a conventional Laravel package: auto-discovered service provider, publishable config, facade/helper surface, and (based on the description) a driver-based resolver that returns country/city/coordinates for the current request's IP. That shape fits cleanly into standard Laravel layering — resolution happens in the service container, and consumption happens in middleware, form requests, or a Blade/API presenter. It does not impose architectural opinions, which is both its virtue and its weakness: it will not fight your codebase, but it also will not give you a domain model for geography.
Integration feasibility. Mechanically trivial: composer require, php artisan vendor:publish, set a driver plus credentials in .env, optionally register middleware. Expect a half-day spike to a working prototype in a single-tenant app. The real cost is not installation but the decisions around it — driver selection, caching, privacy posture, and fallback behavior.
Technical risk.
.mmdb file must be refreshed on a schedule to stay accurate.Key questions to put to the maintainer / README / source before committing.
null, or a configurable default? Silent null requires every consumer to handle absence.Request::ip() and honor TrustProxies, or does it read REMOTE_ADDR directly? The latter breaks behind a CDN/ALB.Stack fit. Well-matched to a Laravel monolith or a small number of Laravel services. It is a poor fit for a polyglot estate or a service mesh where geo resolution should live in an edge/CDN layer or a shared internal service — in those topologies, wrapping a PHP package per service creates N copies of the same config, credentials, and cache.
Migration path. There is nothing to migrate from: zero dependents and no incumbent means this is a greenfield insertion, not a replacement. The deliberate move is to insert it behind your own seam — define a GeoResolver interface in your domain and implement it with this package. That costs ~50 lines and buys you a one-afternoon swap to geoip2/geoip2 directly, or to a CDN header (CF-IPCountry, CloudFront-Viewer-Country), if the package stalls. Given the maturity signals, I would not let vendor types leak into controllers or models.
Compatibility. Confirm three things before the spike: the Laravel/PHP constraint range against your runtime, collision risk with any existing geo package (torann/geoip, stevebauman/location) already in composer.lock, and whether the config publishes cleanly into a config-cached production build (php artisan config:cache is where facades reading env() at runtime commonly break).
Sequencing.
Accept-Language → app default) and make it the same everywhere.Maintenance. Assume you are the maintainer of last resort. At 23 stars the community is not going to triage your issue. Pin the version in composer.json, avoid dev-main, and budget a few hours per quarter to (a) refresh the geolocation database or re-verify the API contract, and (b) confirm the package still installs against your current Laravel. If it goes quiet, the fork-and-own path is realistic given the small surface area — which is another argument for keeping the integration thin.
Support. No SLA, no vendor, community issues only. Escalation path is "read the source," which is viable here only because the package is small. Do not put it on a path where a support ticket depends on upstream response time.
Scaling. The cost profile is entirely determined by caching. A local .mmdb lookup is effectively a memory-mapped read — cheap, no network, no quota — and scales horizontally without coordination. An HTTP-API driver puts a 50–200 ms network call on the request path, exposes you to rate limits and per-lookup billing, and turns your third-party provider into a hard dependency for every page view. Either way: cache by IP, set an explicit TTL, use a shared store (Redis) rather than per-process memory so the hit rate survives autoscaling, and never resolve geo inside a loop over historical records without batching. Also verify TrustProxies is configured — otherwise every request behind your load balancer resolves to the balancer's IP and you will ship the same country to all users while the dashboards look fine.
Failure modes to design for explicitly.
X-Forwarded-For unconditionally, a client can choose its own country. Only acceptable where geo drives cosmetic personalization, never entitlement.Ramp-up. Low for a mid-level Laravel developer — an afternoon to install, configure, and read the source. The engineering judgment required is not in the package: it is in the caching layer, the proxy/IP-source correctness, the privacy posture, and the fallback policy. Those are the items that will actually consume sprint capacity, and they are the same regardless of which geo library you pick. Frame the adoption decision accordingly: the package is a cheap, low-commitment way to validate that you need geo detection at all, and the wrapping seam is what keeps that validation reversible.
How can I help you explore Laravel packages today?