aaix/laravel-countries

A modern Laravel country-data package: idempotent seeders, zero-touch install, no interactive commands. Opinionated fork of lwwcas/laravel-countries.

Maintainers

Package info

github.com/jonaaix/laravel-countries

pkg:composer/aaix/laravel-countries

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.3 2026-04-24 20:05 UTC

This package is auto-updated.

Last update: 2026-04-24 20:07:58 UTC


README

Laravel Countries Logo

Laravel Countries

A modern Laravel country-data package — idempotent seeders, zero-touch install, ergonomic API.

Opinionated fork of lwwcas/laravel-countries.

Latest Version on Packagist Total Downloads GitHub Actions License

Install

composer require aaix/laravel-countries
php artisan migrate

Migrations load automatically via the package service provider.

Seed

php artisan db:seed --class="Aaix\\LaravelCountries\\Database\\Seeders\\DatabaseSeeder"

Seeds 5 regions, 245 countries, 9 language translations and the native_name column. Idempotent — safe to re-run. See Seeding for deploy-pipeline integration.

Principle

A country-data package should do exactly two things: create the tables and keep the rows in sync. Three commands (composer require, php artisan migrate, php artisan db:seed) do both. The seeders are idempotent, so running them on every deploy keeps rows in sync with no extra wiring.

Migrating from lwwcas/laravel-countries

Same 7-table schema, same Eloquent models, same query scopes, same country data. Migration is mostly a namespace swap — see the step-by-step guide in the docs:

Migrating from lwwcas

Usage

use Aaix\LaravelCountries\Models\Country;

// Lookup
$de = Country::getByCode('DE');             // alpha-2, case-insensitive
$de = Country::whereIsoAlpha3('DEU')->first();
$de = Country::whereIso('276')->first();    // matches alpha-2, alpha-3, or numeric

// Names
$de->name;                                  // current app locale, falls back to config fallback
$de->nameInLang('ja');                      // "Germany" (falls back if 'ja' missing)
$de->official_name;                         // "Federal Republic of Germany"
$de->native_name;                           // "Deutschland"

// Bulk localized list — ready for dropdowns
Country::listInLang('de');
// Collection(['DE' => 'Deutschland', 'FR' => 'Frankreich', ...] sorted by name)

// Flag
$de->getFlagEmoji();                        // 🇩🇪
$de->flag_colors_hex;                       // ['#000000', '#DD0000', '#FFCE00']

// Relations
$de->region;                                // CountryRegion
$de->coordinates;                           // CountryCoordinates
$de->extras;                                // CountryExtras (religions, orgs, sports, internet stats)
$de->geographical;                          // CountryGeographical (GeoJSON)

Available query scopes: whereIso, whereIsoAlpha2, whereIsoAlpha3, whereIsoNumeric, whereCurrency, whereBorders, whereDomain, whereLanguages, whereFlagColors, wherePhoneCode, whereIndependenceDay, whereStatistics, whereName, whereSlug, whereWmo.

Table layout

Table Purpose
lc_regions 5 continents (Africa, Americas, Asia, Europe, Oceania)
lc_region_translations Region names per locale
lc_countries 245 countries — ISO codes, capital, currency, flag metadata, native_name, population, GDP etc.
lc_countries_translations Country name + slug per locale
lc_countries_coordinates Latitude/longitude and formatted coordinate variants
lc_countries_geographical Country outline as GeoJSON
lc_countries_extras Religions, international orgs, national sport, internet stats, cybersecurity agency

Translations are handled by astrotomic/laravel-translatable (already a dependency). The withTranslation() global scope eager-loads the current locale + fallback locale — so Country::all()->pluck('name') is one query, not N+1.

Requirements

  • PHP 8.2+
  • Laravel 11+

Testing

composer test

Credits

License

MIT. See LICENSE.md.