svelte-headless-tableSimple Table for Svelte

Migrate from svelte-headless-table to Simple Table for Svelte

A practical migration guide from svelte-headless-table to Simple Table for Svelte. Trade headless table primitives for batteries-included virtualization, pinning, grouping, and editing.

svelte-headless-table is a popular headless table builder—you compose plugins (sort, filter, group, paginate) and write the HTML yourself. It's powerful but you own all the wiring: virtualization, pinning, themes, accessibility.

Simple Table for Svelte is an MIT-licensed Svelte 4 / Svelte 5 data grid that ships virtualization for 1M+ rows, column pinning, row grouping with aggregations, and inline editing in the box.

This guide shows how to swap an existing svelte-headless-table view for @simple-table/svelte when your headless setup has grown more complex than you wanted.

Why migrate

  • You want a working grid in 5 minutes, not a half-day of plugin wiring.
  • You need real virtualization for 100k+ rows without integrating a separate virtual list.
  • You want column pinning, grouping with aggregations, and inline editing as built-in primitives.
  • You ship Svelte 5 with runes and want a component that aligns with that reactivity model.

Prerequisites

  • SvelteKit / Svelte 4 or Svelte 5 project.
  • Simple Table for Svelte installed: npm install @simple-table/svelte.

Install

npm install @simple-table/svelte

API mapping cheat sheet

svelte-headless-tableSimple Table for SvelteNotes
createTable + writable store$state with default headers + rowsReactivity via runes (Svelte 5) or stores (Svelte 4).
table.column({ accessor, header })HeaderObject (accessor, label, width)Same fields, declared on a plain object.
addSortBy / addColumnFilters pluginsBuilt-in sort + filterNo plugin wiring needed.
addGroupedRowsBuilt-in row grouping + aggregationsConfigure via HeaderObject + props.
Custom HTML composition<SimpleTable /> + cell renderer componentsPass renderers for custom cells/headers.
Bring-your-own virtualizationBuilt-in (set height)Row + column virtualization for 1M+ rows.

Step-by-step migration

  1. Install Simple Table for Svelte

    Add @simple-table/svelte and its stylesheet. Remove svelte-headless-table once you've migrated all consumers.

    npm install @simple-table/svelte
    npm uninstall svelte-headless-table
    
    // app.html or a global CSS file
    import "@simple-table/svelte/styles.css";
  2. Convert columns

    Replace table.column({ accessor, header }) calls with HeaderObject entries containing accessor + label + width.

  3. Replace stores with $state or stores

    In Svelte 5, use $state. In Svelte 4, keep using a writable store and pass it to :rows.

  4. Drop the plugin pipeline

    Sort, filter, paginate, and group are built in—remove addSortBy / addPagination / addGroupedRows plugin code.

  5. Move custom HTML to renderers

    Anywhere you used <Render of=… /> with custom JSX-ish projection, pass a Svelte component via HeaderObject.cellRenderer.

Gotchas

Less low-level control
You give up DOM-level control over <table>, <tr>, <td>. In return you get virtualization and pinning that's tedious to build by hand.
Plugin parity
Most plugin features map 1:1 onto Simple Table props. The exception is exotic plugin compositions—open an issue if you have one and we'll point you at the equivalent prop.

FAQ

Is Simple Table compatible with Svelte 5 runes?
Yes. @simple-table/svelte exposes idiomatic props that work with $state, $derived, and SvelteKit's data-loading patterns.
Can I keep svelte-headless-table for some views?
Yes. They can coexist during a migration. Remove svelte-headless-table once the last consumer is gone.

Keep going