Product Decisions This Supports
- "Do we build custom fields or buy them?" — This is the core decision this package collapses. A homegrown user-defined-field system means an EAV schema, 20+ input types, validation, conditional logic, per-tenant isolation, a Filament admin UI for managing definitions, and CSV import/export. That is a multi-quarter subsystem. The package converts it into a plugin registration, a trait, and a
CustomFields::form()->build() call. For most teams this is the single highest-leverage build-vs-buy line item in a B2B admin product.
- Enterprise/CRM-tier roadmap expansion — "Can we add a field for that?" is the most common blocker to closing mid-market and enterprise deals. Shipping customer-defined fields unlocks a paid tier, removes a recurring sales objection, and turns bespoke integration requests into self-serve configuration instead of engineering tickets.
- Vertical market entry — One codebase with tenant-scoped field definitions can serve recruiters, agencies, clinics, and logistics customers simultaneously without forking the schema. This is a market expansion decision, not just a feature decision, and it's the clearest strategic reason to adopt.
- Feature-scoping under uncertainty — When you don't yet know which attributes matter (deal stages, candidate properties, asset metadata), shipping a flexible field system lets you defer the schema decision and learn from real usage instead of guessing in a migration.
- Deprioritizing the metadata subsystem — Adopting this explicitly frees engineering capacity. Frame it as reallocating N engineer-months from plumbing to your actual differentiator; that's the roadmap trade you're making.
- Multi-tenancy and compliance posture — Built-in tenant isolation plus optional per-field encryption supports "each customer's schema is invisible to others" and "PII fields are encrypted at rest" commitments that are otherwise expensive to retrofit after a security review.
- Procurement/commercial decision — AGPL-3.0 means a commercial license is mandatory for closed-source SaaS. That is a line item, a vendor relationship, and a renewal risk — treat it as part of the roadmap decision, not an afterthought.
When to Consider This Package
Adopt when most of these are true:
- You are on Filament 5, Laravel 12/13, PHP 8.3+. This is not optional — the package tracks Filament majors aggressively (v2 → Filament 4, v3 → Filament 5 + Laravel 12), so you inherit its upgrade clock.
- Your admin/back-office surface is Filament-based and the custom fields are for internal users or tenant admins, not a bespoke public API.
- You have, or can secure, a commercial license budget. AGPL-3.0 with a dual commercial model is a hard gate for any closed-source product; the license terms, not the code, are the deciding factor.
- Your tenants are B2B with meaningfully different data models — the multi-tenancy story is the strongest part of the value proposition.
- You want conditional field visibility, file uploads, rich text, and CSV round-tripping without building each one.
- Engineering has appetite to validate the data layer (see risk below) but not to own the subsystem.
Look elsewhere / build when:
- Not on Filament 5. Earlier versions exist but you'd be adopting a version the maintainer has already moved past. Check the version matrix before anything else.
- AGPL is incompatible and commercial licensing isn't viable — for a side project, a public-sector procurement process, or an org that cannot add vendor licenses, this is disqualifying regardless of quality.
- Custom fields are a core product differentiator. If the data model is your product, keeping it inside a third-party package means ceding control of your moat and your query surface.
- You need heavy querying, filtering, and reporting across custom field values at scale — EAV storage is structurally weaker than native columns for analytics, sorting, and indexing. Benchmark against your expected row counts and query patterns before committing.
- You need a public/partner API over custom field data with strict schema contracts and versioning; the Filament-centric design won't carry that load for you.
- Vendor concentration is unacceptable. 168 stars,
dependents: 0 on Packagist, and an apparently single-maintainer release history imply real bus-factor risk for a subsystem that will hold customer data. That's tolerable for a convenience plugin; it deserves scrutiny for a load-bearing one.
Diligence checklist before signing off:
- Run a spike: one model, all field types you actually need, export/import round-trip, and a restore from a database dump.
- Confirm how values are stored and whether you can export the full definitions + values schema cleanly — this is your escape hatch and your negotiating position.
- Get the license terms reviewed by legal, including what happens to already-shipped code if you later stop paying.
- Check upgrade cost by reading the 3.0 release notes: phone and email storage formats changed to JSON and needed a migration command. Assume one forced migration per major.
- Ask what happens on a Filament major upgrade; the package has forced two in its history.
Quality signals in its favor: disciplined changelog discipline, a custom-fields-upgrade migration command for breaking changes, config blocks added with defaults that preserve prior behavior (v3.8.0 explicitly makes 3.7 behavior restorable), and engineering rigor unusual for a plugin of this size — the 3.8.0 notes ship EXPLAIN (ANALYZE, BUFFERS) benchmarks showing deterministic ordering costs nothing (0.036 ms vs 0.043 ms) and that an unindexed updated_at sort would cost 7.59 ms. That is a maintainer who measures before shipping and thinks about downstream upgrades.
How to Pitch It (Stakeholders)
For executives — one paragraph:
We have a recurring revenue blocker: customers ask for fields and workflows that don't exist in our schema, and each request becomes an engineering ticket. relaticle/custom-fields is a mature Laravel/Filament plugin that gives us customer-defined fields — 20+ types, conditional visibility, per-tenant isolation, encryption, CSV import/export — without building and maintaining that subsystem ourselves. It replaces an estimated multi-quarter internal build with a plugin integration and an ongoing commercial license. The trade-offs are honest: it is AGPL-licensed, so closed-source use requires a paid commercial license; it requires Filament 5 and Laravel 12+; and it is maintained by a very small team, so we should keep a clean export path. Recommendation: approve a two-week spike with legal review of the license in parallel, and decide on a paid-tier rollout after.
For engineering — the short version:
- Integration is small and surgical: register
CustomFieldsPlugin::make() on the panel, add UsesCustomFields + HasCustomFields to the model, drop CustomFields::form()->build() into the schema. Tables and infolists have equivalent builders.
- Storage is EAV-style in package-owned tables; values are accessed through the trait. Field types are extensible with auto-discovery via
BaseFieldType/FieldSchema, so custom types are a supported path rather than a fork.
- Expect to own the upgrade path on Filament majors — the package has already forced two, and v3.0 changed phone/email to structured JSON with a
custom-fields-upgrade command. Budget for it.
- Known sharp edges to test before committing: uniqueness/validation rules on non-scalar values,
$guarded models, MariaDB behavior, and query performance for filtering/sorting on custom values at your data volume.
- The 3.8.0 release is a good proxy for maintainer quality: benchmarked query plans, config-driven behavior with explicit pre-3.8 opt-outs, and no breakage for existing published configs.
The decision to make: approve a time-boxed spike plus license review, not an immediate commitment. Success criteria should be a working end-to-end slice on a real tenant, a verified data export, and a legal sign-off on the commercial terms — with an explicit fallback of a narrow, hand-rolled field system for the two or three types you actually need if any of those fail.