From Project-Based Datatable to Laravel Composer Package
How I turned my Laravel Inertia Datatable project implementation into a reusable Composer package for server-side search, filters, sorting, relations, and pagination.

From Project-Based Datatable to Laravel Composer Package
I recently created a standalone Laravel Composer package called raprmdn/laravel-inertia-datatables.
This package started from my older project-based implementation: laravel-inertia-datatable.
The original version was built as a complete Laravel, Inertia, React, Tailwind, and shadcn/ui project. It worked as a full implementation, but the backend datatable logic was reusable enough that it should not stay locked inside one project.
So I extracted the core logic into a Composer package.
Package: Packagist
Source Code: GitHub
The Problem
Datatable logic is repeated in many Laravel applications.
Most admin panels and internal tools need similar features:
- Search
- Filters
- Date range filters
- Sorting
- Pagination
- Relationship columns
- Configurable limits
At first, this logic usually lives directly inside controllers. But after building multiple tables, the same patterns keep repeating.
That was the main reason I wanted to create a package.
Why I Extracted It
The original repository was useful as a project example, but it was not flexible enough to reuse in other applications.
If I wanted the same datatable behavior in another Laravel project, I would need to copy the code manually.
That creates a few problems:
- Duplicate logic
- Harder maintenance
- Inconsistent implementation between projects
- More controller code than necessary
By moving the datatable logic into a package, I can reuse the same backend behavior across different Laravel applications.
Why Backend First?
Even though the package name includes Inertia, the current version is backend-first.
It can be used with:
- Inertia
- API resources
- Blade
- JSON responses
- Custom Laravel responses
The frontend components are planned for a future release, but the most important part is the backend query behavior.
The backend is where search, filters, sorting, relations, and pagination need to be handled safely and consistently.
Basic Usage
Install the package using Composer:
composer require raprmdn/laravel-inertia-datatablesPublish the configuration file:
php artisan vendor:publish --tag=inertia-datatables-configThen use the DataTable facade:
use App\Models\User;
use Raprmdn\DataTables\Facades\DataTable;
$users = DataTable::query(User::query())
->searchable(['name', 'email'])
->orderBy('created_at', 'desc')
->make();Filters and Sorting
The package supports safe filter and sort mappings.
use Raprmdn\DataTables\Facades\DataTable;
$filterColumns = [
'status' => 'status',
'priority' => 'priority.name',
];
[$columnFilters, $dateRanges] = DataTable::parseFilters(
$request->query('filters', []),
$filterColumns
);
$sortColumns = [
'name' => 'name',
'email' => 'email',
'created_at' => 'created_at',
];
[$sort, $allowedSorts] = DataTable::parseSort(
$request->query('col'),
$sortColumns
);
$users = DataTable::query(User::query())
->searchable(['name', 'email'])
->applyFilters($columnFilters)
->allowedFilters(array_values($filterColumns))
->applySort($sort)
->allowedSorts($allowedSorts)
->orderBy('created_at', 'desc')
->make();This keeps request parameters simple while still letting the backend control which columns are allowed.
Relationship Support
The package also supports relationship columns using dot notation.
DataTable::query($query)
->with(['contact.channel', 'priority'])
->searchable([
'number',
'contact.name',
'contact.email',
'contact.phone',
])
->make();For example:
'contact.name'means:
contactis the relationship method on the modelnameis the column on the related table
This is useful for admin panels where table data often comes from multiple related models.
What Changed From the Old Project?
The old repository was a full project implementation. The new package is focused on reusable backend logic.
Some important changes:
- Moved the datatable logic into a Composer package
- Added the
Raprmdn\DataTablesnamespace - Added Laravel auto-discovery support
- Added a service provider
- Added a facade API
- Added publishable configuration
- Added filter and sort parser helpers
- Separated backend logic from frontend components
The old project answers:
How does this datatable work in one Laravel Inertia app?
The new package answers:
How can this datatable logic be reused across Laravel apps?
Current Limitations
The package is still in beta.
Current limitations:
- The public API may still change before
v1.0.0 - Frontend starter components are not included yet
- Advanced filter operators are not implemented yet
- Relation sorting does not support every relation type
- Automated tests are still planned
Roadmap
Next improvements I want to work on:
- Add automated tests
- Improve documentation
- Add more filter operators
- Add optional Inertia React starter components
- Add a column definitions API
Final Thoughts
This package is still early, but it already solves the main problem I wanted to fix: reducing repeated datatable query logic in Laravel controllers.
The original project will remain as the project-based implementation and will be updated to use the standalone Composer package in a future release.
Building the feature inside a real project first helped me understand the problem better. After that, extracting it into a package felt much clearer.
Links: