wikimedia/bcp-47-code
A lightweight PHP library offering value objects for BCP 47 language codes, letting you parse, validate, and format tags like en, de-AT, or zh-Hant safely instead of passing raw strings around.
Architecture fit. wikimedia/bcp-47-code is a deliberately tiny, framework-agnostic library: a Bcp47Code interface plus a value-object implementation representing a language tag, with conversion to/from the Wikimedia/MediaWiki internal language code space. There is no service provider, no config file, no facade, no container coupling, and no runtime dependency on MediaWiki core. Architecturally it slots into Laravel as a leaf dependency — the kind of thing you type-hint in a domain service or cast on an Eloquent model. That is a good fit if the problem you have is "language codes are untyped strings flowing through the app, and some of them are MediaWiki codes while others are RFC 5646 tags." It is a poor fit if you expect it to do locale validation, likely-subtags resolution, display names, or CLDR data — it does none of that.
Integration feasibility. Mechanically trivial. composer require wikimedia/bcp-47-code, optional interface binding in a service provider, and instantiation at the boundaries. Realistic effort for a first vertical slice is under a day. The genuine cost is domain knowledge, not wiring: RFC 5646 casing rules, ISO 639-1/639-3 relationships, and MediaWiki's idiosyncratic codes (simple, be-tarask, de-formal, deprecated iw/in) are where teams get burned.
Technical risk.
Key questions.
symfony/intl plus a small value object covers it without the license question.Vary/Content-Language, hreflang sitemap, email templates — and do they all agree on canonical casing?Stack fit. Pure PHP, no Laravel version constraint, no conflicting dependency tree expected given zero runtime deps. It is complementary, not substitutive: pair it with symfony/intl for ICU-backed display names and locale data, and with your own or a community validation rule for tag well-formedness. Do not assume bcp-47-code validates; assume it represents.
Migration path. Strangler pattern at the edges — this is the whole point of the package.
varchar language columns; do not migrate schema for a type change.Accept-Language parsing middleware.string at persistence and transport; hold the object in domain/service layers only.en-US vs en-us) mid-rollout.Compatibility. Two things to verify concretely: the package's PHP floor against your lowest supported runtime, and namespace collisions with any existing Language, Locale, or I18n value objects — alias imports rather than renaming your own classes. If the app already speaks MediaWiki codes in the database (common when ingesting from MediaWiki/Wikibase/Parsoid), confirm the round-trip direction you need is the one supported, and write a characterization test for the specific codes you actually carry.
Sequencing.
hreflang, search indexing.Maintenance. Releases track Wikimedia Gerrit and MediaWiki's cadence; the GitHub mirror accepts no issues or PRs. Practical consequence: you are tracking tags, not conversations. Churn should be minimal given the API surface, but budget for a periodic manual check rather than expecting Dependabot plus an active changelog to guide you.
Support. Volunteer/Wikimedia-staffed, no SLA, no commercial backing. Given the LOC count, the mitigation is cheap: vendor it or maintain a private fork behind a repositories VCS entry. Decide the fork owner now, not during an incident.
Scaling. Effectively free — pure PHP, immutable value objects, no I/O, no shared state, no cache to warm. Instantiating per request is fine. The only scaling-adjacent concern is if you bolt on your own validation or lookup tables; memoize those per request, not globally.
Failure modes.
iw, in, mo, simple, be-tarask, de-formal) failing to round-trip, silently dropping content from language-filtered queries.Ramp-up. Hours for any mid-level Laravel engineer to use the API; the real onboarding cost is RFC 5646 and MediaWiki code semantics. Pair the adoption with a short internal write-up on which code space is canonical in which layer, or the team will re-litigate it in every PR review.
Bottom line for a TPM. The package is technically low-risk and operationally nearly free, but its addressable problem is narrow and its license is a real gate. Adopt it only where MediaWiki interop or shared code-space conversion is an actual requirement; otherwise the value is a typed wrapper you could write in an afternoon without the GPL question. Score it as a component, not a product.
How can I help you explore Laravel packages today?