Free Laravel Inertia
Tables for Vue.
Zonvoir Table is a free, open-source Laravel Inertia table package for Vue applications. Define tables in PHP using Eloquent, then render searchable, sortable, paginated tables with the Vue adapter.
Tables that speak Laravel.


The capability ledger
Every row, accounted for.
Zonvoir Table's own feature set, kept in the same format your users will see it in.
PHP Backend + Vue Adapter
Define in PHP. Render in Vue.
A single PHP class defines the Eloquent query, columns, URL state, row actions, and exports. In Vue, the first-party adapter renders a responsive, interactive data table with zero boilerplate.
1 use App\Models\User;
2 use Zonvoir\InertiaTable\Columns\TextColumn;
3 use Zonvoir\InertiaTable\Table;
4
5 final class UsersTable extends Table
6 {
7 protected ?string $resource = User::class;
8 protected ?string $defaultSort = 'name';
9
10 public function columns(): array
11 {
12 return [
13 TextColumn::make('name')->searchable()->sortable(),
14 TextColumn::make('email')->searchable(),
15 ];
16 }
17 }
1 <script setup lang="ts">
2 import { ZonvoirTable, type TableResource } from '@zonvoir/inertia-table-vue';
3
4 defineProps<{ users: TableResource }>();
5 </script>
6
7 <template>
8 <ZonvoirTable :table="users" />
9 </template>
Features
Built for every row. Ready for every workflow.
# Built-in Table Definition
One PHP class drives the query, columns, URL state, row actions, exports, and frontend metadata.
- Resolve an Eloquent model class or query builder.
- Return typed column, action, and export definitions.
- Serialize a stable payload for Inertia.
1 UsersTable::make();# Search State
Search can be table-level, column-level, or customized with callbacks in the query builder layer.
- Set searchable fields on the table.
- Mark individual columns as searchable.
- Keep search state in the query string.
1 protected array|string|null $search = ['name', 'email'];
2
3 TextColumn::make('name')->searchable();# Sorting
Sortable columns expose direction-aware query state while the backend stays in charge of the query.
- Enable sorting per column.
- Use `-column` for descending defaults.
- Override sorting with `sortUsing()` when needed.
1 protected ?string $defaultSort = '-created_at';
2
3 TextColumn::make('name')->sortable();# Pagination
Pagination configuration lives with the table, including allowed page sizes and pagination strategy.
- Standard, simple, and cursor modes.
- Configurable per-page options.
- Normalized page, cursor, and per-page input.
1 protected ?int $defaultPerPage = 30;
2 protected ?array $perPageOptions = [15, 30, 50];# Row Actions & Links
Actions and row URLs are serialized as metadata so Vue can render the right controls.
- Return actions from `actions()`.
- Use `Url` for route and Inertia metadata.
- Support authorization, disabled, hidden, and confirm states.
1 Action::make('Edit')
2 ->url(fn ($user, $url) => $url->route('users.edit', $user));# Bulk Actions
Bulk actions reuse the action API and execute against selected row keys.
- Enable bulk mode with `asBulkAction()`.
- Use `onlyAsBulkAction()` for bulk-only flows.
- Control chunk size and strategy.
1 Action::make('Archive')
2 ->asBulkAction(chunkSize: 100)
3 ->confirm('Archive users?');# Columns
One Columns guide covers common options plus text, numeric, boolean, badge, image, date, date-time, and action columns.
- Shared visibility, sizing, sticky, search, and sort metadata.
- Column-specific display settings.
- Export labels, values, formats, and styles.
1 BadgeColumn::make('status')
2 ->colors(['active' => 'success'])
3 ->solid();# Sticky Columns
Sticky columns keep high-value identifiers visible while users scan wide data sets.
- Enable sticky behavior per column.
- Pair with width metadata for predictable layout.
- Allow sticky overrides through table state.
1 TextColumn::make('name')
2 ->sticky()
3 ->width('16rem');# Excel Exports
Return export definitions from the table and choose filtered or selected-row export scope.
- Expose export controls in table metadata.
- Limit to filtered or selected rows.
- Queue large exports when needed.
1 Export::make('Users', 'users.xlsx')
2 ->limitToFilteredRows();# URL State
Table state is represented in query string keys for page, per-page, cursor, search, sort, direction, columns, and sticky overrides.
- Name tables to namespace query state.
- Generate navigation URLs from the current state.
- Keep reloads and browser history predictable.
1 $table->navigation()->search('olivia');
2 $table->navigation()->sort('name');# Multiple Tables
Name each table to avoid query string collisions when a page renders more than one table.
- Use `named()` or `as()`.
- Separate page, search, sort, columns, and sticky state.
- Render multiple independent table payloads.
1 UsersTable::make()->named('users')->results();
2 OrdersTable::make()->named('orders')->results();Start with a real table
Create a table, render it, then add behavior feature by feature.
Understand the moving parts
Columns, state, row links, selection, pagination, and payload shape.
Check exact signatures
Classes, methods, enum cases, callback signatures, and Vue exports.
100% Free & Open Source
Complete Laravel Inertia Table functionality. Zero paywalls.
Zonvoir Table is published under the permissive Apache License 2.0. Both the Laravel Eloquent backend package (zonvoir/laravel-inertia-table) and the Inertia Vue 3 adapter (@zonvoir/inertia-table-vue) are completely free for personal and commercial applications.
Live Server-Side Search
Global table search and column-specific filters orchestrated directly through Eloquent queries with query-string synchronization.
Searching Guide →Per-Column Sorting
Direction-aware sorting with descending defaults (-column), custom sort callbacks, and URL state preservation.
Standard & Cursor Pagination
Built-in support for length-aware, simple, and cursor pagination with configurable per-page options (e.g. 15, 30, 50).
Pagination Guide →Row & Bulk Actions
Single-row actions and multi-row selection with batch chunking, confirmation dialogs, and authorization checks.
Bulk Actions Guide →Column Visibility & Sticky Pins
Users can toggle column visibility dynamically and pin high-value identification columns during wide horizontal scrolling.
Sticky Columns Guide →Excel & CSV Exports
Download filtered subsets or selected rows directly from table state, with background queue support for large datasets.
Exports Guide →Developer FAQ
Clear answers for your Laravel & Inertia stack.
Everything you need to know about integrating Zonvoir Table into your Laravel Inertia Vue applications.
Is Zonvoir Table really free for commercial projects?
Yes. Zonvoir Table is 100% free and open-source software licensed under the Apache License 2.0. There is no "Pro" version, paid license, or feature gating. You can use it in commercial SaaS apps, internal dashboards, and client deliverables subject to the Apache License 2.0 conditions.
What stack versions does Zonvoir Table support?
Zonvoir Table is tested against modern releases: PHP 8.3+, Laravel 11, 12, and 13, Inertia.js 2.x and 3.x, Vue 3.4+, and Tailwind CSS 3.4+ or 4.0+. Full TypeScript type declarations are packaged with the Vue adapter. See the Requirements guide for details.
How does server-side data fetching work without separate API routes?
You define tables using PHP classes (e.g., UsersTable extends Table). In your Inertia controller, return UsersTable::make(). The table orchestrates the Eloquent query, applies current search/sort/pagination filters from the request, and passes a normalized payload to your Vue template. The Inertia adapter updates the page via standard Inertia partial reloads.
Can I customize the design, colors, and cell components?
Yes. Zonvoir Table is styled with Tailwind CSS utility classes and includes built-in dark mode support. You can customize theme colors, apply column-level classes, or use Vue slots to render custom interactive components, avatars, status badges, and action dropdowns in any cell. Explore the Slots guide and Styling guide.
Official Packages & Resources
Ready to build fast, expressive tables?
Install via Composer and npm, or inspect the source code and interactive demo: