Squire: read-only Eloquent models for countries, airports and currencies
A library of static Eloquent models for common fixture data.
At a glance
- What is it?
- Squire is a set of Composer packages that ship static fixture data as Eloquent models, so a country dropdown or an airport lookup is a query against your own database rather than a bundled JSON file, with a read-only guarantee and per-locale packages.
- Who is it for?
- Squire fits a Laravel application that needs a country list, a currency table or airport metadata and wants it to look like any other Eloquent model, especially one that already validates input against a country or currency code. It is a poor fit if you want to edit the reference data, because the models are read-only, and it is a poor fit if you need a locale that no package covers.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Fixture data as Eloquent models rather than as a JSON file
Squire is a library of static Eloquent models for fixture data that is commonly needed in web applications, such as countries, currencies and airports. It is based on the concepts of Caleb Porzio's Sushi package, which is the PHP package for static data.
The difference from the usual approach is the shape of the API. The common alternative to a package like this is a JSON file you read at runtime, or a set of constants. Squire makes the reference data live in your database as ordinary Eloquent models, so a country lookup is a query and a country dropdown is a relationship traversal rather than a separate lookup table.
The use cases the documentation lists are concrete. Populating dropdown options, such as a country selector on an address form. Attaching extra data to other models in your application, such as airport information attached to a Flight model. And validating user input, where a submitted country code is checked against the real list rather than a regex.
The install is one Composer package per model per locale, so a project only pays for what it uses. The example given is the English country model:
composer require squirephp/countries-enThe package is MIT licensed with a LICENSE.md file, the primary language is PHP, and the repository is not archived with the last push on 2026-09-18. The releases are v3.11.1 from 2026-07-02, v3.11.0 from 2026-03-19 and v3.10.1 from 2025-07-17, and the default branch is 3.x, so the 3.x line is the current one. The badges say Laravel v8.x and PHP 8.
Read-only, and the three query methods you get
The rule that shapes the API is that Squire models are read-only. The documentation says you can interact with a Squire model just like any other Eloquent model, except that it only handles read-only operations.
So the three things you do with them are the three read operations, and they look exactly like Eloquent:
use Squire\Models\Country;
Country::all(); // Get information about all countries.
Country::find('us'); // Get information about the United States.
Country::where('name', 'like', 'a%')->get(); // Get information about all countries beginning with the letter "a".That is the point of the design. The models inherit the query builder, so where clauses, scopes and eager loading work, and there is no second data access path to learn. What you cannot do is write to them, which is what makes it safe to seed a table of reference data and forget about it.
The identifiers are the natural keys rather than numeric ids, since find('us') takes the country code. That matters for the relationship traversal described below, where a country_id column on your own model holds the same two letter code that Squire uses as its primary key.
The find() call returning null for a code that does not exist is worth knowing about, because if the reference data is used for validation, a null result and a valid result are two very different answers and one of them is a bug in your validation logic.
The models, their schemas, and how they relate
The catalogue covers nine model types, and each one is documented with the same three things: an installation table of locales, a schema table of columns with descriptions and examples, and a relationships table.
The Airline model carries an alias, a call sign, the IATA and ICAO codes, the country_id as an ISO 3166-1 alpha-2 code, and a name, with relationships to country and continent.
The Airport model has its IATA and ICAO codes, a country_id, a municipality, a name, and a timezone_id holding a PHP timezone identifier such as Europe/London, with relationships to country and timezone. That timezone_id is the interesting column, because it is a PHP identifier rather than a raw offset, so the application can convert an airport's local time properly.
The Continent model is small, a two letter code and a name, and it relates to countries, regions and timezones. The Country model is the one with the most columns: an E.164 calling code, a capital_city, the ISO 3166-1 alpha-2 code_2, the alpha-3 code_3, a continent_id, a currency_id holding the ISO 4217 alphabetic currency code, and more.
The Continent model is where the relationship structure shows. A continent has countries, regions and timezones, and a country has a continent, a currency and a region. So the set of models forms a graph, and the country model is the hub: an airline points at a country, an airport points at a country and a timezone, a country points at a continent and a currency.
That graph is what makes the package useful beyond a dropdown. A Flight model with a country and an airport can traverse to the continent and the currency in one eager-loaded query, which is the relationship feature the documentation calls out under model relationships.
Locales are separate packages, and some come from elsewhere
Each model and each language is its own Composer package, and the installation tables show how wide the coverage is and how uneven.
The Continent model has German, English and Polish under the squirephp organisation, and Italian published by squirephp-italian. The Country model has English, French, German, Polish and Spanish under squirephp, Dutch published by quickstreambe as squirephp-countries-nl, and Italian from squirephp-italian. The Airline and Airport models are documented with English only in the tables shown.
So the pattern is clear and it has a consequence: the core languages are maintained by the project, and the rest are community packages under a different vendor. The documentation for each model also says you need only install the ones you will use, and there is a full list of available models further down.
There is a documentation section on adding a localization and a section on creating your own models, so both extension paths are documented rather than left to the reader.
For the currency model there is an extra piece of functionality, formatting money, which has its own subsection in the contents. That is a case where the reference data is not just a lookup table: the currency carries enough to format an amount, which means the column set is doing something beyond identification.
There is also a section on upgrading from 1.x, which matters for a package on its 3.x branch, and a Need Help section at the end of the contents.
The monorepo layout, and what the licence lets you do
The repository is a monorepo, and the file listing shows how it is arranged. There is a packages/ directory holding the individual model packages, a composer.json, and a monorepo-builder.php, which is the tool that publishes and versions the many small packages from one source tree. The tests live in a tests/ directory with a phpunit.xml.dist, and the formatting is handled by a .php-cs-fixer.dist.php configuration.
The build and release tooling explains why the packages are versioned separately. Every locale of every model is its own published artifact, and the monorepo builder is what keeps their versions in step and moves them out in order. It is a piece of infrastructure most contributors never think about, and its presence is the price of the per-locale install model.
The licence is MIT, in a LICENSE.md file, with a CODE_OF_CONDUCT.md and a SECURITY.md alongside. MIT is the permissive end of the spectrum, and for a package of public reference data that is the right choice: you can use the models in a commercial application, modify them, ship them, and the only obligation is to keep the copyright notice.
The practical thing about the licence and the design together is that the data is yours to copy. If a locale is missing and you need it, you can build the model yourself, which the documentation supports with its own section, and nothing about the core package prevents that.
The project is on the 3.x branch, the last push was on 2026-09-18, and the release line moves with small version bumps, v3.10.1 through v3.11.1, which fits a package whose change surface is a data refresh rather than an API change.
Editorial conclusion
Squire fits a Laravel application that needs a country list, a currency table or airport metadata and wants it to look like any other Eloquent model, especially one that already validates input against a country or currency code. It is a poor fit if you want to edit the reference data, because the models are read-only, and it is a poor fit if you need a locale that no package covers. Before adopting, install only the models and locales you actually use, since each is a separate Composer package, and check the locale table for the country model because several languages are published by third parties rather than by the project itself.
Frequently asked questions
What is Squire and what does it provide?
Squire is a library of static Eloquent models for fixture data commonly needed in web applications, such as countries, currencies and airports, based on the concepts of Caleb Porzio's Sushi package. The models cover Airline, Airport, Continent, Country, Currency, GbCounty, Region and Timezone, and each is installed as its own Composer package per locale.
How do I install a Squire model?
With Composer, one package per model per locale. For example, composer require squirephp/countries-en installs the English country model, and the documentation notes that you need only install the models you will use.
Can I write to a Squire model?
No. The models are read-only. You interact with them just like any other Eloquent model, except that only read operations are handled, so Country::all(), Country::find('us') and where clauses work, but there is no write path.
What relationships do the Squire models have?
A continent has countries, regions and timezones. An airline has a country and a continent. An airport has a country and a timezone, and carries a timezone_id with a PHP timezone identifier such as Europe/London. A country carries its own identifiers including code_2, code_3, a calling_code, a capital_city, a continent_id and a currency_id.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/squirephp-squire)Was this useful?