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
Svelte 5 + Inertia client

Svelte 5 + Inertia client

A thin Svelte 5 (runes) wrapper around the headless engine. Same protocol, same theme, same options as the Vue client.

Install

composer require elyra/datagrid-js

The Svelte client, headless core and theme ship in the elyra/datagrid-js Composer package (same token as the server — no npm registry). Alias the @elyra/* specifiers to vendor/elyra/datagrid-js/dist/* in vite.config.ts — see Installation.

// entry (e.g. resources/js/app.ts)
import '@elyra/datagrid-theme/theme.css';
import '@elyra/datagrid-theme/accents.css';
import '@elyra/datagrid-theme/grid.css';

Set up the endpoints and CSRF as in Inertia integration.

Component

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

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

  const mutate = async (m: GridMutation): Promise<GridMutationResult> =>
    (await fetch('/api/sales/mutate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
      body: JSON.stringify(m),
    })).json();

  const options = {
    key: 'id',
    columns: [
      { field: 'sku', header: 'SKU', frozen: true, cell: { type: 'link', href: '/orders/{id}' } },
      { field: 'region', header: 'Region' },
      { field: 'status', header: 'Status', editable: true, editor: 'select',
        options: [{ value: 'paid', label: 'paid' }, { value: 'pending', label: 'pending' }],
        badges: { pending: 1, paid: 2, shipped: 3, delivered: 4, returned: 5 } },
      { field: 'revenue', header: 'Revenue', type: 'number', align: 'right',
        editable: true, editor: 'number', cell: { type: 'currency', symbol: 'kr ', decimals: 2 } },
    ],
    fetch: laravelFetch('/api/sales/grid'),
    exportUrl: '/api/sales/export',
    initialData: initial,
    persistKey: 'sales',
    selection: { mode: 'multiple' },
    grouping: { aggregates: [{ field: 'revenue', fn: 'sum', as: 'sum_revenue' }] },
    search: true,
    editing: { mode: 'slideover', mutate },
    columnOps: true,
  };
</script>

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

Props

Prop Type Default Purpose
options GridOptions — The grid config.
theme string '' '' (app) or a preset like tokyo-night.
accent string '' '' (app) or a Flux-style accent.
heading string Data Toolbar title.
height number 480 Viewport height (virtual scroll mode).
messages Partial<Messages> — UI string overrides (i18n).

Natural-language filtering

Provide an ask function in the options to show an "ask in plain language" box in the toolbar. It POSTs to an endpoint that calls GridDefinition::ask() and returns the translated filter; GridController applies it and refetches.

const options = {
  // ...
  ask: async (query: string) => {
    const res = await fetch('/api/sales/ask', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
      body: JSON.stringify({ q: query }),
    });
    return (await res.json()).filter;   // FilterGroup | null
  },
};

Omit ask to hide the box. Full guide: Natural-language filtering.

The controller

For custom markup, use GridController (a runes bridge over the engine):

import { GridController } from '@elyra/datagrid-svelte';

const ctrl = new GridController(options);
// ctrl.state (reactive), ctrl.grid.toggleSort('revenue'), ctrl.grid.setPageSize(50)
// ctrl.destroy() on teardown

ctrl.state is a $state rune kept in sync with the engine. Every ctrl.grid method is documented in the Client core API.

Pivot

For a cross-tab over the same source — dimensions on two axes, with subtotals and margins — this client also ships DataPivot from @elyra/datagrid-svelte. See Pivot.