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

Laravel Geoly Laravel Package

akuechler/laravel-geoly

Laravel GeoLy adds geospatial querying to Eloquent, letting you store coordinates and run distance-based searches, radius filters, and nearby lookups directly in your models without extra services.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. laravel-geoly is a trait-plus-Eloquent-scope package: it adds a withinRadius-style query scope to any model carrying latitude/longitude columns. Architecturally this is the lowest-friction shape a Laravel package can take — no service container bindings to reason about, no external geo service, no queue or event surface, and no schema ownership beyond two columns. It computes a bounding-box prefilter in SQL and then applies a haversine distance calculation for exact filtering/ordering. That means it stays entirely inside the application's existing database connection: no PostGIS extension, no Redis GEO, no third-party API, no new network hop on the read path. For a Laravel monolith with moderate geo needs (store locators, "near me" listings, delivery-radius checks, marketplace search), this is a proportionate fit. It is not a fit if geo search is a core product differentiator requiring polygon queries, routing, or sub-100ms p95 at high query volume.

Integration feasibility. High on a technical level, low on a supply-chain level. The code surface is small enough that a competent Laravel engineer can read the whole package in an hour and fork it if needed, so lock-in is negligible — the real cost is the evaluation cost, not the adoption cost. The 2021-04-20 last release and 41 stars are the material findings: at the time of writing this almost certainly predates Laravel 9/10/11 service-provider conventions and PHP 8.2+ deprecations, so the composer.json constraint (illuminate/support, php) will likely block installation on a current stack before any code-level incompatibility surfaces. Budget a half-day spike to confirm whether it installs cleanly or requires a fork with relaxed constraints.

Technical risk. Three buckets:

  • Staleness risk (high, but bounded). No upstream security patching, no Laravel-version tracking, near-zero community. Mitigated cheaply because the dependency tree is thin and the logic is a few hundred lines — you are really adopting a code snippet, not a platform.
  • Correctness risk (medium). Haversine implementations typically carry a hardcoded earth radius (6371 km vs 3959 mi) — unit mismatches are a classic silent bug. Bounding-box prefilters classically break at the antimeridian (±180° longitude) and near the poles, and can silently return fewer rows than expected. Float/decimal precision on lat/lng columns affects edge-of-radius inclusion. None of these are hard to fix, but they need explicit tests.
  • Performance risk (medium, data-dependent). The bounding box is only fast if a composite index on (latitude, longitude) exists. Without it you get a full table scan with trig functions in the WHERE clause — a query that passes in staging and times out in production.

Key questions for the spike.

  1. What are the exact composer.json constraints on PHP and illuminate/*, and does it install on our target Laravel version without --ignore-platform-reqs?
  2. Does it ship a migration, or do we own the lat/lng columns and index ourselves?
  3. Which database drivers are exercised — is the SQL haversine written portably (MySQL vs. PostgreSQL vs. SQLite math-function availability)?
  4. Does the scope return distance as a selectable/orderable column, and does it compose with pagination and existing scopes?
  5. Does the bounding box degrade correctly at the antimeridian and near-polar latitudes?
  6. Is the radius unit configurable, and what earth-radius constant is used?

Integration Approach

Stack fit. Appropriate for Laravel 8-era or earlier applications with MySQL/PostgreSQL and read-heavy, low-to-moderate-QPS geo filtering. Assume it is not supported on our current Laravel version until the spike proves otherwise. It is a poor fit for multi-tenant databases with per-tenant sharding, for read models backed by Elasticsearch/Algolia (those have native geo), or anywhere we already run PostGIS — in those cases the package duplicates capability we already pay for.

Migration path. Two viable routes, decided by the spike:

  • Adopt (if it installs cleanly): composer require, add decimal(10,7)/(10,8) columns, backfill coordinates through our existing geocoder in batched jobs, add a composite (latitude, longitude) index, add the trait, and wrap the scope in a repository/service method so the package is callable from exactly one place. That single choke point is the whole point: it makes the eventual build-vs-fork-vs-replace decision a one-file change.
  • Fork (default assumption): vendor the package under our namespace (or a VCS repository entry in composer.json), relax the framework/PHP constraints, add a test suite covering the correctness risks above, and publish it internally. Cost is roughly 1–2 engineer-days including tests — still cheaper than writing haversine logic from scratch, but not by much, which is the honest framing to give stakeholders.

Compatibility. Verify against our actual stack matrix rather than the package's declared one: PHP version, Laravel version, and database engine. SQLite-backed test suites are a specific trap — SQLite only exposes RADIANS/COS/SIN when built with math-function support, so a passing CI suite on SQLite does not validate production behaviour on MySQL/PostgreSQL. Run correctness tests against a containerised copy of the production engine.

Sequencing.

  1. Spike (0.5 day): install attempt, read the source, answer the six questions.
  2. Benchmark (0.5 day): seed ~1M synthetic rows, measure query time with and without the composite index, and record the radius at which performance degrades.
  3. Decide: adopt / fork / build-in-house (a hand-rolled scope is ~50 lines and may win once fork cost is on the table).
  4. Implement behind an interface, backfill data, add integration tests, ship behind a feature flag.

Do not sequence this behind a geo-dependent product launch; the dependency's staleness makes it a schedule risk.

Operational Impact

Maintenance. Effectively zero upstream maintenance — plan for us to be the maintainers. The upside is that the maintenance burden is small: one trait, one scope, no runtime services. Assign clear internal ownership and pin the version (or the fork's commit SHA) so an accidental composer update cannot silently change query semantics. Add it to the quarterly dependency-review list with a standing "fork is current" check.

Support. No vendor, no SLA, minimal community (41 stars implies few answered issues and little Stack Overflow coverage). Internal documentation is mandatory: unit conventions, the earth-radius constant, supported database engines, and the known antimeridian limitation should live in an ADR, not in someone's head. Expect onboarding engineers to ask "why do we have this tiny unmaintained package?" — the ADR answers that.

Scaling. The bounding-box-plus-index approach scales comfortably to low millions of rows for typical radii, which covers most product needs. It does not scale to full-table geo search: once the bounding box filters a large fraction of the table (very large radius, or a dense urban dataset), you are back to a scan with trig functions in the predicate. It also has no caching layer — callers must add response caching themselves. At high query volume or when geo becomes a discovery surface rather than a filter, the migration target is PostGIS or a search engine with native geo (Meilisearch, Algolia, Elasticsearch), not a bigger version of this package. Design the service-layer wrapper now so that swap stays cheap.

Failure modes. Ranked by likelihood × impact:

  • Composer constraint blocks a framework upgrade (likely) — the package becomes the reason a Laravel upgrade stalls. Mitigate by forking early rather than at upgrade time.
  • Missing composite index causes table scans and query timeouts under load (likely if not explicitly handled) — make the index part of the migration, not a README note.
  • Silent under-return at the antimeridian / high latitudes (moderate) — surfaces as "the store exists but search doesn't find it," which is hard to reproduce and expensive to debug in support.
  • Unit or earth-radius mismatch (moderate) — returns plausible-but-wrong radii; catchable with a fixed-fixture test asserting known distances.
  • SQLite-only CI passes while production DB fails (moderate) — test on the production engine.
  • Abandonment with no successor (certain, already true) — accepted risk, priced in by the fork decision.

Ramp-up. Very low for any Laravel developer: one trait, one scope, roughly an hour to productive use once the ADR and tests exist. The ramp-up cost sits with the first engineer, who must do the evaluation, fork, and test work — estimate 1–2 days. After that the package is invisible infrastructure.

TPM recommendation. Proceed to spike, with the default expectation of adopting the code via an internal fork rather than consuming the upstream release. The package's low score reflects stewardship, not engineering quality, and the blast radius of that poor stewardship is unusually small here because the code is trivially replaceable. Gate full adoption on the benchmark and the correctness tests, and require the service-layer wrapper so the decision remains reversible.

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.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr