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

Search Laravel Package

trinity/search

A Laravel package that adds search capabilities to your Eloquent models. It offers a simple API for indexing and querying records, letting you wire up search across your application with minimal configuration and without pulling in an external search service.

View on GitHub
Deep Wiki
Context7

Getting Started

trinity/search is a 2017-era Laravel search package (last release December 2017, no dependents, effectively unmaintained). Before you build anything on it, spend ten minutes reading the repository source rather than its README — at this age the README likely describes a Laravel 5.x install flow that no longer matches current Laravel.

Minimal steps:

  1. Confirm compatibility first. Check composer.json in the repo for the illuminate/* constraint. If it caps at 5.4/5.5, do not attempt it on Laravel 9+ without a fork — the service provider, facade, and any Str/Arr helpers it calls are the usual breakpoints.
  2. Install and register. On Laravel ≤5.4 you will almost certainly need to add the service provider to config/app.php and alias the facade manually; package auto-discovery only became standard in 5.5, so don't assume it works.
  3. Publish and inspect the config. Run the package's publish command (typically php artisan vendor:publish --provider="...TrinitySearchServiceProvider"), then read the generated config to learn which driver it uses (database index table vs. an external engine). This config is the single most important file for understanding the package's behavior.
  4. First use case. The intended entry point is: make one existing Eloquent model "searchable" via a trait or interface, index its existing rows, then execute a keyword query that returns ranked models. Start with one small table — a few hundred rows — so you can verify ranking and freshness end-to-end before committing.

If step 1 fails, stop. The realistic decision at a 1-star/0-dependent/2017 baseline is "use this as reference implementation, not a dependency."

Implementation Patterns

Trait-on-model indexing. The standard shape for packages of this vintage is a Searchable trait added to a model, exposing something like toSearchableArray() (the fields actually written to the index). Keep that array deliberately narrow — only the columns you filter or rank on. Pulling in relations here is where indexing gets slow and stale.

Event-driven synchronization. Expect the package to hook saved/deleted model events to keep the index current. That means indexing failures happen inside your normal save path. Wrap write operations so a search-index failure doesn't roll back a user's actual data write, or override the hooks to dispatch a queued job instead.

Query-then-hydrate. The typical flow is: run the search against the index, get an ordered list of model keys, then whereIn those keys back through Eloquent. Preserve the index's ordering yourself — a whereIn will not return rows in rank order. This is the pattern to build your own repository/service around so controllers never see raw index results.

Service/repository boundary. Wrap the package behind your own SearchService interface with index($model), remove($model), and search($term, $filters). Given the package's maintenance status, this boundary is what lets you swap in Scout, Meilisearch, or a raw MATCH AGAINST query later without touching call sites. Treat it as a migration insurance policy, not architecture astronautics.

Backfill as a command. Any indexing package needs a reindex command for existing rows. If the package ships one, wrap it in your own Artisan command that chunks by ID (e.g., 500 at a time) so you can run it idempotently after schema changes or a driver swap.

Filters alongside free text. Most day-to-day use is "keyword plus constraints" (status, tenant, date range). Implement filters as a separate scoped query layered on top of the key list, not inside the index, unless the package clearly supports faceting.

Gotchas and Tips

  • Abandonment is the headline gotcha. No releases since 2017 and zero dependents means no security patches, no Laravel 8/9/10 compatibility, and no community answers when it breaks. Budget for a fork you own, or pick a maintained alternative.
  • Auto-discovery assumptions. Older packages require manual provider registration. A Class not found on boot is usually a missing entry in config/app.php, not a broken install.
  • Stale indexes are silent. After a bulk update via Model::where(...)->update(...), model events do not fire, so the index drifts. Use save() in loops, or explicitly reindex after any mass update.
  • Ranking surprises. Database-backed search drivers often fall back to LIKE matching, which ignores relevance. Verify what the configured driver actually does before promising users "relevance-ranked" results.
  • Debugging path. Log the generated index query and the key list returned. Nine out of ten "search returns nothing" reports are either (a) rows never indexed, or (b) a whereIn on the wrong primary key / soft-deleted rows being filtered out during hydration.
  • Soft deletes. Check whether the package's event hooks fire on soft delete. If they only hook deleted, soft-deleted records linger in results and then vanish during hydration, producing short pages.
  • Config quirks. Driver and index-name settings are easy to leave at defaults across environments. Pin them per-environment in .env so staging never writes into a production index.
  • Extension points to look for. toSearchableArray() (field selection), a custom index-name method (multi-tenant partitioning), and any driver binding in the service provider. These are your levers if you do fork it.
  • Verdict for day-to-day use. Useful as a compact reference for how event-driven indexing is wired in Laravel; risky as a production dependency. If you keep it, own the fork and pin the Laravel version explicitly in composer.json.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource