PHPackages                             ykan/elastickit-laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. ykan/elastickit-laravel

ActiveLibrary[Search &amp; Filtering](/categories/search)

ykan/elastickit-laravel
=======================

Laravel integration for ElasticKit: client bootstrapping and native pagination.

v1.0.0-beta.1(today)10MITPHPPHP ^8.1CI failing

Since Jun 30Pushed todayCompare

[ Source](https://github.com/ykan821/ElasticKitLaravel)[ Packagist](https://packagist.org/packages/ykan/elastickit-laravel)[ RSS](/packages/ykan-elastickit-laravel/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (7)Versions (2)Used By (0)

ElasticKit Laravel
==================

[](#elastickit-laravel)

Laravel integration for [ElasticKit](https://github.com/ykan821/ElasticKit) — wires up the Elasticsearch client from config and bridges ElasticKit's pagination to Laravel's native paginator.

Installation
------------

[](#installation)

Requires PHP 8.1+, Laravel 10.x–12.x, and Elasticsearch 8.x.

```
composer require ykan/elastickit-laravel

```

ElasticKit (the framework-agnostic core) is pulled in automatically as a dependency of this package — you require only this one. The service provider is **auto-discovered**; no manual registration is needed.

Publish the config:

```
php artisan vendor:publish --tag=elastickit-config

```

Then set your cluster credentials (`.env`):

```
ELASTICKIT_HOST=http://localhost:9200
# Elastic Cloud / serverless:
# ELASTICKIT_CLOUD_ID=...
# ELASTICKIT_API_KEY=...
# ELASTICKIT_API_KEY_ID=...
# Traditional secured cluster:
# ELASTICKIT_USERNAME=elastic
# ELASTICKIT_PASSWORD=...

```

What it does
------------

[](#what-it-does)

- Builds the Elasticsearch client from `config('elastickit.connections')` and registers each via `Index::setClient($client, $name)` (multi-connection supported).
- Registers a **page resolver**, so `paginate()` with no arguments reads `?page` / `?per_page` from the request automatically (`perPage` is still capped by each index's `maxPerPage()`).
- Registers a **paginator resolver**, so `Results::toPaginator()` returns a Laravel `LengthAwarePaginator`.

Usage
-----

[](#usage)

```
use ElasticKit\Index\Index;

class ProductIndex extends Index
{
    protected string $name = 'products';
}

// compound bool query, paginated → native Laravel LengthAwarePaginator
$results = ProductIndex::query()
    ->bool([
        'must'   => fn ($q) => $q->match('title', 'shoes'),
        'filter' => fn ($q) => $q
            ->range('price', [10, 100])
            ->when($status, fn ($q) => $q->term('status', $status))  // conditional clause
            ->term('status', 'published'),
    ])
    ->highlight('title')
    ->sort('price', 'asc')
    ->paginate($page, $perPage);   // or ->paginate() to read from the request

$results->total();                 // hit count
$results->toPaginator()->links();  // native Laravel pagination UI
```

Artisan commands
----------------

[](#artisan-commands)

Pass an Index class FQCN, or optionally map short aliases in `config/elastickit.php`:

```
'indices' => [
    'products' => \App\Search\ProductIndex::class,
],
```

**Index management**

CommandDescriptionOptions`php artisan elastickit:index:create products`Create the index with its mappings—`php artisan elastickit:mapping:put products`Push mapping changes to an existing index—`php artisan elastickit:index:exists products`Check existence — exit code 0 = exists—`php artisan elastickit:index:delete products`Delete the index`--force`**Zero-downtime rebuild**

CommandDescriptionOptions`php artisan elastickit:rebuild products`Build a new backing index, import via `Index::source()`, swap the alias`--clean`, `--batch-size=`, `--allow-empty`, `--context=``php artisan elastickit:rebuild:rollback products `Point the alias back at a previous backing index—`php artisan elastickit:rebuild:clean products `Delete a leftover backing index`--force``php artisan elastickit:rebuild:unlock products`Release a lock left by a crashed rebuild—`--clean` removes the previous backing index right after the swap.

**Passing context to `source()`**

`--context=key=value` (repeatable) is forwarded to `Index::source()` as an associative array — handy for incremental or filtered rebuilds. Values are strings; cast inside `source()`:

```
php artisan elastickit:rebuild products --context=since=2026-06-01 --context=limit=1000

```

```
public function source(array $context = []): iterable
{
    $query = Product::query();
    if ($since = $context['since'] ?? null) {
        $query->where('updated_at', '>', $since);
    }
    if ($limit = $context['limit'] ?? null) {
        $query->limit((int) $limit);
    }
    foreach ($query->cursor() as $p) {
        yield $p->id => $p->toArray();
    }
}
```

> Prefer `elastickit:rebuild` for first-time setup if you ever want zero-downtime rebuilds: it bootstraps via an alias, while `index:create` makes a plain index that `rebuild` cannot swap.

**Handling import errors**

By default, a bulk import error aborts the rebuild (the new backing index is deleted). To customize — skip failed items, log them, or retry — set `rebuild.on_error` in the published config to an invokable class:

```
// config/elastickit.php
'rebuild' => [
    'on_error' => \App\Search\ImportErrorHandler::class,
],
```

```
// app/Search/ImportErrorHandler.php
use ElasticKit\Index\Bulk;

class ImportErrorHandler
{
    public function __invoke(array $response, array $actions, Bulk $newbulk): void
    {
        foreach ($response['items'] ?? [] as $item) {
            if (isset($item['index']['error'])) {
                logger('elastickit import failed', ['id' => $item['index']['_id'] ?? null]);
            }
        }
        // return → drop the failed items and continue
        // throw  → abort the rebuild
        // re-send on $newbulk, then $newbulk->flush() → retry
    }
}
```

**Per-index handlers**

For index-specific error handling, implement `HasRebuildErrorHandler` on the Index subclass — it overrides the global `rebuild.on_error` for that index only:

```
use ElasticKit\Index\Bulk;
use ElasticKit\Index\Index;
use ElasticKit\Laravel\Console\HasRebuildErrorHandler;

class ProductIndex extends Index implements HasRebuildErrorHandler
{
    protected string $name = 'products';

    public function rebuildErrorHandler(): callable
    {
        return function (array $response, array $actions, Bulk $newbulk): void {
            // per-index logic; same contract as the global handler
        };
    }
}
```

**Replacing the rebuild command**

To take over the `elastickit:rebuild` name entirely (custom `handle()`, extra options, etc), set `rebuild.command` to a `RebuildCommand` subclass — the provider registers yours instead of its default:

```
// config/elastickit.php
'rebuild' => [
    'command' => \App\Console\Commands\CustomRebuildCommand::class,
],
```

```
use ElasticKit\Laravel\Console\RebuildCommand;

class CustomRebuildCommand extends RebuildCommand
{
    // inherit the elastickit:rebuild signature; override handle().
    // stopIndicator() and parseContext() are protected — reuse them from your handle().
}
```

Configuration
-------------

[](#configuration)

See `config/elastickit.php` after publishing. Define additional connections under `connections`and target one from an Index subclass:

```
class ArchiveIndex extends Index
{
    protected string $name = 'archive';
    protected string $connection = 'archive';
}
```

Todo
----

[](#todo)

- Documentation sync — Eloquent auto-sync (`IndexesTo`) model trait.

License
-------

[](#license)

MIT

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity28

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/120786616?v=4)[ykan](/maintainers/ykan821)[@ykan821](https://github.com/ykan821)

---

Top Contributors

[![ykan821](https://avatars.githubusercontent.com/u/120786616?v=4)](https://github.com/ykan821 "ykan821 (4 commits)")

---

Tags

builderdslelastickitelasticsearchlaravelquerylaravelelasticsearchquerybuilderDSLelastickit

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ykan-elastickit-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/ykan-elastickit-laravel/health.svg)](https://phpackages.com/packages/ykan-elastickit-laravel)
```

###  Alternatives

[mailerlite/laravel-elasticsearch

An easy way to use the official PHP ElasticSearch client in your Laravel applications.

935572.3k2](/packages/mailerlite-laravel-elasticsearch)[tallstackui/tallstackui

TallStackUI is a powerful suite of Blade components that elevate your workflow of Livewire applications.

721160.4k12](/packages/tallstackui-tallstackui)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

1.0k2.1M169](/packages/laravel-ai)[api-platform/laravel

API Platform support for Laravel

59156.3k11](/packages/api-platform-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
