flairuk / laravel-countries
ISO 3166 countries for Laravel: codes, currencies, calling codes, regions, EEA membership and flags, with a lookup API, validation rule and optional database table.
Requires
- php: ^8.2
- illuminate/console: ^12.0|^13.0
- illuminate/database: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- illuminate/validation: ^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0|^11.0
- phpunit/phpunit: ^11.5|^12.0|^13.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-05 11:04:08 UTC
README
Laravel Countries — All 249 ISO 3166 countries for Laravel 12 and 13. Each country includes:
- alpha-2, alpha-3 and numeric codes
- currency (ISO 4217 code, symbol, sub-unit, decimals)
- international calling code
- capital and citizenship
- UN M49 region and sub-region
- EEA membership
- flags, as emoji and as bundled PNGs
What the package provides:
- No database required. Look countries up through a facade backed by an in-memory dataset.
- Typed results. Every lookup returns readonly
Countryobjects in Laravel collections keyed by alpha-2 code. - Validation rule.
CountryCodeaccepts alpha-2, alpha-3 and/or numeric codes. - Optional table. Publish a migration and seed a
countriestable when other tables need to reference countries.
📦 Installation · 🚀 Usage · 💾 Database table · 🔄 Upgrading
📦 Installation
composer require flairuk/laravel-countries
Requires PHP 8.2 or later with Laravel 12, or PHP 8.3 or later with Laravel 13.
Laravel discovers the service provider and the Countries facade automatically.
🚀 Usage
use FLAIRUK\Countries\Facades\Countries; $uk = Countries::find('GB'); // also 'gbr', '826' or 826 $uk->name; // "United Kingdom" $uk->iso3; // "GBR" $uk->currencyCode; // "GBP" $uk->currencySymbol; // "£" $uk->dialCode(); // "+44" $uk->flagEmoji(); // "🇬🇧" $uk->flagUrl(); // "https://app.test/vendor/countries/flags/GB.png" Countries::findOrFail('XX'); // throws ItemNotFoundException Countries::findByName('France'); Countries::exists('DEU'); // true Countries::all(); // Collection<string, Country> keyed by alpha-2 Countries::eea(); // the 30 EEA members Countries::usingCurrency('EUR'); Countries::withCallingCode('+1'); Countries::inRegion('150'); // UN M49 region (Europe) or sub-region ('154' = Northern Europe) Countries::search('kingdom'); // name, full name or exact code Countries::currencies(); // ['AED', 'AFN', ...]
Select options
Countries::options(); // ['AF' => 'Afghanistan', ...] sorted by name Countries::options('iso3'); // ['AFG' => 'Afghanistan', ...] Countries::options('iso2', 'citizenship');
Validation
use FLAIRUK\Countries\Rules\CountryCode; $request->validate([ 'country' => ['required', new CountryCode], // alpha-2 (default) 'nationality' => ['required', CountryCode::alpha3()], 'origin' => ['required', CountryCode::any()], // alpha-2, alpha-3 or numeric ]);
Flags
flagEmoji() works everywhere and needs no assets. To use the PNG flags (30×20), publish them to public/vendor/countries/flags:
php artisan vendor:publish --tag=countries-flags
flagUrl() returns null for the few newer territories without a bundled image: AX, BL, BQ, CW, GG, IM, JE, MF, RS, SS and SX.
💾 Database table (optional)
php artisan countries:install # publish config + migration, then ask to migrate and seed php artisan countries:install --migrate # migrate and seed without asking php artisan countries:seed # insert / update (safe to re-run) php artisan countries:seed --prune # also delete rows no longer in the dataset
You can also call the seeder from your own DatabaseSeeder:
$this->call(\FLAIRUK\Countries\Database\CountriesSeeder::class);
Query the table through the bundled Eloquent model:
use FLAIRUK\Countries\Models\Country; Country::code('GB')->first(); // alpha-2 or alpha-3 Country::eea()->orderBy('name')->get(); Country::usingCurrency('EUR')->pluck('name');
The table name and connection come from COUNTRIES_TABLE and COUNTRIES_DB_CONNECTION, or from the published config. The primary key id is the ISO 3166 numeric code.
🔄 Upgrading from dev-master
Version 1.0 is a rewrite. Breaking changes:
| dev-master | 1.0 |
|---|---|
Facade FLAIRUK\Countries\CountriesFacade |
FLAIRUK\Countries\Facades\Countries |
Countries::getList($sort) (array) |
Countries::all()->sortBy($property, SORT_NATURAL | SORT_FLAG_CASE) (Collection of Country; properties are camelCase, e.g. countryCode) |
Countries::getOne($id) |
Countries::find($id) (numeric code) |
Countries::getListForSelect($display) (keyed by id) |
Countries::options('id', $display) |
php artisan countries:migration |
php artisan countries:install / countries:seed |
Config key countries.table_name |
countries.table |
Keys country-code, region-code, sub-region-code |
numeric_code, region_code, sub_region_code |
Column country_code |
numeric_code |
Column flag ("GB.png") |
removed. Use flagUrl() / flagEmoji() |
Flags in src/flags |
resources/flags, publishable with --tag=countries-flags |
Row ids are unchanged. If you have an existing table, rename the column before re-seeding:
Schema::table('countries', function (Blueprint $table) { $table->renameColumn('country_code', 'numeric_code'); $table->dropColumn('flag'); });
Data corrections in 1.0
- EEA membership: the United Kingdom has left (Brexit). Iceland, Liechtenstein and Norway have been added. The list now has 30 members.
- Euro adoption: Croatia (2023) and Bulgaria (2026) now use the euro. Euro symbols are fixed for Estonia, Latvia, Lithuania, Malta, Slovakia, Cyprus, Åland, Saint Barthélemy and Saint Martin.
- Re-denominated currencies: BYR → BYN, MRO → MRU, STD → STN, SLL → SLE, VEF → VES, ZWL → ZWG.
- Sterling issues: Guernsey, Jersey and the Isle of Man use the ISO code
GBP. Their old codes (GGP, JEP, IMP) are not ISO 4217 codes. - Names: Eswatini, North Macedonia, Czechia, Türkiye and Cabo Verde.
- Formatting: whitespace is trimmed and empty values are
null.
🧪 Testing
composer test
📄 License
MIT. See LICENSE.