PHPackages                             mahocommerce/directory-data - 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. mahocommerce/directory-data

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

mahocommerce/directory-data
===========================

Multilingual country and region JSON data plus per-country address format metadata (postcode regex, required fields, format templates) for international e-commerce

1.0.20260516.1(3w ago)14↓100%[1 PRs](https://github.com/MahoCommerce/directory-data/pulls)MITPHPPHP &gt;=8.3CI passing

Since May 3Pushed 1w agoCompare

[ Source](https://github.com/MahoCommerce/directory-data)[ Packagist](https://packagist.org/packages/mahocommerce/directory-data)[ RSS](/packages/mahocommerce-directory-data/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (3)Versions (6)Used By (0)

Directory Data: Multilingual Countries, Regions &amp; Address Formats
=====================================================================

[](#directory-data-multilingual-countries-regions--address-formats)

A data package for international e-commerce: country/region names in 100+ locales plus per-country address format metadata (postcode regex, required fields, format templates), all distributed as plain JSON, framework-agnostic.

What This Provides
------------------

[](#what-this-provides)

### `countries.json`

[](#countriesjson)

249 ISO 3166-1 countries with multilingual names:

```
{
  "IT": {
    "en": "Italy",
    "it_IT": "Italia",
    "fr_FR": "Italie",
    "de_DE": "Italien"
  }
}
```

### `regions/{CC}.json`

[](#regionsccjson)

Shipping-relevant administrative subdivisions per country, multilingual:

```
{
  "TO": { "en": "Turin",  "it_IT": "Torino" },
  "MI": { "en": "Milan",  "it_IT": "Milano" }
}
```

### `formats/{CC}.json`

[](#formatsccjson)

Per-country address format metadata sourced from Google's libaddressinput:

```
{
  "country": {
    "key": "IT",
    "fmt": "%N%n%O%n%A%n%Z %C %S",
    "require": "ACSZ",
    "upper": "CS",
    "zip": "\\d{5}",
    "zipex": "00144,47037,39049",
    "posturl": "http://www.poste.it/online/cercacap/"
  },
  "subdivisions": {
    "AG": { "key": "AG", "name": "Agrigento", "zip": "92" }
  }
}
```

Field semantics follow the [libaddressinput conventions](https://github.com/google/libaddressinput/wiki/AddressValidationMetadata): `fmt` uses `%N` (name), `%O` (organization), `%A` (street), `%Z` (postcode), `%C` (city), `%S` (subdivision), `%n` (newline); `require` lists required field codes; `upper` lists fields that should be uppercased.

Installation
------------

[](#installation)

```
composer require mahocommerce/directory-data
```

Reading the Data
----------------

[](#reading-the-data)

Use `Maho\DirectoryData\Paths` to resolve file locations; never hardcode `vendor/mahocommerce/directory-data/...` since consumers may customize Composer's `vendor-dir`.

```
use Maho\DirectoryData\Paths;

$countries = json_decode(file_get_contents(Paths::countriesFile()), true);
$itRegions = json_decode(file_get_contents(Paths::regionsFile('IT')), true);
$itFormat  = json_decode(file_get_contents(Paths::formatsFile('IT')), true);
```

### Translation Lookup (countries.json + regions/\*.json)

[](#translation-lookup-countriesjson--regionsjson)

To keep file sizes minimal, redundant translations are omitted. Apply this fallback chain when reading:

1. Exact locale (e.g. `it_IT`)
2. Language code (e.g. `it`)
3. `en` (always present)

```
$name = $countries['IT']['it_IT']
    ?? $countries['IT']['it']
    ?? $countries['IT']['en'];
```

When to Use `regions/` vs `formats/`
------------------------------------

[](#when-to-use-regions-vs-formats)

Both files carry subdivision data, with different purposes and coverage. Pick based on what you're building:

- **Subdivision dropdown / address-form picker** → `regions/.json`. Multilingual names. Includes real shipping destinations that aren't in strict ISO 3166-2 (e.g. US military APO codes, US territories, AU Jervis Bay Territory, NO Svalbard).
- **Postcode validation, address-format template, required-field hints** → `formats/.json` `country` block. libaddressinput postal rules, mirrored verbatim.
- **Subdivision-level postcode hints** (e.g. an Italian province's ZIP prefix) → `formats/.json` `subdivisions[]`. libaddressinput's subdivision set; in some countries it's at a different administrative level from `regions/`. Join by key when you need both.

`regions/` is the canonical list for *display*; `formats/`'s `subdivisions` map is the canonical source for *postal rules*. The two overlap intentionally.

### Beyond strict ISO 3166-2

[](#beyond-strict-iso-3166-2)

`regions/` is built primarily from iso-codes (ISO 3166-2 with 100+ locale translations) plus a small curated set of real postal jurisdictions ISO doesn't cover. The most notable case is **US**: `regions/US.json` includes the 50 states + `DC` + Outlying Areas (`PR`, `GU`, `VI`, `AS`, `MP`, `UM`) + military APO codes (`AA`, `AE`, `AP`). The military codes are sourced from libaddressinput; the territories come from broader iso-codes subdivision types. Note that `PR`/`GU`/`VI`/`AS`/`MP`/`UM` are also separately listed as ISO 3166-1 countries; the dual-listing matches libaddressinput's convention and lets merchants pick the model that fits their checkout flow.

Similar augmentations exist for **AU** (Jervis Bay Territory), **NO** (Svalbard / Jan Mayen), **ES** (Ceuta / Melilla), **BR** (Brasília), **MX** (Ciudad de México), **AR** (CABA), **KR** (Jeju / Gangwon / Sejong), and **BS** (New Providence).

**A note on UK addresses:** `regions/GB.json` lists the 4 UK Constituent Countries (England, Scotland, Wales, Northern Ireland). Real-world UK checkout flows don't actually use a region dropdown: Royal Mail routes by postcode alone, so most major platforms (Magento, WooCommerce, Shopify, BigCommerce, PrestaShop) ship no GB regions and treat county as an optional free-text field after a postcode lookup. The 4 entries here are provided as a minimal option for merchants who do want a dropdown; most won't need them. UK counties (~48 ceremonial or 200+ current administrative units) are deliberately not provided; there's no canonical merchant-facing list and the prevailing convention is to skip the dropdown entirely.

Versioning
----------

[](#versioning)

Releases use the scheme **`1.0.YYYYMMDD`**:

- **Patch** (`YYYYMMDD`): daily snapshot date. New patch released only when upstream data actually changed.
- **Minor** (`1.X.0`): additive schema changes (new fields).
- **Major** (`X.0.0`): breaking schema changes (renames, removals, layout reorganization).

Pin with `^1.0` to receive non-breaking updates automatically.

Automated Updates
-----------------

[](#automated-updates)

A weekly GitHub Action regenerates the data from upstream sources and, if anything changed and validation passes, commits to `main` and tags a new release. Packagist picks up new tags via webhook.

Data Attribution &amp; Licensing
--------------------------------

[](#data-attribution--licensing)

Repository code is MIT. Data files carry their upstream licenses; see [LICENSE](LICENSE) for the full attribution table. Summary:

FilesSourceLicense`countries.json`, `regions/*.json`[Debian iso-codes](https://salsa.debian.org/iso-codes-team/iso-codes) via [sokil/php-isocodes](https://github.com/sokil/php-isocodes)LGPL-2.1+ / MIT`formats/*.json`[Google libaddressinput](https://github.com/google/libaddressinput) (via `chromium-i18n.appspot.com`)CC-BY 4.0Redistributors of the `formats/*.json` files must preserve attribution to Google's libaddressinput per CC-BY 4.0.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance97

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75% 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 ~7 days

Total

3

Last Release

24d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/262e16fb4a6bbef60ac0fd0172f5586e2c24effcc80a2138e662fb0316083c4c?d=identicon)[fballiano](/maintainers/fballiano)

---

Top Contributors

[![fballiano](https://avatars.githubusercontent.com/u/909743?v=4)](https://github.com/fballiano "fballiano (21 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")[![maho-organization-controller[bot]](https://avatars.githubusercontent.com/u/176492716?v=4)](https://github.com/maho-organization-controller[bot] "maho-organization-controller[bot] (2 commits)")[![sync-l10n-data[bot]](https://avatars.githubusercontent.com/u/176492716?v=4)](https://github.com/sync-l10n-data[bot] "sync-l10n-data[bot] (2 commits)")

---

Tags

addresslocalizationi18ntranslationmultilingualcountriesisoecommercepostcoderegionsaddress validationmahomahocommercelibaddressinput

### Embed Badge

![Health badge](/badges/mahocommerce-directory-data/health.svg)

```
[![Health](https://phpackages.com/badges/mahocommerce-directory-data/health.svg)](https://phpackages.com/packages/mahocommerce-directory-data)
```

###  Alternatives

[tractorcow/silverstripe-fluent

Simple localisation for Silverstripe

91432.1k28](/packages/tractorcow-silverstripe-fluent)[inpsyde/multilingual-press

Simply THE multisite-based free open source plugin for your multilingual websites.

2414.0k1](/packages/inpsyde-multilingual-press)[whitecube/lingua

A PHP language codes converter, from and to the most common formats (ISO, W3C, PHP and human-readable names).

441.2M21](/packages/whitecube-lingua)[jayesh/laravel-gemini-translator

An interactive command to extract and generate Laravel translations using Gemini AI.

712.2k1](/packages/jayesh-laravel-gemini-translator)[skillshare/formatphp

Internationalize PHP apps. This library provides an API to format dates, numbers, and strings, including pluralization and handling translations.

8031.5k](/packages/skillshare-formatphp)[fisharebest/localization

A lightweight localization database and translation tools, with data from the CLDR, IANA, ISO, etc.

29101.1k3](/packages/fisharebest-localization)

PHPackages © 2026

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