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

Typesense Scout Laravel Package

siberfx/typesense-scout

A Typesense driver for Laravel Scout that adds fast, typo-tolerant full-text search to your Eloquent models. Index, filter, sort, and query records through Typesense using the familiar Scout APIs and simple model configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Verify compatibility before installing. The package targets Laravel 12/13 on PHP 8.4/8.5. Pin it explicitly and check the README/service provider namespace, since adoption is very low:

    composer require siberfx/typesense-scout
    
  2. Run Typesense locally. The fastest path is Docker:

    docker run -p 8108:8108 -v/tmp/typesense-data:/data typesense/typesense:latest \
      --data-dir /data --api-key=xyz --enable-cors
    
  3. Publish the package config and set environment variables.

    php artisan vendor:publish
    

    Look for the typesense-scout config tag/provider in the publish list, then set:

    SCOUT_DRIVER=typesense
    TYPESENSE_API_KEY=xyz
    TYPESENSE_HOST=127.0.0.1
    TYPESENSE_PORT=8108
    TYPESENSE_PROTOCOL=http
    
  4. Add Searchable to your first model. Keep toSearchableArray() explicit; do not rely on toArray() if you have relations or computed attributes.

    use Laravel\Scout\Searchable;
    
    class Article extends Model
    {
        use Searchable;
    
        public function toSearchableArray(): array
        {
            return [
                'id'         => (string) $this->id,
                'title'      => $this->title,
                'body'       => $this->body,
                'status'     => $this->status,
                'created_at' => $this->created_at->timestamp,
            ];
        }
    }
    
  5. Create the collection and import existing rows.

    php artisan scout:import "App\Models\Article"
    
  6. First use case: a search endpoint.

    $articles = Article::search('laravel typesense')
        ->where('status', 'published')
        ->paginate(20);
    

Where to look first: the package README, the published config file, the service provider, and the Typesense engine class under src/. Confirm how it maps Scout’s builder methods to Typesense search parameters before building complex filters.

Implementation Patterns

Define schemas deliberately

Typesense is schema-first. Decide field types up front and keep them in sync with toSearchableArray():

  • Strings: string, string[]
  • Numbers: int32, int64, float
  • Booleans: bool
  • Dates: store as int64 Unix timestamps, not formatted date strings
  • Nested relations: use object / object[] and enable nested fields in the collection schema

Use searchableAs() when the default table-based collection name is not what you want:

public function searchableAs(): string
{
    return 'articles';
}

Use Scout’s query builder for common cases

Typical day-to-day filters and sorting:

$results = Product::search($term)
    ->where('is_active', true)
    ->whereIn('category_id', $categoryIds)
    ->where('price', '>=', 100)
    ->orderBy('popularity', 'desc')
    ->paginate(24);

Eager-load database relations after search hydration:

$products = Product::search($term)
    ->query(fn ($query) => $query->with('category', 'media'))
    ->paginate(24);

Pass Typesense-specific options for relevance tuning

Search quality usually depends on query_by, field weights, typo tolerance, and token dropping. Use the driver’s option/parameter API where available; otherwise call the engine directly.

$results = Article::search($term)
    ->options([
        'query_by' => 'title,body,tags',
        'query_by_weights' => '4,2,1',
        'num_typos' => 1,
        'drop_tokens_threshold' => 1,
    ])
    ->paginate(20);

Queue indexing for writes

In production, avoid synchronous indexing on every model save:

SCOUT_QUEUE=true

Use a queue connection with after_commit enabled so workers do not index rows before the database transaction commits. For bulk changes, prefer scout:import over saving thousands of models individually.

Control indexing explicitly

Useful for imports, migrations, and bulk updates:

Article::withoutSyncingToSearch(function () {
    // bulk database work
});

$article->searchable();   // index one model
$article->unsearchable(); // remove one model

Keep the database as the source of truth

Scout returns hydrated Eloquent models, but Typesense is not a relational database. For complex authorization, joins, or aggregates, search first for IDs, then constrain the final Eloquent query:

$ids = Article::search($term)->take(200)->get()->modelKeys();

$articles = Article::query()
    ->whereIn('id', $ids)
    ->where('tenant_id', tenant()->id)
    ->with('author')
    ->paginate(20);

Expose search safely to the frontend

If you use Typesense directly from JavaScript, issue a search-only API key scoped to specific collections. Never ship the admin key to the browser.

Gotchas and Tips

  • Schema changes are not automatic. Adding or changing a field in toSearchableArray() usually requires recreating the collection and reimporting: scout:flush then scout:import. Plan for zero-downtime reindexing via collection aliases if search is critical.
  • IDs must be strings. Typesense expects the id field as a string. Cast (string) $this->id in toSearchableArray().
  • Dates need care. Store timestamps as integers; formatted date strings will sort and filter incorrectly.
  • Nested data is easy to get wrong. If you index related objects, the Typesense schema must define them as object or object[] and nested fields must be enabled. Flattening data is often simpler.
  • Do not rely on toArray(). It can include relations, hidden fields, appended attributes, and nulls that break the schema. Build the search payload explicitly.
  • Soft deletes need explicit handling. Confirm the package removes soft-deleted models from the index; otherwise stale results will appear. Test delete() and restore() behavior.
  • Queue and transactions can race. Enable after_commit on the queue connection and monitor failed indexing jobs. A row can exist in MySQL but be missing from Typesense.
  • Pagination limits apply. Typesense caps per_page (commonly 250). Scout pagination still works, but do not request huge pages.
  • Config caching hides env changes. After changing Typesense credentials or driver settings, run php artisan config:clear.
  • Debug at the Typesense layer. Use curl or the Typesense dashboard to inspect collection schemas and documents. If Scout returns nothing, check whether the collection exists, whether documents are present, and whether query_by fields match the schema.
  • Log import failures. scout:import can fail on a single malformed document. Run it in chunks and inspect the first failure rather than assuming the whole import succeeded.
  • Low adoption is a real risk. With one star, zero dependents, and a very new release, treat this package as young infrastructure: pin the exact version, read the engine source, add integration tests against a real Typesense container, and be prepared to fork or switch to Laravel Scout’s official Typesense driver if compatibility or maintenance becomes a problem.
  • Test with a real Typesense instance. Mocking search hides schema, typo, and filtering behavior. Use a Docker service in CI and flush/import fixtures between tests.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo