adamlc/address-format
A PHP package for formatting postal addresses using country-specific templates. adamlc/address-format turns structured address fields into consistent, locale-aware output, making it useful for invoices, shipping labels, and any app that needs to display addresses correctly across countries.
Install via Composer and confirm the package resolves against your PHP version (the 2025 release targets modern PHP; check composer.json for the floor before adopting on an older app):
composer require adamlc/address-format
The entry point is the formatter class in the Adamlc\AddressFormat namespace (Format in current releases — verify the exact FQCN against the installed README, since the package is small and class names have churned across versions). It accepts a flat address array using the same field names as the international address-format data model:
use Adamlc\AddressFormat\Format;
$address = [
'countryCode' => 'US', // required, ISO 3166-1 alpha-2
'recipient' => 'Jane Doe',
'organization' => 'Acme Inc.',
'addressLine1' => '123 Main St',
'addressLine2' => 'Suite 400',
'locality' => 'Springfield',
'administrativeArea' => 'IL',
'postalCode' => '62701',
];
echo (new Format())->format($address);
First use case: rendering a stored shipping address in an order confirmation or invoice, where the line order, postal-code placement, and administrative-area rules differ by country (e.g. US puts state before ZIP; GB puts the post town and postcode on their own line; JP orders from largest to smallest). Read the README first, then read the bundled address-format data to see which fields the target countries actually use.
Bind it as a singleton. The formatter loads country-format data on construction. Resolve it once from the container rather than new Format() per address:
// AppServiceProvider
$this->app->singleton(Format::class);
Wrap it behind a small domain service, so your app depends on an interface you control, not on a 84-star package:
final class AddressFormatter
{
public function __construct(private Format $formatter) {}
public function forOrder(Order $order): string
{
return $this->formatter->format([
'countryCode' => strtoupper($order->shipping_country),
'recipient' => $order->shipping_name,
'organization' => $order->shipping_company,
'addressLine1' => $order->shipping_line1,
'addressLine2' => $order->shipping_line2,
'locality' => $order->shipping_city,
'administrativeArea' => $order->shipping_state,
'postalCode' => $order->shipping_postcode,
]);
}
}
Map from an Eloquent model via a cast or accessor. Keep the array shape in one place so a schema change only touches one mapping.
Render in Blade with white-space: pre-line (or pipe through nl2br() if the formatter exposes a formatHtml() variant). The library returns newline-separated text, not HTML.
Use it at the output boundary only. Store addresses as structured columns; format at render time so a user changing country re-renders correctly. Do not persist the localized string as the source of truth.
Pair with validation. The formatter assumes the fields are meaningful; it does not validate postal codes or required fields per country. Keep a country-aware validation rule set and call the formatter only on validated data.
countryCode is mandatory and case-sensitive. Uppercase ISO alpha-2 only. A lowercase us or a missing key typically falls back to an empty/odd result rather than throwing — guard it.addressLine1 and locality produces a valid-looking two-line string. Assert on full output in tests, not substrings.administrativeArea is the state/province, locality is the city, dependentLocality is the suburb/neighbourhood, sortingCode is the extra postal segment (used by e.g. BR, GB). Passing state or city silently does nothing.<br>. For emails use \n as-is; for Blade use {!! nl2br(e($formatted)) !!} or CSS. Never echo raw.US/GB.How can I help you explore Laravel packages today?