Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Country Code Field Laravel Package

tapp/filament-country-code-field

A country code select form field, table column, and table filter for Laravel Filament. Easily add searchable country codes to your resources' forms and tables, with a publishable config file. Supports Filament 4.x and 5.x.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What the package is. tapp/filament-country-code-field is a narrow, presentation-layer Laravel package that registers three Filament building blocks — a form select (CountryCodeSelect), a table column (CountryCodeColumn), and a table filter (CountryCodeSelectFilter) — for a single scalar attribute (a country code). It ships a publishable config file and a CSS asset, and otherwise delegates behaviour to Filament's own field/column/filter base classes. There is no service layer, no persistence layer, no migrations, and no domain logic beyond enumerating countries.

Architecture fit. Fit is high if and only if the consuming application is already a Filament panel app on a supported major. The package is additive and orthogonal: it does not touch routing, auth, models, or the database, so it cannot perturb existing domain boundaries. It is a textbook "thin UI package" — roughly 200–400 LOC of real logic plus a country list. For a non-Filament Laravel app, or a Livewire/Tall-stack app without Filament, fit is zero; the field types are unusable outside the Filament form/table lifecycle.

Integration feasibility. Very high. Composer install + optional config publish + three use statements in a Resource. No queue, no scheduler, no external API, no credentials, no migration. A competent Laravel engineer can wire it into one resource in under an hour and validate it in a review environment the same day. The real effort is not integration but the decision around data representation (see below).

Technical risk. Low blast radius, non-trivial longevity risk.

Risk Severity Notes
Data representation ambiguity High README never states whether the field stores ISO 3166-1 alpha-2 (US), alpha-3 (USA), or a dial code (+1). This determines whether the value is interoperable with phone validation, address, tax, and shipping logic downstream. Must be confirmed from source before schema commitment.
Longevity / bus factor Medium 21 stars, 0 dependents, one primary maintainer plus a small contributor pool. Effectively single-vendor stewardship.
Filament major coupling Medium v2.x targets Filament 4.x/5.x; v1.x targets Filament 3.x. Filament 5 support only landed in v2.0.2, so that combination is young. A Filament 6 major will require a package major.
PHP floor shift Medium v2.1.0 dropped PHP 8.2 and added 8.5. Teams still on 8.2 are pinned to ≤2.0.2, which lacks the CSS path fix.
Asset registration fragility Low–Medium The most recent patch (v2.1.1) was purely a CSS path registration fix — evidence that asset publishing is the historically brittle surface.
Security / supply chain Low No network calls, no eval, no dynamic code loading. Dependabot is active and CI runs tests plus Pint, which is a positive hygiene signal.

Key questions to resolve before commitment.

  1. Encoding: What exact string is persisted, and is it normalised (case, + prefix, nullability)?
  2. Country list source and currency: Is the list vendored, or derived from league/iso3166 / ICU? How stale can it get (e.g., new ISO codes, Kosovo, disputed territories)?
  3. Config surface: What is actually configurable — locale for country names, sort order, allowed/denied country subset, flag rendering on/off?
  4. Null and empty-state behaviour: v1.0.1 fixed "exception when column state is empty." Confirm the filter's behaviour on null and whether a "no country" option is offered.
  5. Localisation coverage: Only pt_BR was added over the project's life. What is the baseline locale set, and are country names translated or only the chrome?
  6. Accessibility: Is the select keyboard-navigable and screen-reader labelled, given the custom CSS?
  7. Test surface: What do the CI tests actually cover — field state, column rendering, filter query construction?
  8. Maintainer intent: Is there a published support window or a stated Filament 6 plan, or is this best-effort?

Build-vs-buy note. A TPM should price the alternative honestly: an internal Filament field wrapping a country enum is roughly 1–2 engineer-days, and it removes the external dependency entirely. With 21 stars and zero dependents there is no ecosystem signal that this package is load-bearing for anyone else, so adopting it is a convenience decision, not a de-risking decision. The correct framing is "buy a day of engineering time for a small stewardship liability," which is usually the right trade for a leaf-level UI widget — provided the encoding question resolves cleanly.

Integration Approach

Stack fit. Required baseline for current 2.x: PHP ≥ 8.3 (post-2.1.0), Laravel with Filament 4.x or 5.x, Composer 2. Filament 5 consumers must pin ^2.0.2 at minimum — 2.0.0/2.0.1 are Filament-4-only in practice. Filament 3 consumers must stay on the 1.x line and its separate documentation branch, which means the two lines are not interchangeable and should not coexist across a multi-panel monorepo without care.

Installation and configuration.

composer require tapp/filament-country-code-field:"^2.1"
php artisan vendor:publish --tag="filament-country-code-field-config"

Pin a caret on ^2.1 rather than a floating ^2.0 so you inherit the CSS path fix and PHP 8.5 support. Publishing the config is a deliberate choice: published config becomes your artifact and your upgrade liability; publish only if you actually need to override locale, ordering, or the country subset. If defaults suffice, skip the publish step and keep upgrades trivial. Commit the lockfile entry and verify the CSS asset registers correctly in the built panel — that is the one thing that has broken in production history.

Migration path.

  • Filament 3 → 4/5: the 1.x → 2.x jump is a package major tied to a Filament major. Schedule it with the Filament upgrade, not separately. The 1.x docs branch remains available for reference during the transition.
  • Existing free-text or select country columns: no data migration is required if the package stores the same encoding you already store. If it does not — the common case, where legacy rows hold dial codes or full country names — you need an explicit backfill with an idempotent mapping table and a rollback plan. Do not discover this in staging.
  • Existing league/iso3166 or symfony/intl usage: confirm the package's country list does not diverge from your validation layer, or you will create rows the validator rejects.

Compatibility and sequencing.

  1. Spike (½ day). In a branch, install, publish config, drop CountryCodeSelect into one secondary resource. Read the field's dehydrateStateUsing/formatStateUsing to answer the encoding question definitively. Write the answer into the team's data dictionary.
  2. Contract decision (with data owner). Lock the persisted format, nullability, and allowed-country subset. This is the only irreversible step.
  3. First resource (1 day). Form field + column + filter on one resource. Verify: rendering at the two supported Filament majors if the monorepo is mixed; empty-state display; filter query on null and on a subset of codes; CSS in the production build, not just vite dev.
  4. Test gate. Add one feature test asserting the column renders an empty cell without throwing (the historical regression) and one asserting the filter narrows results. This is cheap insurance against a package you do not control.
  5. Rollout. Remaining resources, batched. Keep each change a single small PR so a package-level regression is attributable and revertible.
  6. Exit rehearsal. Because you are adopting a leaf widget from a small maintainer, do a 30-minute exercise: copy the three classes into app/Filament/ and confirm the app still runs. If that is true, the dependency is reversible and the risk is bounded. If it is false, you have hidden coupling.

Operational Impact

Maintenance. Ongoing cost is close to zero in steady state — no runtime services, no data to reconcile, no cron. The cost concentrates in upgrade windows: every Filament major triggers a package major, and every PHP floor shift can force a pin (the drop of PHP 8.2 in v2.1.0 is the concrete precedent). Budget roughly half a day per Filament major plus a quarterly 15-minute check of the changelog. Because the package is small and permissively licensed, the credible worst case is a fork-and-vendor, which is a few hours rather than a few days — this should be stated explicitly in the risk register so the small maintainer base does not get over-weighted.

Support. There is no vendor SLA. Support is community/best-effort via GitHub issues, with one primary maintainer and an active Dependabot-driven maintenance loop. Treat issues as "we fix or fork" rather than "vendor responds." Internal ownership must be assigned to a named engineer on the platform team; an unowned third-party Filament widget is the classic orphan dependency. Localisation support is thin and contribution-driven (only pt_BR landed historically), so any locale beyond the defaults should be assumed to be internal work.

Scaling. No scaling dimension of consequence. The country list is a static in-process array; render cost is a select with roughly 250 options, which is negligible at any realistic admin-panel concurrency. If the list becomes searchable/AJAX-driven in a future version, re-evaluate, but the current shape is a non-issue. The filter translates to a simple where on a low-cardinality string column — index it if the table is large, but that is a database concern, not a package concern.

Failure modes to monitor.

  • Empty/null state throws on render — the historical v1.0.1 regression. Mitigate with the feature test in step 4 and by treating nullable columns as the default assumption.
  • CSS asset not registered in production build — the v2.1.1 regression. Verify in a built environment, not just HMR; add a visual check to the release checklist.
  • Encoding drift between this field and validation/phone-number logic — silent, and the most damaging failure because it corrupts data rather than breaking a page. Guard with a validator asserting the format at the model or form-request boundary.
  • Filament major bump breaks the field — loud and immediate, generally at deploy time; caught by CI if panel smoke tests exist.
  • Package abandonment — slow-onset. Detectable by a stale changelog; the fork contingency already covers it.

Ramp-up. Effectively nil. The README is complete for the three usage paths, screenshots exist for field and column/filter, and version compatibility is documented in a table — better than most packages at this size. A new engineer can use the components correctly from the README alone; the only knowledge that must be transferred verbally is the encoding contract and the fact that this is a leaf dependency eligible for vendoring. Onboarding cost: under an hour, plus the 30-minute exit rehearsal.

Recommendation. Adopt, conditional on resolving the encoding question and confirming the Filament/PHP matrix matches the target application. Scope it as a convenience dependency on a small number of resources first, assign internal ownership, add the two regression tests, and pre-agree the fork contingency. Do not let it spread to dozens of resources before the encoding contract is documented — the package itself is low-risk, but a silently inconsistent country-code column across a schema is not.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode