PHPackages                             imujas9/laravel-world - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. imujas9/laravel-world

ActiveLibrary[Localization &amp; i18n](/categories/localization)

imujas9/laravel-world
=====================

World countries, states and cities with multi-language support for Laravel. Works without a database out of the box.

v1.1.0(1mo ago)034MITPHPPHP ^8.1

Since May 25Pushed 1mo agoCompare

[ Source](https://github.com/imujas9/laravel-world)[ Packagist](https://packagist.org/packages/imujas9/laravel-world)[ RSS](/packages/imujas9-laravel-world/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (5)Versions (3)Used By (0)

🌍 Laravel World
===============

[](#-laravel-world)

[![Latest Version on Packagist](https://camo.githubusercontent.com/3c715aae9e6e15a6a00fe75721e87ac184036eb1a4e15c61b7b744076a1ad34b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696d756a6173392f6c61726176656c2d776f726c642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/imujas9/laravel-world)[![Total Downloads](https://camo.githubusercontent.com/518cb8ebf6ffaab3447812ca4c3cede36d5d131d2eb7941c30556f44a761bbe0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f696d756a6173392f6c61726176656c2d776f726c642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/imujas9/laravel-world)[![PHP Version](https://camo.githubusercontent.com/359518412212551c11fc792969f786863addf0fd70a1c66ee7f80e28dfd147f9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f696d756a6173392f6c61726176656c2d776f726c642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/imujas9/laravel-world)

World countries, states, and cities for Laravel — with multi-language support. Works **without a database** out of the box. Switch to a database driver any time with a single env variable.

---

✨ What Makes This Different
---------------------------

[](#-what-makes-this-different)

FeatureLaravel WorldOthersWorks without a database✅❌Switch to DB with one env var✅❌Auto locale detection✅❌Multi-language in one query✅❌City translations on demand✅❌20+ languages for countries &amp; states✅PartialFluent chainable API✅LimitedPartial name search &amp; operators✅❌---

📦 What's Included
-----------------

[](#-whats-included)

- **250 countries** — numeric ID, ISO codes, dialling codes, currencies, flags, regions, capital cities, TLD, coordinates
- **5,308 states / provinces** — linked to countries by ID and code, with administrative type
- **156,025 cities** — linked to states and countries by ID and code, with coordinates
- **20 languages** for country names · **27** for states · **24** for cities (downloaded on demand)

---

Requirements &amp; Installation
-------------------------------

[](#requirements--installation)

- PHP **8.1+** · Laravel **10**, **11**, **12**, or **13**

```
composer require imujas9/laravel-world
```

No migrations, no seeding, no config. Auto-registers and works immediately.

---

Quick Start
-----------

[](#quick-start)

```
use Imujas9\World\Facades\Country;
use Imujas9\World\Facades\State;
use Imujas9\World\Facades\City;

Country::all();                          // all countries, names in app locale
Country::find(101);                      // by numeric ID
Country::findByCode('IN');               // by ISO2 code

State::whereCountry('IN')->get();        // states of India
State::find(12);                         // by numeric ID
State::findByCode('GJ');                 // by code

City::whereState('GJ')->get();           // cities of Gujarat
City::whereCountry('IN')->whereState('MH')->get();

// Explicit language
Country::lang('hi')->get();              // Hindi names
Country::lang('en', 'hi')->get();        // both → name_en, name_hi

// Locale-aware — no lang() needed when app locale is set
App::setLocale('hi');
Country::all();                          // names in Hindi automatically
```

---

⚙️ Configuration```
php artisan vendor:publish --tag=world-config
```

```
// config/world.php
return [
    // 'file' (default, zero setup) or 'database'
    'driver' => env('WORLD_DRIVER', 'file'),

    // Fallback language. Priority: app locale → this → 'en'
    'default_lang' => env('WORLD_LANG', 'en'),

    // Table prefix for database driver
    'table_prefix' => 'world_',

    // Storage path for downloaded city translations
    'city_translations_path' => storage_path('app/world/translations/cities'),
];
```

---

🌐 Locale SupportThe package reads `app()->getLocale()` automatically. No `lang()` call needed once locale is set in middleware.

**Resolution order** (when `lang()` is not called):

1. `app()->getLocale()` — set by middleware or `App::setLocale()`
2. `config('world.default_lang')` — `WORLD_LANG` env value
3. `'en'` — hardcoded fallback

Locale strings are normalised: `en_US` → `en`, `zh_CN` → `zh`.

**Middleware example:**

```
App::setLocale($request->user()?->locale ?? 'en');

// Anywhere downstream — no lang() needed:
Country::all();                    // names in user's language
Country::findByCode('IN');         // name in locale
State::whereCountry('IN')->get();  // state names in locale
```

**Fallback behaviour:**

LocaleTranslation file existsResult`hi`✅Hindi name`ga`❌Falls back to `default_lang``en_US`✅ normalised to `en`English name`lang()` always overrides the locale for that specific query.

---

🏙️ City TranslationsCity names work in English out of the box. Translations are **not bundled** (they add 51 MB to every install) — download only what you need:

```
php artisan world:translations hi fr de   # specific languages
php artisan world:translations --all      # all 24 languages
php artisan world:translations hi --force # re-download to update
php artisan world:translations            # list available / downloaded
```

Once downloaded, translations are used automatically:

```
City::lang('hi')->whereState('GJ')->get();
```

**Available:** `ar` `bn` `br` `de` `es` `fa` `fr` `ga` `hi` `hr` `hy` `id` `it` `ja` `ko` `nl` `pl` `pt` `ru` `tr` `uk` `ur` `vi` `zh`

> Add `php artisan world:translations hi` to your deploy script for the languages your app uses.

---

🗄️ Database DriverUse the database driver when you need SQL joins, full-text search, or indexing on millions of rows.

```
php artisan vendor:publish --tag=world-migrations
php artisan migrate
php artisan world:seed
```

> Re-seed: `php artisan world:seed --truncate`

```
WORLD_DRIVER=database
```

Your application code stays **exactly the same** — the driver swap is transparent.

**When to use each driver:**

ScenarioRecommended driverRead-only lookups, dropdowns, country picker`file` (default)SQL `JOIN` to your own tables`database`Full-text search with relevance ranking`database`Multi-tenant SaaS — no shared DB schema constraint`file`High-traffic API — want to avoid repeated JSON I/O`file` + cacheYou already manage a world-data migration workflow`database`**DB performance notes:**

- `paginate()` runs a `COUNT(*)` + a single `LIMIT/OFFSET` query — no full table scan.
- An index on `name` is created for all three tables. Use `whereLike('name', 'Ind%')` for fast prefix searches.
- For suffix / infix LIKE (`%istan%`), consider a full-text index on your database engine.

---

📖 API Reference### Country

[](#country)

```
Country::all();
Country::find(101);                              // by numeric ID
Country::findByCode('IN');                       // by ISO2 (case-insensitive)
Country::lang('hi')->get();                      // single language
Country::lang('en', 'hi')->get();                // multiple → name_en, name_hi
Country::lang('en')->whereRegion('Asia')->get();
Country::lang('en')->where('currency', 'INR')->get();
Country::lang('en')->where('id', '>', 50)->get();    // operators: >, =, whereLike('name', 'Ind%')->get();
Country::lang('en')->search('india')->get();         // partial name match
Country::lang('en')->whereIn('code', ['IN', 'US', 'GB'])->get();
Country::lang('en')->orderBy('name')->get();
Country::lang('en')->orderBy('name', 'desc')->get();
Country::lang('en')->limit(10)->offset(20)->get();
Country::lang('en')->whereRegion('Asia')->first();
Country::whereRegion('Europe')->count();
Country::lang('en')->paginate(15);               // reads ?page from request
Country::lang('en')->paginate(15, 2);            // explicit page 2
```

### State

[](#state)

```
State::all();
State::find(12);                                 // by numeric ID
State::findByCode('GJ');                         // by code (case-insensitive)
State::findByCode('CA', 'US');                   // disambiguate — CA exists in US and Canada
State::whereCountry('IN')->get();
State::lang('hi')->whereCountry('IN')->get();
State::lang('en', 'hi')->whereCountry('IN')->get();
State::whereCountry('US')->count();
State::whereCountry('IN')->paginate(20);
State::whereCountry('IN')->search('gujar')->get();  // partial name match
State::whereIn('country_code', ['IN', 'US'])->get();
```

### City

[](#city)

```
City::all();
City::find(1);                                   // by numeric ID
City::whereCountry('IN')->get();
City::whereState('GJ')->get();
City::whereCountry('IN')->whereState('MH')->get();
City::lang('hi')->whereState('GJ')->get();
City::lang('en', 'hi')->whereState('GJ')->get();
City::whereCountry('IN')->paginate(50);
City::whereCountry('IN')->search('mumbai')->get();   // partial name match
City::whereIn('state_code', ['GJ', 'MH'])->get();
```

---

📊 Result ObjectsAll methods return consistent value objects regardless of driver.

### CountryData

[](#countrydata)

PropertyTypeDescription`id``int`Numeric ID`code``string`ISO2 (e.g. `IN`)`iso3``string`ISO3 (e.g. `IND`)`phone_code``string`Dialling code (e.g. `91`)`currency``string`ISO 4217 (e.g. `INR`)`flag``string|null`Emoji flag (e.g. `🇮🇳`)`region``string|null`e.g. `Asia``subregion``string|null`e.g. `Southern Asia``capital``string|null`Capital city (e.g. `New Delhi`)`tld``string|null`Top-level domain (e.g. `.in`)`latitude``string|null`Country centre latitude`longitude``string|null`Country centre longitude`name``string|null`Translated name (single lang)`names``array``['en' => 'India', 'hi' => 'भारत']` (multi-lang)### StateData

[](#statedata)

PropertyTypeDescription`id``int`Numeric ID`code``string`State code`country_code``string`Parent country ISO2`country_id``int`Parent country numeric ID`type``string|null`State / Province / Region…`latitude``string|null``longitude``string|null``name``string|null`Translated name (single lang)`names``array`Translated names (multi-lang)### CityData

[](#citydata)

PropertyTypeDescription`id``int`Numeric ID`state_code``string`Parent state code`country_code``string`Parent country ISO2`state_id``int|null`Parent state numeric ID (DB driver only)`country_id``int|null`Parent country numeric ID (DB driver only)`latitude``string|null``longitude``string|null``name``string|null`Translated name (single lang)`names``array`Translated names (multi-lang)---

🔍 Filtering &amp; SearchAll three facades share the same fluent filtering API.

### Equality (default)

[](#equality-default)

```
Country::where('currency', 'INR')->get();
Country::where('region', 'Asia')->get();
```

### Comparison operators

[](#comparison-operators)

```
Country::where('id', '>', 100)->get();
Country::where('id', '>=', 50)->count();
Country::where('id', '!=', 1)->get();
```

### LIKE / partial match

[](#like--partial-match)

```
// whereLike uses SQL-style % and _ wildcards
Country::lang('en')->whereLike('name', 'United%')->get();   // starts with
Country::lang('en')->whereLike('name', '%land')->get();     // ends with
Country::lang('en')->whereLike('name', '%istan%')->get();   // contains

// search() is shorthand for whereLike(field, '%term%')
Country::lang('en')->search('india')->get();
State::whereCountry('IN')->search('gujar')->get();
City::whereCountry('IN')->search('mumbai')->get();

// search on a different field
Country::lang('en')->search('Delhi', 'capital')->get();
```

### whereIn

[](#wherein)

```
Country::whereIn('code', ['IN', 'US', 'GB'])->get();
State::whereIn('country_code', ['IN', 'US'])->get();
City::whereIn('state_code', ['GJ', 'MH', 'DL'])->get();
```

### Chaining multiple filters

[](#chaining-multiple-filters)

```
City::whereCountry('IN')
    ->whereIn('state_code', ['GJ', 'MH'])
    ->search('abad')
    ->orderBy('name')
    ->paginate(20);
```

> **File driver note:** LIKE filtering on `name` for countries and states matches the translated name in the active language. For cities the stored English name is used. All other fields (`code`, `capital`, `region`, `currency`, etc.) are matched against the raw data.

---

📄 Pagination`paginate()` behaves like Laravel's native paginator — it reads the current page from the `?page` query parameter automatically.

```
// In a controller — page comes from ?page=N in the URL
$countries = Country::lang('en')->whereRegion('Asia')->paginate(15);
$states    = State::whereCountry('IN')->paginate(20);
$cities    = City::whereCountry('IN')->paginate(50);

// Explicit page (useful outside HTTP context)
$page2 = Country::lang('en')->paginate(15, 2);
```

The returned `LengthAwarePaginator` carries the correct `path` and query string, so `$countries->links()` renders proper next/prev URLs in Blade templates.

**Database driver:** paginate executes a `COUNT(*)` query + a single `LIMIT/OFFSET` data query — no full table scan.

**File driver:** paginate streams/filters all matching records to count, then returns only the requested page slice.

---

🌍 Available Languages> Missing translations fall back to the English name automatically. City translations must be downloaded separately — see [City Translations](#%EF%B8%8F-city-translations).

CodeLanguageCountriesStatesCities`en`English✅✅✅`ar`Arabic✅✅✅`bn`Bengali❌✅✅`br`Breton✅✅✅`de`German✅✅✅`el`Greek❌✅❌`es`Spanish✅✅✅`et`Estonian❌✅❌`fa`Persian✅✅✅`fi`Finnish❌✅❌`fr`French✅✅✅`ga`Irish❌❌✅`gu`Gujarati✅✅❌`hi`Hindi✅✅✅`hr`Croatian✅✅✅`hy`Armenian❌✅✅`id`Indonesian❌✅✅`it`Italian✅✅✅`ja`Japanese✅✅✅`ko`Korean✅✅✅`nl`Dutch✅✅✅`pl`Polish✅✅✅`pt`Portuguese✅✅✅`ru`Russian✅✅✅`tr`Turkish✅✅✅`uk`Ukrainian✅✅✅`ur`Urdu❌❌✅`vi`Vietnamese❌✅✅`zh`Chinese (Simplified)✅✅✅---

🔗 Model TraitsDrop a trait into any Eloquent model to get `country`, `state`, and `city` accessors that work with both drivers.

### HasWorldRelations — all in one

[](#hasworldrelations--all-in-one)

```
// Migration
$table->unsignedBigInteger('country_id')->nullable();
$table->unsignedBigInteger('state_id')->nullable();
$table->unsignedBigInteger('city_id')->nullable();
```

```
use Imujas9\World\Traits\HasWorldRelations;

class User extends Authenticatable
{
    use HasWorldRelations;
}
```

```
$user->country;             // CountryData (both drivers)
$user->country->name;       // "India"
$user->country->flag;       // "🇮🇳"
$user->country->capital;    // "New Delhi"
$user->country->phone_code; // "91"
$user->state->name;         // "Gujarat"
$user->city->name;          // "Ahmedabad"

// Eager loading (database driver only)
User::with('country', 'state', 'city')->get();
// $user->country still returns CountryData, not a raw model
```

### Individual traits

[](#individual-traits)

TraitColumn neededType`HasCountry``country_id``unsignedBigInteger``HasState``state_id``unsignedBigInteger``HasCity``city_id``unsignedBigInteger`### Using string codes instead of integer IDs

[](#using-string-codes-instead-of-integer-ids)

```
class User extends Authenticatable
{
    use HasCountry, HasState;

    protected string $countryForeignKey = 'country_code';
    protected string $countryOwnerKey   = 'code';

    protected string $stateForeignKey   = 'state_code';
    protected string $stateOwnerKey     = 'code';
}
```

### Driver behaviour

[](#driver-behaviour)

File driverDatabase driver`$user->country`✅ `CountryData`✅ `CountryData``User::with('country')`❌ no DB table✅ eager loads → `CountryData`---

🛠️ ContributingContributions, bug reports, and feature requests are welcome.

1. Fork the repo · create a branch · write tests · open a PR

```
composer install
./vendor/bin/phpunit
```

**Updating world data** — all data lives in `resources/data/` as plain JSON:

FilePurpose`countries.json`Country base data`states.json`State base data`cities.json`City base data`translations/countries/{lang}.json`Country names per language`translations/states/{lang}.json`State names per language`translations/cities/{lang}.json`City names per language (keyed by city ID)To add a new language, create `translations/countries/{lang}.json` with `{ "ISO2": "Name" }` pairs and repeat for states/cities.

---

About
-----

[](#about)

Hi, I'm **Ujas Patel** — a Backend Developer (TALL Stack), based in Ahmedabad, India. I built this package because every existing world-data solution for Laravel forces a database setup before you can use even a simple country list. Laravel World works out of the box — and scales to a full database driver when you need it.

**Reach out:** [imujaspatel \[at\] gmail \[dot\] com](mailto:imujaspatel@gmail.com)

[![GitHub](https://camo.githubusercontent.com/dc40bf3713654f6a710448974a829828bfdd4ddfc3769c43941a32927074ec34/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4769744875622d696d756a6173392d3138313731373f7374796c653d666c61742d737175617265266c6f676f3d676974687562)](https://github.com/imujas9)[![X](https://camo.githubusercontent.com/1ca1a396c811a14053f28720c83efcadd567c592fffabde3570b12df21ed64c7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f582d696d756a6173392d3144413146323f7374796c653d666c61742d737175617265266c6f676f3d78)](https://x.com/imujas9)[![LinkedIn](https://camo.githubusercontent.com/2deae44c74299097c5b42ef4dbd28203e084dfda2f4e1ca2ebc68680110bfe33/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d696d756a61732d3041363643323f7374796c653d666c61742d737175617265266c6f676f3d6c696e6b6564696e)](https://www.linkedin.com/in/imujas)

---

Support
-------

[](#support)

NeedWhere to go🐛 Bug[Open an issue](https://github.com/imujas9/laravel-world/issues)💡 Feature request[Open an issue](https://github.com/imujas9/laravel-world/issues)❓ Question[Start a discussion](https://github.com/imujas9/laravel-world/discussions)If this package saved you time, a ⭐ on [GitHub](https://github.com/imujas9/laravel-world) goes a long way.

---

License
-------

[](#license)

This package is open-source software licensed under the MIT License. Feel free to use, modify, and distribute it according to the terms of the license.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance89

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

2

Last Release

55d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/67316015?v=4)[Ujas Patel](/maintainers/imujas9)[@imujas9](https://github.com/imujas9)

---

Top Contributors

[![imujas9](https://avatars.githubusercontent.com/u/67316015?v=4)](https://github.com/imujas9 "imujas9 (7 commits)")

---

Tags

phplaraveli18nmultilingualcountriesworldstatescities

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/imujas9-laravel-world/health.svg)

```
[![Health](https://phpackages.com/badges/imujas9-laravel-world/health.svg)](https://phpackages.com/packages/imujas9-laravel-world)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.5k55.4M9.2k](/packages/larastan-larastan)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M246](/packages/laravel-ai)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[erag/laravel-lang-sync-inertia

A powerful Laravel package for syncing and managing language translations across backend and Inertia.js (Vue/React/Svelte) frontends, offering effortless localization, auto-sync features, and smooth multi-language support for modern Laravel applications.

4925.3k](/packages/erag-laravel-lang-sync-inertia)[calebdw/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

15118.7k4](/packages/calebdw-larastan)[itpathsolutions/dbstan

Database Standardization and Analysis Tool for Laravel

463.0k](/packages/itpathsolutions-dbstan)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
