nramos/search-indexer
A Laravel package for adding search indexing to Eloquent models. Define indexable data, keep indexes synchronized with model events, and run flexible search queries through a simple, configurable API.
Architecture fit
The package is a Doctrine ORM entity indexer with a Meilisearch driver and a pluggable abstraction for additional backends. That framing matters more than the "Laravel/PHP package" label suggests: its natural home is a Doctrine-based application (Symfony, Laminas, or Laravel running laravel-doctrine/orm), not an Eloquent-first Laravel codebase. If our target services persist through Eloquent, the package's core value — mapping entity metadata and lifecycle events to index documents — does not apply, and we would be adopting it as a library of concepts rather than as an integration.
Where it does fit, the shape is sensible: an indexer abstraction plus a driver boundary is the right seam for supporting multiple search backends, and it keeps Meilisearch-specific concerns out of domain entities. The extension point for "other indexing systems" is the main architectural argument in its favour, and it is also the main thing we would be betting on with no evidence of anyone else having exercised it.
Integration feasibility
Technical risk
Key questions
Stack fit
Qualify per service, not per organisation. Doctrine services: green field for evaluation. Eloquent services: not a fit; stay on Scout. Mixed services (Doctrine plus Eloquent in one app) are the worst case — two indexing paths, two consistency models, and a standing source of "why is this document stale" tickets.
Migration path
Treat this as a parallel-run adoption, never a cutover:
Compatibility
Pin exact versions, not ranges, and commit the lockfile. Verify Doctrine ORM major support explicitly against our ORM version, and check the Meilisearch PHP client major the driver declares. Where the package permits a range we have not tested, narrow it in our own composer constraints rather than trusting upstream.
Sequencing
Spike and audit first (dependency tree, license, maintainer activity, driver contract). Decide second. Integrate third, behind a feature flag, on a service where search is not revenue-critical. Do not sequence this ahead of any first-party Meilisearch work already in flight — the opportunity score suggests the marginal value is low and the switching cost of abandoning a half-adopted third-party indexer is high.
Maintenance
Assume we own it. Budget for a fork-and-vendor arrangement within the first year: the package is small enough that forking is cheap, and 0 dependents means upstream will not be fixing our bugs. Assign a named owner. Track upstream via a pinned commit rather than a version constraint so drift is visible.
Support
No vendor, no community, no SLA. Internal support means internal documentation — the driver contract, the entity mapping conventions, and the reindex runbook must be written by us during the spike, not after. Ramp-up for a new engineer is effectively zero external material; the package's own docs are the only artefact and they are unvalidated by a second consumer.
Scaling
Two axes to test before commitment:
Failure modes
| Mode | Impact | Mitigation |
|---|---|---|
| Meilisearch unavailable during write | Write path blocked if synchronous | Wrap indexing in async dispatch or outbox |
| Index drifts from source of truth | Silent stale/missing results | Periodic reconciliation job comparing counts and content hashes |
| Upstream unmaintained | Security/compat drift, no fixes | Fork at adoption; internal owner |
| Abstraction leaks on second backend | Costly rework if we add a backend | Do not commit to a second backend until the first is proven |
| Entity mapping misses associated changes | Nested documents go stale | Explicitly test relation updates in the spike |
| Reindex partially completes | Duplicate or missing docs | Idempotent document IDs; resumable backfill |
Ramp-up
Low code-complexity, high context-complexity. The library is small and readable, so an engineer can understand it in a day. The expensive part is the invisible operational contract — when indexing fires, what is synchronously guaranteed, and how to repair a drifted index. Those answers do not exist publicly; we generate them once, in writing, or we pay for them repeatedly.
Recommendation
Do not adopt as a platform dependency. Run a time-boxed spike only if we have a genuine Doctrine-backed service with search needs; otherwise the opportunity score of 25.43 is the correct read. If the spike succeeds, adopt via a pinned fork with a named internal owner and an outbox-based indexing path, not via the composer package directly.
How can I help you explore Laravel packages today?