Elyra
Elyra The coding agent eTerm The terminal that knows where each command ends Huskarl AI colleagues on your own Mac Starf An activity monitor for Apple silicon that never invents a number etrans An SSH and SFTP client for macOS Elyra VM Virtual machines for macOS, Linux and Windows on your Mac Litr A small, native web browser for macOS Notr A notebook for macOS e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Refr Local-first PDF workspace for macOS Elyra Workspace A desktop workspace for coding agents Elyra SQL Server MySQL-compatible SQL server in Rust Elyra Félagi Agents as teammates on one board Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra Sjá SEO & GEO workspace for macOS Elyra DataGrid Server-driven data grid for Laravel
Elyra

Quick start

This guide builds a minimal, sortable, filterable, paged grid over a sales table for each client. It assumes you completed Installation.

Every grid needs a server definition (which columns exist, security, driver). The clients then either use it directly (Livewire) or call it through a JSON endpoint (Vue/Svelte).


Livewire

Create a component that extends DataGrid:

<?php

namespace App\Livewire;

use Elyra\DataGrid\Livewire\DataGrid;
use Elyra\DataGrid\Server\Grid;
use Elyra\DataGrid\Server\GridDefinition;

class SalesGrid extends DataGrid
{
    public string $heading = 'Sales';

    protected function definition(): GridDefinition
    {
        return Grid::table('sales')
            ->connection('elyrasql')
            ->key('id')
            ->columns(['sku', 'region', 'category', 'status'])
            ->column('revenue', type: 'number')
            ->searchable(['sku', 'category']);
    }

    protected function columns(): array
    {
        return [
            ['field' => 'sku', 'header' => 'SKU', 'frozen' => true],
            ['field' => 'region', 'header' => 'Region'],
            ['field' => 'category', 'header' => 'Category'],
            ['field' => 'status', 'header' => 'Status'],
            ['field' => 'revenue', 'header' => 'Revenue', 'type' => 'number'],
        ];
    }
}

Route it as a full-page component:

Route::get('/sales', App\Livewire\SalesGrid::class);

That is a complete, working grid. See the Livewire guide to enable selection, grouping, editing, export, and more.


Vue (Inertia)

Server — a JSON endpoint plus a page route (routes/web.php):

use Elyra\DataGrid\Protocol\GridRequest;
use Elyra\DataGrid\Server\Grid;
use Illuminate\Http\Request;

function salesGrid()
{
    return Grid::table('sales')->connection('elyrasql')->key('id')
        ->columns(['id', 'sku', 'region', 'category', 'status'])
        ->column('revenue', type: 'number')
        ->searchable(['sku', 'category']);
}

Route::get('/sales', fn () => Inertia::render('Sales', [
    'initial' => salesGrid()->respond(GridRequest::fromArray([
        'columns' => ['id', 'sku', 'region', 'category', 'status', 'revenue'],
        'view' => ['skip' => 0, 'take' => 20],
        'meta' => ['total'],
    ])),
]));

Route::post('/api/sales/grid', fn (Request $r) => salesGrid()->respond(GridRequest::fromArray($r->all())));

Exempt the API route from CSRF (bootstrap/app.php):

$middleware->validateCsrfTokens(except: ['api/*']);

Page — resources/js/pages/Sales.vue:

<script setup lang="ts">
import { DataGrid, laravelFetch } from '@elyra/datagrid-vue';
import type { GridResponse } from '@elyra/datagrid-vue';

const props = defineProps<{ initial?: GridResponse }>();

const options = {
    key: 'id',
    columns: [
        { field: 'sku', header: 'SKU', frozen: true },
        { field: 'region', header: 'Region' },
        { field: 'category', header: 'Category' },
        { field: 'status', header: 'Status' },
        { field: 'revenue', header: 'Revenue', type: 'number' as const, align: 'right' as const },
    ],
    fetch: laravelFetch('/api/sales/grid'),
    initialData: props.initial, // instant first paint (SSR)
};
</script>

<template>
    <DataGrid :options="options" heading="Sales" />
</template>

The initialData prop is the server-seeded first page — the grid renders immediately, then fetches on interaction. See Inertia integration.


Svelte (Inertia)

Server setup is identical to Vue. The page (resources/js/pages/Sales.svelte):

<script lang="ts">
  import { DataGrid, laravelFetch } from '@elyra/datagrid-svelte';
  import type { GridResponse } from '@elyra/datagrid-svelte';

  let { initial }: { initial?: GridResponse } = $props();

  const options = {
    key: 'id',
    columns: [
      { field: 'sku', header: 'SKU', frozen: true },
      { field: 'region', header: 'Region' },
      { field: 'revenue', header: 'Revenue', type: 'number', align: 'right' },
    ],
    fetch: laravelFetch('/api/sales/grid'),
    initialData: initial,
  };
</script>

<DataGrid {options} heading="Sales" />

Next: Defining grids.