hammerstone/refine-nova
Integrate Refine's React admin framework into Laravel Nova. Build custom tools and pages with Refine components while reusing Nova resources, models, authentication, and APIs—ideal for adding rich, reactive CRUD interfaces to your Nova admin.
Prerequisites — A Laravel app running Laravel Nova (build target is Nova 4) and hammerstone/refine installed. Refine is the engine; this package is the thin Nova adapter that feeds Nova's filter state into a Refiner.
Install — composer require hammerstone/refine-nova. No service provider registration needed in modern Laravel; publish assets/config only if the README for your version says so.
Write a Refiner first — Before touching Nova, define a Refiner class (from hammerstone/refine) with filters() and sorts(). This is where 90% of your work lives; the Nova package only decides how those filters are presented and applied.
Register it on the resource — Add the package's refiner filter to filters() in your Nova resource:
public function filters(Request $request)
{
return [
new RefineFilter(UserRefiner::class),
// ...native Nova filters
];
}
First use case — Take an index page that has accumulated four or five native Nova filters (status, date range, text search, relation exists) and collapse them into one Refiner that you also reuse in your JSON API controller. That dual-use is the whole point of the package.
If you only have simple, single-column filters, stay with native Nova filters — Refine is overhead until you need composable, reusable, API-shareable filtering.
app/Refiners, then use it from the Nova filter, from API controllers (UserRefiner::for(User::class)->apply($request)->results()), and from console commands. Nova becomes one consumer, not a special case.BooleanFilter/DateFilter for the simple cases and add the Refine filter for the complex ones. They stack; Nova merges each filter's constraints into the index query.toSql() or result IDs. The Nova adapter is then a thin, low-risk layer you verify manually once.composer.json, and before upgrading Nova, smoke-test the filter on one resource. If breaking changes land upstream, budget for a fork — at 34 stars the package is small enough that vendoring the filter class and its Vue component is a realistic afternoon.filter[...] vs filters[...]). If the filter renders but does nothing, log $request->all() inside the Refiner and check the key actually arriving. This is the #1 integration bug.canSee/policy checks. If a filter exposes a column a user shouldn't see (e.g. filtering by another tenant's relation), gate it in the Refiner's filters() method based on $request->user().$query rather than calling ->results().dd($query->toSql(), $query->getBindings()) in the Refiner's apply is faster than tailing logs. The generated SQL also reveals whether your filter is using where vs whereHas correctly.How can I help you explore Laravel packages today?