ijeffro/laravel-airports
Laravel Airports provides IATA codes, ISO 3166-3 and country codes for airports, plus a service provider, facade, migration and seeder to populate an airports table. Install via Composer, publish config, migrate and seed for searchable airport data.
Architecture fit. The package is a single-responsibility reference-data bundle: a service provider, a facade over an in-memory PHP array of IATA records, an optional Eloquent model/migration/seeder, a validation rule, and two Artisan commands. It follows idiomatic Laravel packaging (auto-discovery, publishable tags, readonly value objects) and sits in the "domain primitives" layer rather than the request/response layer. That makes it a good fit for any product with airport pickers, itinerary imports, autocomplete endpoints, or travel-partner integrations — the lookup surface (find, findOrFail, exists, inCountry, search, options) covers most of the workflows a TPM would scope. It is not a geospatial engine, a fare/route service, or an airline database; scoping expectations accordingly matters.
Integration feasibility. Technically low-effort: composer require, auto-discovery, and a working in-memory lookup on a fresh install with no migration. Realistically the effort is concentrated in identification, not integration. The package presents as two identities — the ijeffro/laravel-airports metadata and README (Laravel 5, dev-master, manual provider registration) versus the v1.0.0 release notes and namespace FLAIRUK\Airports (Laravel 12/13, PHP 8.2+). A TPM should treat "confirm the canonical Packagist name, version, and FQCN" as an explicit, time-boxed spike task before any sprint commitment.
Technical risk.
airports table can drift; reseeding is idempotent but may overwrite locally curated rows.Key questions.
composer.json?Stack fit. Only viable for Laravel 12/13 on PHP 8.2+. For anything older, the correct decision is usually not to adopt this package — either stay pinned to the unmaintained 0.x line or vendor a trimmed airport list directly. Confirm no transitive constraint conflicts, then treat adoption as greenfield.
Migration path. There is no migration path, only a replacement path. Plan it as a call-site audit: grep for legacy idioms (getByIata, getByName, whereCountry, pluck, ->merge(, array offsets like $airport['iata']), remove the old provider and Airports alias from config/app.php, then composer dump-autoload and clear config/cache so a cached bootstrap/cache/config.php doesn't produce phantom "class not found" errors. Budget this as real work; it is the largest line item in the plan.
Compatibility. Three compatibility surfaces to verify rather than assume: Laravel/PHP version ceilings against the rest of the dependency graph; Octane and queue workers (the array loads per process — measure before scaling worker counts); and the optional database path, where the published migration's column list must be validated against any belongsTo foreign keys we define. Sparse records (null city/region/coordinates) require null-safe rendering in every Blade and API resource.
Sequencing.
find, exists, AirportCode, and the commands in a throwaway app. Timebox and require a written artifact.exists:airports,iata for AirportCode and one autocomplete endpoint for search(). No database, no migration.strtoupper(trim()) helper or form request, applied consistently — cheap now, painful later.Maintenance. This is a low-churn dependency with a high-ownership burden. The code is unlikely to break often; the data and the fork identity are the maintenance surface. Pin an exact version, and assume we — not upstream — will handle dataset refreshes, namespace questions, and doc corrections. Budget a small recurring review, not a large one.
Support. Effectively self-support: one maintainer, four stars, no dependents, and a README that describes a different package than the one shipping. Do not plan on upstream responsiveness for blockers. Internal documentation capturing the verified package name, FQCN, supported versions, and the source-of-truth decision is not optional — it is the support plan.
Scaling. Adequate for typical php-fpm workloads. Two scaling notes for the roadmap: avoid json_encode-ing the full options() payload into every page (filter server-side by country or term, cap search() results, cache only serialized large API responses), and measure memory per process before scaling Octane workers or queue concurrency. Geospatial proximity is fine in PHP for small candidate sets; push to SQL only with the published table and indexes.
Failure modes.
composer update; mitigated by cache-clear in the release checklist.Airports::exists() in tinker.airports:seed succeeding while local curations are overwritten, or exists:airports,iata failing on a fresh install where the table was never published.find() returning null and sparse records rendering blanks; enforce findOrFail in imports and null-safe accessors in views.Ramp-up. Low for any Laravel developer — an afternoon to a working pilot, with the README's inconsistencies as the only real speed bump. The hidden ramp is organizational: the call-site audit for 0.x consumers, the source-of-truth decision, and the dataset-governance stance. Those are TPM-owned decisions, not engineering trivia, and should be resolved before the package is promoted beyond a pilot.
How can I help you explore Laravel packages today?