kerrialnewham/autocomplete
Laravel autocomplete package that makes it easy to add typeahead-style search to your app. Configure searchable model fields, query matching records, and return JSON results ready for any frontend autocomplete widget, with minimal setup and a clean, framework-friendly API.
Architecture fit — primary finding: this is not a Laravel package. kerrialnewham/autocomplete is a Symfony bundle built on Symfony UX / Stimulus. It ships a bundle class registered through the Symfony kernel, Twig templates, Symfony DI service definitions, and Stimulus controllers intended to be wired via Symfony's AssetMapper/Webpack Encore integration. Laravel has no equivalent bundle registration path (no Kernel::registerBundles(), no Twig by default, no Symfony UX bridge). Any Laravel adoption is therefore a port or a partial reuse, not an install.
wire:model.live or a plain JSON endpoint + Alpine. Choosing this package means choosing a non-idiomatic third path.Integration feasibility. Feasible at roughly 2–4 engineer-days for a thin first slice, assuming the JS controller is cleanly decoupled:
@hotwired/stimulus via Vite/npm, register the package's controller, keep the data-controller/data-action attributes.Configuration tree → config/autocomplete.php) and DI bindings (bundle services.yaml → a service provider).The blocker is step 1–2 fidelity: without reading the actual controller and endpoint contract we cannot confirm whether the JS is hard-coupled to Symfony-specific URL generation, CSRF tokens, or response envelopes.
Technical risk — high, concentrated in maturity and coupling.
LIKE construction, XSS via unescaped fragment rendering, and enumeration/data-leak risk if the endpoint returns more than intended.Key questions to resolve before committing:
Stack fit — the honest assessment is "poor fit, salvageable components." Our stack is Laravel + Blade + Vite + Alpine (assumed). This package targets Symfony + Twig + Stimulus. Overlap is limited to the browser-side controller and the endpoint design. We should treat the package as a reference implementation to port, not a dependency to install.
Three options, in order of recommendation:
composer.json. Cost: one controller's worth of adaptation.Configuration → config/autocomplete.php, Symfony HttpClient → Laravel Http facade. Gives us a first-class internal package, but we now own a fork with a single upstream author and no dependents. Only justified if we need the feature in ≥2 applications.Migration path (Option A):
HasAutocomplete trait or query scope.Compatibility gates:
data-* attributes. Scope Stimulus to a single root element to avoid attribute collision and double-initialization.GET (read-only, cacheable, no CSRF token needed) or explicitly CSRF-exempted with rate limiting. Do not port a Symfony CSRF assumption blindly.Sequencing. Do the Livewire benchmark and the controller audit in parallel, in week one. Only proceed to Option A if the audit shows a clean JS contract and the Livewire spike underperforms on a real requirement (e.g., fragment-level caching, or a specific interaction Livewire handles poorly). Otherwise stop — the correct TPM output here is "evaluated and declined," documented.
Maintenance. Highest ongoing cost in the assessment. A fork means we absorb every upstream change manually with no dependents to validate against and a single-maintainer upstream whose release cadence is unproven. Budget ~10–15% of one engineer's time indefinitely for Option B; near-zero for Option A (a scoped JS controller is cheap to own, and if it rots we replace it in a day). The 6-star, 0-dependent profile means we should assume the package may be abandoned and plan for that as the base case, not the tail risk.
Support. GitHub issues only — no SLA, no commercial backing, no Stack Overflow corpus. Internal escalation path is "read the source." This is acceptable for a thin JS controller and unacceptable for anything in a critical path.
Scaling. Server-side-rendered autocomplete is latency-bound and query-bound, not CPU-bound:
LIKE '%term%' on MySQL will not use a B-tree index and will degrade non-linearly. Plan on a FULLTEXT index, a trigram index, or an external search service (Meilisearch/Scout) from day one — not as a follow-up.Failure modes to design against:
{{ }} escaping must be preserved — the Symfony/Twig version's escaping guarantees do not transfer.Ramp-up. Low technical ramp-up (small, readable codebase; Stimulus is a ~1-day learn if the team knows Alpine) but two-axis unfamiliarity: the team must reason about both Symfony conventions and Stimulus lifecycle to port correctly. One engineer can own this; it should not be spread across the team.
Recommendation. Do not adopt as a dependency. Run a one-week, time-boxed evaluation: audit the Stimulus controller contract and benchmark Livewire against the same requirement. Default to Livewire or Alpine (native to our stack, mature ecosystem, no cross-framework translation layer). Pursue Option A only if the audit reveals a genuinely reusable, framework-agnostic controller and a requirement Livewire cannot meet — in which case, fork, vendor, pin to a SHA, and treat the upstream as a one-time reference rather than a maintained dependency.
How can I help you explore Laravel packages today?