From jqxGrid to SvGrid. Building a Data Grid in Svelte 5

At jQWidgets we have been building data grids since 2011, for jQuery, Angular, React, Vue, and Blazor. Svelte 5 is the newest addition to that lineup, and it changed how we think about data-heavy interfaces. Runes give you fine-grained, signal-style reactivity, which is exactly what a fast, editable grid needs. If you are building admin panels, dashboards, or line-of-business tools in SvelteKit, a good Svelte data grid is often the single most important component on the screen. Here is what to look for.


Why data grids are hard


A data grid is deceptively complex. It has to stay smooth with tens of thousands of rows, support sorting and filtering without freezing the UI, let users edit cells inline with validation, and remain fully keyboard accessible. Do it naively and the browser repaints the entire table on every keystroke. The trick is to render only what is visible and to update only the cells that actually changed. It is the same engineering discipline behind our jqxGrid demos, applied to a new framework.


Svelte 5 runes are a natural fit


Because runes track reactivity at a granular level, a grid built for Svelte 5 can update a single edited cell without re-rendering its neighbours. That is the difference between a grid that feels instant and one that stutters. It is also why a grid designed from the first line for Svelte 5 tends to beat a grid ported from another framework and wrapped in a Svelte shim.


A minimal example


This is a complete, working grid. Sorting, filtering, virtualization, and inline editing switch on with a single prop each.

<script lang="ts">
  import { SvGrid, type ColumnDef } from '@svgrid/grid'

  const data = [
    { firstName: 'Ada',   age: 36, status: 'active' },
    { firstName: 'Linus', age: 54, status: 'active' },
    { firstName: 'Grace', age: 85, status: 'inactive' },
  ]
  const columns: ColumnDef<{}, (typeof data)[number]>[] = [
    { field: 'firstName', header: 'First name' },
    { field: 'age',       header: 'Age' },
    { field: 'status',    header: 'Status' },
  ]
</script>

<SvGrid {data} {columns} />

Install it with npm install @svgrid/grid, or scaffold a ready-to-run app with npm create @svgrid@latest.


Features that actually matter

  • Virtualization. Row and column virtualization keep 100k rows (and a 1M-row demo) scrolling smoothly.
  • Filtering. An Excel-style filter menu, an inline filter row, and locale-aware text matching.
  • Editing. Built-in cell editors for text, numbers, dates, selects, and more, plus a slot for anything custom, with per-cell validation.
  • Selection. Cell-range selection with copy and paste as TSV and an Excel-style fill handle.
  • Structure. Row grouping with aggregation, tree data, master/detail rows, and a native Kanban board view over the same data.
  • Accessibility. WAI-ARIA grid roles, full keyboard navigation, and right-to-left support.

Already using jqxGrid, and now planning Svelte?

The concepts carry straight over. The main shift is from an imperative jQuery call to a declarative Svelte component: instead of selecting an element and initialising it, you render a component and let Svelte keep it in sync with your data. Here is the same grid in both.


jqxGrid (jQuery):

<div id="grid"></div>

<script>
  var source = {
    localdata: [
      { firstName: 'Ada',   age: 36, status: 'active' },
      { firstName: 'Linus', age: 54, status: 'active' },
      { firstName: 'Grace', age: 85, status: 'inactive' }
    ],
    datatype: 'array'
  };
  var adapter = new $.jqx.dataAdapter(source);

  $('#grid').jqxGrid({
    source: adapter,
    sortable: true,
    filterable: true,
    columns: [
      { text: 'First name', datafield: 'firstName' },
      { text: 'Age',        datafield: 'age' },
      { text: 'Status',     datafield: 'status' }
    ]
  });
</script>

SvGrid (Svelte 5):

<script lang="ts">
  import { SvGrid, type ColumnDef } from '@svgrid/grid'

  const data = [
    { firstName: 'Ada',   age: 36, status: 'active' },
    { firstName: 'Linus', age: 54, status: 'active' },
    { firstName: 'Grace', age: 85, status: 'inactive' },
  ]
  const columns: ColumnDef<{}, (typeof data)[number]>[] = [
    { field: 'firstName', header: 'First name' },
    { field: 'age',       header: 'Age' },
    { field: 'status',    header: 'Status' },
  ]
</script>

<SvGrid {data} {columns} sortable filterable />

The mental model maps almost one to one:

jqxGridSvGrid
source + $.jqx.dataAdapterdata (a plain array, or a server row model)
columns[].textcolumns[].header
columns[].datafieldcolumns[].field
sortable: truesortable prop
filterable: truefilterable prop
column editableeditorType on the column
$('#grid').jqxGrid({ ... })the <SvGrid /> component

There is no dataAdapter to wire up and no manual refresh: assign a new array and the grid re-renders itself. For a field-by-field walkthrough, see the jqxGrid to SvGrid migration guide.


Headless when you need it

Sometimes you want the grid to look exactly like the rest of your design system. A headless-first architecture gives you a small engine you can compose with your own markup, plus a drop-in render component for when you just want it to work out of the box. You are not locked into one or the other.


Built for the AI era

Modern teams build with AI editors. SvGrid ships an MCP (Model Context Protocol) server, so tools like Claude, Cursor, and Zed answer with accurate, version-pinned APIs and real example sources as grounding. In practice that means the grid code the assistant writes actually runs, instead of hallucinating props that do not exist.


Try it

The community core is MIT-licensed and free for commercial use, with no row-count cap and no watermark. Browse the 280+ live demos to see every feature in action, or drop it into your next SvelteKit project and see how it feels.


About admin


This entry was posted in Svelte and tagged , , , , , , . Bookmark the permalink.



Leave a Reply