@svgrid/mcp 3.0.7 → 3.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data.js +52 -52
- package/dist/preview.d.ts +1 -1
- package/dist/preview.js +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
package/dist/data.js
CHANGED
|
@@ -965,7 +965,7 @@ export const examples = [
|
|
|
965
965
|
"title": "Export And Print",
|
|
966
966
|
"category": "Data Export & Import",
|
|
967
967
|
"blurb": "21. Export + Print (Pro) Demonstrates the @svgrid/enterprise feature pack: download the visible grid to Excel, PDF, CSV, TSV, or HTML, and open a printable view in a new window.",
|
|
968
|
-
"source": "<script lang=\"ts\">\n /**\n * 21. Export + Print (Pro)\n * ------------------------\n * Demonstrates the @svgrid/enterprise feature pack: download the visible grid to\n * Excel, PDF, CSV, TSV, or HTML, and open a printable view in a new window.\n *\n * The grid itself is plain @svgrid/grid. Pro is installed via\n * installEnterprise(api) which adds api.exportData(...) and api.print(...) onto\n * the same SvGridApi object you already have.\n */\n import {\n SvGrid,\n tableFeatures,\n rowSortingFeature,\n columnFilteringFeature,\n rowSelectionFeature,\n type GridColumns,\n type SvGridApi,\n } from '@svgrid/grid'\n import {\n installEnterprise,\n setLicenseKey,\n getLicenseKey,\n clearLicenseKey,\n dismissUnlicensedNudge,\n type EnterpriseGridApi,\n } from '@svgrid/enterprise'\n import { makeOrders, type Order } from '../shared/seed'\n\n // The license key is set once at app startup (main.ts), never in a\n // component. This demo borrows whatever key the app set so the toggle can\n // show the unlicensed state (watermark + console nudge) and back. With no\n // key set there is nothing to toggle: the watermark simply shows.\n const appKey = getLicenseKey()\n let licensed = $state(appKey !== null)\n $effect(() => {\n if (!appKey) return\n if (licensed) {\n setLicenseKey(appKey)\n dismissUnlicensedNudge() // clear the watermark the unlicensed view left\n } else {\n clearLicenseKey()\n }\n // Leaving the demo restores the key, so the next page is not unlicensed.\n return () => {\n setLicenseKey(appKey)\n dismissUnlicensedNudge()\n }\n })\n\n const features = tableFeatures({\n rowSortingFeature,\n columnFilteringFeature,\n rowSelectionFeature,\n })\n\n let rows = $state<Order[]>(makeOrders(120))\n let api = $state<EnterpriseGridApi<typeof features, Order> | null>(null)\n let lastAction = $state<string>('')\n let busy = $state<string | null>(null)\n let errorMsg = $state<string | null>(null)\n\n const columns: GridColumns<Order> = [\n { field: 'company', header: 'Company', width: 140 },\n { field: 'product', header: 'Product', width: 170 },\n { field: 'sellDate', header: 'Sell date', width: 110,\n format: { type: 'date', pattern: 'y-m-d' } },\n { field: 'quantity', header: 'Quantity', width: 90,\n format: { type: 'number', options: { maximumFractionDigits: 0 } } },\n { field: 'orderId', header: 'Order ID', width: 130 },\n { field: 'country', header: 'Country', width: 90 },\n { field: 'price', header: 'Price', width: 110,\n format: { type: 'currency', currency: 'USD' } },\n ]\n\n // Listed explicitly (rather than .map'd from `columns`) so the export\n // module's ExportColumn type (field: string, required) is satisfied\n // without casts - ColumnDef.field is keyof TData | undefined.\n const exportColumns = [\n { field: 'company', header: 'Company' },\n { field: 'product', header: 'Product' },\n { field: 'sellDate', header: 'Sell date' },\n { field: 'quantity', header: 'Quantity' },\n { field: 'orderId', header: 'Order ID' },\n { field: 'country', header: 'Country' },\n { field: 'price', header: 'Price' },\n ]\n\n function onReady(next: SvGridApi<typeof features, Order>) {\n api = installEnterprise(next)\n }\n\n async function run(label: string, fn: () => Promise<unknown>) {\n if (!api) return\n busy = label\n errorMsg = null\n try {\n await fn()\n lastAction = label\n } catch (err) {\n errorMsg = err instanceof Error ? err.message : String(err)\n } finally {\n busy = null\n }\n }\n\n const exportFormats: Array<{ label: string; format: 'xlsx' | 'pdf' | 'csv' | 'tsv' | 'html' }> = [\n { label: 'Excel (xlsx)', format: 'xlsx' },\n { label: 'PDF', format: 'pdf' },\n { label: 'CSV', format: 'csv' },\n { label: 'TSV', format: 'tsv' },\n { label: 'HTML', format: 'html' },\n ]\n</script>\n\n<section class=\"flex flex-col flex-1 min-h-0 gap-3\">\n <div class=\"text-sm shrink-0 xp-note\">\n {rows.length} rows. Apply sort or filter - exports always reflect the\n <em>currently displayed</em> rows. Print opens a new window with the\n same view, ready for the browser print dialog.\n </div>\n\n <div class=\"flex flex-wrap items-center gap-2 shrink-0\">\n {#each exportFormats as f (f.format)}\n <button\n type=\"button\"\n class=\"rounded border px-3 py-1.5 text-sm font-medium disabled:opacity-50 xp-btn\"\n disabled={busy !== null || api === null}\n onclick={() =>\n run(`Exported ${f.label}`, () =>\n api!.exportData({\n format: f.format,\n filename: `orders.${f.format}`,\n columns: exportColumns,\n pageOrientation: 'landscape',\n }),\n )}\n >\n Export {f.label}\n </button>\n {/each}\n <button\n type=\"button\"\n class=\"rounded border px-3 py-1.5 text-sm font-medium disabled:opacity-50 xp-btn xp-btn-primary\"\n disabled={busy !== null || api === null}\n onclick={() =>\n run('Opened print view', () =>\n api!.print({\n title: 'Orders',\n columns: exportColumns,\n orientation: 'landscape',\n }),\n )}\n >\n Print…\n </button>\n {#if busy}\n <span class=\"text-xs xp-note\">{busy}…</span>\n {:else if lastAction}\n <span class=\"text-xs text-green-600 dark:text-green-400\">{lastAction}</span>\n {/if}\n {#if errorMsg}\n <span class=\"text-xs text-red-600 dark:text-red-400\">{errorMsg}</span>\n {/if}\n\n <label class=\"ml-auto flex items-center gap-2 text-xs xp-note\">\n <input type=\"checkbox\" bind:checked={licensed} disabled={!appKey} class=\"h-4 w-4\" />\n Licensed (uncheck to see the unlicensed watermark + console nudge)\n </label>\n </div>\n\n <div class=\"flex-1 min-h-0\">\n <SvGrid responsive={true}\n columnResize\n data={rows}\n columns={columns}\n features={features}\n filterMode=\"menu\"\n selectionMode=\"both\"\n showRowSelection={true}\n showRowNumbers={true}\n showGroupingControls={false}\n enableCellSelection={true}\n enableInlineEditing={false}\n rowHeight={36}\n containerHeight=\"100%\"\n fitColumns={true}\n onApiReady={onReady}\n />\n </div>\n\n <footer class=\"text-xs shrink-0 xp-note\">\n Pro feature - gated by <code>setLicenseKey()</code>. Without
|
|
968
|
+
"source": "<script lang=\"ts\">\n /**\n * 21. Export + Print (Pro)\n * ------------------------\n * Demonstrates the @svgrid/enterprise feature pack: download the visible grid to\n * Excel, PDF, CSV, TSV, or HTML, and open a printable view in a new window.\n *\n * The grid itself is plain @svgrid/grid. Pro is installed via\n * installEnterprise(api) which adds api.exportData(...) and api.print(...) onto\n * the same SvGridApi object you already have.\n */\n import {\n SvGrid,\n tableFeatures,\n rowSortingFeature,\n columnFilteringFeature,\n rowSelectionFeature,\n type GridColumns,\n type SvGridApi,\n } from '@svgrid/grid'\n import {\n installEnterprise,\n setLicenseKey,\n getLicenseKey,\n clearLicenseKey,\n dismissUnlicensedNudge,\n type EnterpriseGridApi,\n } from '@svgrid/enterprise'\n import { makeOrders, type Order } from '../shared/seed'\n\n // The license key is set once at app startup (main.ts), never in a\n // component. This demo borrows whatever key the app set so the toggle can\n // show the unlicensed state (watermark + console nudge) and back. With no\n // key set there is nothing to toggle: the watermark simply shows.\n const appKey = getLicenseKey()\n let licensed = $state(appKey !== null)\n $effect(() => {\n if (!appKey) return\n if (licensed) {\n setLicenseKey(appKey)\n dismissUnlicensedNudge() // clear the watermark the unlicensed view left\n } else {\n clearLicenseKey()\n }\n // Leaving the demo restores the key, so the next page is not unlicensed.\n return () => {\n setLicenseKey(appKey)\n dismissUnlicensedNudge()\n }\n })\n\n const features = tableFeatures({\n rowSortingFeature,\n columnFilteringFeature,\n rowSelectionFeature,\n })\n\n let rows = $state<Order[]>(makeOrders(120))\n let api = $state<EnterpriseGridApi<typeof features, Order> | null>(null)\n let lastAction = $state<string>('')\n let busy = $state<string | null>(null)\n let errorMsg = $state<string | null>(null)\n\n const columns: GridColumns<Order> = [\n { field: 'company', header: 'Company', width: 140 },\n { field: 'product', header: 'Product', width: 170 },\n { field: 'sellDate', header: 'Sell date', width: 110,\n format: { type: 'date', pattern: 'y-m-d' } },\n { field: 'quantity', header: 'Quantity', width: 90,\n format: { type: 'number', options: { maximumFractionDigits: 0 } } },\n { field: 'orderId', header: 'Order ID', width: 130 },\n { field: 'country', header: 'Country', width: 90 },\n { field: 'price', header: 'Price', width: 110,\n format: { type: 'currency', currency: 'USD' } },\n ]\n\n // Listed explicitly (rather than .map'd from `columns`) so the export\n // module's ExportColumn type (field: string, required) is satisfied\n // without casts - ColumnDef.field is keyof TData | undefined.\n const exportColumns = [\n { field: 'company', header: 'Company' },\n { field: 'product', header: 'Product' },\n { field: 'sellDate', header: 'Sell date' },\n { field: 'quantity', header: 'Quantity' },\n { field: 'orderId', header: 'Order ID' },\n { field: 'country', header: 'Country' },\n { field: 'price', header: 'Price' },\n ]\n\n function onReady(next: SvGridApi<typeof features, Order>) {\n api = installEnterprise(next)\n }\n\n async function run(label: string, fn: () => Promise<unknown>) {\n if (!api) return\n busy = label\n errorMsg = null\n try {\n await fn()\n lastAction = label\n } catch (err) {\n errorMsg = err instanceof Error ? err.message : String(err)\n } finally {\n busy = null\n }\n }\n\n const exportFormats: Array<{ label: string; format: 'xlsx' | 'pdf' | 'csv' | 'tsv' | 'html' }> = [\n { label: 'Excel (xlsx)', format: 'xlsx' },\n { label: 'PDF', format: 'pdf' },\n { label: 'CSV', format: 'csv' },\n { label: 'TSV', format: 'tsv' },\n { label: 'HTML', format: 'html' },\n ]\n</script>\n\n<section class=\"flex flex-col flex-1 min-h-0 gap-3\">\n <div class=\"text-sm shrink-0 xp-note\">\n {rows.length} rows. Apply sort or filter - exports always reflect the\n <em>currently displayed</em> rows. Print opens a new window with the\n same view, ready for the browser print dialog.\n </div>\n\n <div class=\"flex flex-wrap items-center gap-2 shrink-0\">\n {#each exportFormats as f (f.format)}\n <button\n type=\"button\"\n class=\"rounded border px-3 py-1.5 text-sm font-medium disabled:opacity-50 xp-btn\"\n disabled={busy !== null || api === null}\n onclick={() =>\n run(`Exported ${f.label}`, () =>\n api!.exportData({\n format: f.format,\n filename: `orders.${f.format}`,\n columns: exportColumns,\n pageOrientation: 'landscape',\n }),\n )}\n >\n Export {f.label}\n </button>\n {/each}\n <button\n type=\"button\"\n class=\"rounded border px-3 py-1.5 text-sm font-medium disabled:opacity-50 xp-btn xp-btn-primary\"\n disabled={busy !== null || api === null}\n onclick={() =>\n run('Opened print view', () =>\n api!.print({\n title: 'Orders',\n columns: exportColumns,\n orientation: 'landscape',\n }),\n )}\n >\n Print…\n </button>\n {#if busy}\n <span class=\"text-xs xp-note\">{busy}…</span>\n {:else if lastAction}\n <span class=\"text-xs text-green-600 dark:text-green-400\">{lastAction}</span>\n {/if}\n {#if errorMsg}\n <span class=\"text-xs text-red-600 dark:text-red-400\">{errorMsg}</span>\n {/if}\n\n <label class=\"ml-auto flex items-center gap-2 text-xs xp-note\">\n <input type=\"checkbox\" bind:checked={licensed} disabled={!appKey} class=\"h-4 w-4\" />\n Licensed (uncheck to see the unlicensed watermark + console nudge)\n </label>\n </div>\n\n <div class=\"flex-1 min-h-0\">\n <SvGrid responsive={true}\n columnResize\n data={rows}\n columns={columns}\n features={features}\n filterMode=\"menu\"\n selectionMode=\"both\"\n showRowSelection={true}\n showRowNumbers={true}\n showGroupingControls={false}\n enableCellSelection={true}\n enableInlineEditing={false}\n rowHeight={36}\n containerHeight=\"100%\"\n fitColumns={true}\n onApiReady={onReady}\n />\n </div>\n\n <footer class=\"text-xs shrink-0 xp-note\">\n Pro feature - gated by <code>setLicenseKey()</code>. Without your license key\n the feature still runs, but the grid shows a watermark linking to\n svgrid.com/pricing. A wrong key never throws; it behaves like no key.\n </footer>\n</section>\n\n<style>\n .xp-note { color: var(--sg-muted, #475569); }\n .xp-btn {\n border-color: var(--sg-border, #cbd5e1);\n background: var(--sg-bg, #ffffff);\n color: var(--sg-fg, #0f172a);\n }\n .xp-btn:hover:not(:disabled) { background: var(--sg-row-hover-bg, #f8fafc); }\n .xp-btn-primary {\n border-color: var(--sg-accent, #4f46e5);\n background: var(--sg-accent, #4f46e5);\n color: var(--sg-on-accent, #fff);\n }\n .xp-btn-primary:hover:not(:disabled) {\n background: var(--sg-accent, #4f46e5);\n filter: brightness(1.08);\n }\n</style>\n"
|
|
969
969
|
},
|
|
970
970
|
{
|
|
971
971
|
"id": "210-format-cells",
|
|
@@ -3565,14 +3565,14 @@ export const docs = [
|
|
|
3565
3565
|
"path": "docs/enterprise/README.md",
|
|
3566
3566
|
"title": "Enterprise feature pack",
|
|
3567
3567
|
"section": "Enterprise tier",
|
|
3568
|
-
"markdown": "# Enterprise feature pack\n\n`@svgrid/enterprise` is a paid add-on for `@svgrid/grid`. It bolts onto\nthe same `<SvGrid>` you already have and adds five feature areas: the\nserver-side row model, data export, data import, pivot tables, and the\nKanban, Scheduler and Spreadsheet views of the same grid. (The AI helpers\nare built in and **free** in `@svgrid/grid` - see\n[AI assistant](../help/ai.md).)\n\n\n\n```bash\npnpm add @svgrid/enterprise\n```\n\n```ts\nimport { installEnterprise, setLicenseKey } from '@svgrid/enterprise'\n\nsetLicenseKey('
|
|
3568
|
+
"markdown": "# Enterprise feature pack\n\n`@svgrid/enterprise` is a paid add-on for `@svgrid/grid`. It bolts onto\nthe same `<SvGrid>` you already have and adds five feature areas: the\nserver-side row model, data export, data import, pivot tables, and the\nKanban, Scheduler and Spreadsheet views of the same grid. (The AI helpers\nare built in and **free** in `@svgrid/grid` - see\n[AI assistant](../help/ai.md).)\n\n\n\n```bash\npnpm add @svgrid/enterprise\n```\n\n```ts\nimport { installEnterprise, setLicenseKey } from '@svgrid/enterprise'\n\nsetLicenseKey('YOUR-LICENSE-KEY') // once, at app startup\nconst pro = installEnterprise(api) // wraps a SvGridApi with Enterprise methods\n```\n\nThat's the whole integration. Every Enterprise helper hangs off the api object\nyou already have; the grid component stays Community.\n\n## What ships in Enterprise\n\n### [Data export](../help/export.md)\n\n`pro.exportData(opts)` writes the current view to Excel (xlsx), PDF,\nCSV, TSV, or HTML from a single call.\n\n**CSV, TSV and JSON export do not need Enterprise** - they are free in\n`@svgrid/grid`, along with copy-to-clipboard. What Enterprise adds is\nxlsx, PDF, styled HTML and XML, plus the unified entry point with\ncolumn resolution and group handling. See\n[the export page](../help/export.md) for the exact split.\n\nThe xlsx writer honours:\n\n- **Cell + row styles** via `opts.styles` - read the same `--sg-*`\n tokens the grid renders with so the file matches the theme.\n- **Page header + footer** lines with text or embedded images\n (`opts.header`, `opts.footer`).\n- **Embedded images** from cell values when columns are listed in\n `opts.imageFields`.\n- **Multiple sheets** in one workbook via `opts.sheets`.\n- **Printable view** via `pro.print(opts)` - opens a new window with\n repeat-on-page headers, cover page, page-size + orientation.\n\nDemos: [56 theme-matched](../../examples/src/demos/56-export-theme-matched.svelte),\n[57 header + footer + logo](../../examples/src/demos/57-export-header-footer-logo.svelte),\n[58 images](../../examples/src/demos/58-export-with-images.svelte),\n[59 multi-sheet](../../examples/src/demos/59-export-multi-sheet.svelte).\n\n### [Data import](../help/import.md)\n\n`pro.importData(opts)` reads an Excel / CSV / TSV / JSON file (or\ninline text), maps columns to your row shape, validates each row, and\nreturns a typed `ImportResult` with `rows`, `errors`, and a `summary`.\nYou decide whether to commit the rows into the grid or preview first.\n\nDemo: [53 Excel import](../../examples/src/demos/53-excel-import.svelte).\n\n### AI assistant - now built-in + free\n\nThe natural-language filter, smart-fill, summarise, classify, chart-this,\nfind-anomalies and natural-language-export helpers moved into the free\n`@svgrid/grid` package. Import them from `@svgrid/grid` and register a provider\nwith `setAIProvider(yourAdapter)` (no model client is bundled - you bring\nOpenAI / Anthropic / Ollama / local). See [AI assistant](../help/ai.md). The\nonly enterprise touch-point is `aiExport`'s write step, which uses this pack's\nexport engine for xlsx / pdf.\n\nDemo: [51 AI assistant](../../examples/src/demos/51-ai-assistant.svelte).\n\n### [Pivot tables](../help/pivot.md)\n\n`createPivotModel(data, config)` (or `pro.pivot.build(config)` against\nthe live api) returns `{ rows, columns }` you feed to a separate\n`<SvGrid>` instance. Supports row + column axes, eight built-in\naggregators (sum/avg/min/max/count/countDistinct/first/last) or\ncustom, grand-total row + column, subtotals, custom axis sort.\n\nDemo: [52 pivot table + designer](../../examples/src/demos/52-pivot-table.svelte).\n\n### [Server-Side Row Model](../help/server/server-grouping.md)\n\n`createServerRowModel(source, options)` runs over the free datasource\ncontract (`ServerDataSource.getRows`) and hands the grid one `rowModel`\nprop: lazy grouping and tree data one level at a time with a block cache\nper level, aggregates, child counts and grand totals, server-side pivot\nwith `SvPivotDesigner` in server mode, transactions on loaded rows,\npaging over the tree, and a selection kept as a rule so select-all\nreaches rows the grid never loaded, with a bulk edit by rule. Flat paging\nand infinite scroll stay free in `@svgrid/grid`.\n\nDemos: [467 one million rows](../../examples/src/demos/467-server-row-model-1m.svelte),\n[468 server pivot](../../examples/src/demos/468-server-pivot.svelte),\n[469 tree data](../../examples/src/demos/469-server-tree-data.svelte),\n[470 transactions](../../examples/src/demos/470-server-transactions.svelte),\n[471 selection by rule](../../examples/src/demos/471-server-selection.svelte),\n[472 request to SQL](../../examples/src/demos/472-server-sql-planner.svelte),\n[473 grouping rules](../../examples/src/demos/473-server-grouping-rules.svelte),\n[482 CRUD with a version check](../../examples/src/demos/482-server-crud.svelte),\n[483 master-detail](../../examples/src/demos/483-server-master-detail.svelte),\n[500 queries in a Web Worker](../../examples/src/demos/500-worker-data-source.svelte).\n\n### Views of the same grid\n\nThe `board` and `scheduler` props and their config types are free in\n`@svgrid/grid`; what Enterprise ships is the renderer behind each,\nregistered once with `enableBoardView()` or `enableSchedulerView()`\n(`installEnterprise(api)` calls both). The same rows, columns, sort and\nfilter feed every one of them. A [Gantt view](../help/rows/gantt.md) of the\nsame grid is in progress and due on 1 November 2026.\n\n- [Kanban board](../help/rows/kanban-board.md) - cards in lanes, drag-and-drop,\n swimlanes, WIP limits, a card drawer.\n- [Scheduler / calendar](../help/rows/scheduler.md) - month, week, day, agenda\n and timeline views with resources, recurrence and booking rules.\n- [The spreadsheet shell](../help/cells/spreadsheet-shell.md) - `<SvSheet />`\n wraps the grid in a ribbon, formula bar, gutter and sheet tabs over the\n [formula engine](../help/spreadsheet-formulas.md).\n\n## Licensing\n\nYou can evaluate the pack without asking for a key. Until a valid\nlicense key is set, everything still functions, and loading the\nEnterprise module displays a watermark on the grid and a console message\nabout the Enterprise package. Set a key once at app startup and both\ndisappear:\n\n```ts\nimport { setLicenseKey } from '@svgrid/enterprise'\nsetLicenseKey('YOUR-LICENSE-KEY') // the key from your order\n```\n\nThe pack comes in two editions, both covering unlimited production apps.\n**Grid** is everything on this page except the spreadsheet and Studio;\n**Suite** is all of it. The Indie license is the Grid edition at a lower\nprice for freelancers and companies under $1M revenue, without support.\nA key names its edition, and a key that predates\neditions reads as Suite. A Grid key that opens `<SvSheet>` is treated the\nsame way as an unlicensed build: the feature runs, with the watermark and a\nconsole notice naming the edition that covers it.\n\nPricing and the OEM tier for redistribution: <https://svgrid.com/pricing/>.\nSee also [licensing](./licensing.md).\n\n## How Enterprise integrates\n\n```ts\nimport { SvGrid, type SvGridApi } from '@svgrid/grid'\nimport { installEnterprise, setLicenseKey, type EnterpriseGridApi } from '@svgrid/enterprise'\n\nsetLicenseKey(import.meta.env.VITE_SVPRO_KEY)\n\nlet api = $state<EnterpriseGridApi<typeof features, Order> | null>(null)\n```\n\n```svelte\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n onApiReady={(next: SvGridApi<typeof features, Order>) => {\n api = installEnterprise(next)\n }}\n/>\n\n<button onclick={() => api?.exportData({ format: 'xlsx', filename: 'orders' })}>\n Export to Excel\n</button>\n```\n\n`installEnterprise` mutates and returns the same api object - existing\nreferences keep working. The `EnterpriseGridApi` type extends `SvGridApi` so\nthe grid's existing methods are still there alongside the new ones.\n\n## Tree-shaking\n\nEach Enterprise module is a separate subpath export:\n\n```ts\nimport { exportGrid } from '@svgrid/enterprise/export' // export only\nimport { importData } from '@svgrid/enterprise/import' // import only\nimport { createPivotModel } from '@svgrid/enterprise/pivot' // pivot only\n// AI helpers are free + built in: import { aiFilter } from '@svgrid/grid'\n```\n\nIf you only need export, the AI provider plumbing, pivot engine, and\nimport parser don't ship. The `@svgrid/enterprise` barrel import is\nconvenient; the subpaths are smaller.\n\n## Peer dependencies\n\n| Feature | Peer dep | Optional? |\n| ------- | -------------------- | ------------------------------------------ |\n| xlsx | `jszip` | Yes - only loaded when xlsx is exported. |\n| pdf | `pdfmake` | Yes - only loaded when pdf is exported. |\n| import | `jszip` (xlsx only) | Yes - only for xlsx import. |\n| AI | - | -. You bring your own provider client. |\n| pivot | - | -. Pure TypeScript, no runtime deps. |\n\nInstall only what you need:\n\n```bash\npnpm add @svgrid/enterprise jszip # community + Enterprise + xlsx\npnpm add @svgrid/enterprise jszip pdfmake # also pdf\n```\n\n## See also\n\n- [Getting started](../getting-started.md) - if you haven't seen the\n Community walkthrough yet.\n- [Help index](../help/index.md) - all topic pages including the\n Enterprise pages.\n- [Missing features](../help/missing-features.md) - the honest gap list.\n"
|
|
3569
3569
|
},
|
|
3570
3570
|
{
|
|
3571
3571
|
"slug": "enterprise/evaluation",
|
|
3572
3572
|
"path": "docs/enterprise/evaluation.md",
|
|
3573
3573
|
"title": "Enterprise evaluation",
|
|
3574
3574
|
"section": "Enterprise tier",
|
|
3575
|
-
"markdown": "# Enterprise evaluation\n\nYou can try every `@svgrid/enterprise` feature without a key. Install it\nand use it. Nothing is locked; the page shows a small watermark and logs\na console message, and that is the only difference.\n\n\n\n## 1. Install\n\n```bash\nnpm install @svgrid/grid @svgrid/enterprise\nnpm install jszip pdfmake # only needed for Excel and PDF export\n```\n\n## 2. Add Enterprise to a grid\n\n```svelte\n<script>\n import { SvGrid } from '@svgrid/grid'\n import { installEnterprise } from '@svgrid/enterprise'\n\n let api = $state(null)\n\n const rows = [\n { name: 'Ada Lovelace', team: 'Engineering', salary: 145000 },\n { name: 'Alan Turing', team: 'Research', salary: 160000 },\n ]\n const columns = [\n { field: 'name', header: 'Name' },\n { field: 'team', header: 'Team' },\n { field: 'salary', header: 'Salary' },\n ]\n</script>\n\n<SvGrid data={rows} {columns} onApiReady={(next) => (api = installEnterprise(next))} />\n\n<button onclick={() => api?.exportData({ format: 'xlsx', filename: 'team' })}>\n Export to Excel\n</button>\n```\n\nThe `<SvGrid>` component itself stays the same. `installEnterprise()` adds\nthe Enterprise methods to the grid API: `exportData`, `importData`,\n`print`, pivot and AI.\n\nFor a complete page with themes, PDF, CSV and print, see\n[Enterprise getting started](./getting-started.md).\n\n## 3. Try the features\n\nThe [demo gallery](https://svgrid.com/demos/) has a working demo for every\nEnterprise feature, with the source next to it. These pages cover each\none in detail:\n\n- [Export](../help/export.md) - Excel, PDF, CSV\n- [Import](../help/import.md) - column mapping and per-row validation\n\n## Without a key\n\nYou can skip `setLicenseKey()` entirely. Everything still runs, and you\nsee:\n\n- a small \"www.svgrid.com\" watermark on each grid, which fades after 5\n seconds\n- one console message per page load\n- a one-time upgrade card the first time you call an Enterprise feature\n\nNone of these make network calls or write cookies or storage (see\n[security](../help/security.md)).\n\nThis works the same on localhost, staging, or a demo deployment. You don't\nneed to ask anyone for a trial key. When you buy a license, call\n`setLicenseKey()` with your key and the watermark goes away.\n\n## Buying\n\n- **Grid Developer License**, $599 per developer: the enterprise grid.\n- **Suite Developer License**, $999 per developer: adds the spreadsheet\n (`<SvSheet>`) and Studio.\n\
|
|
3575
|
+
"markdown": "# Enterprise evaluation\n\nYou can try every `@svgrid/enterprise` feature without a key. Install it\nand use it. Nothing is locked; the page shows a small watermark and logs\na console message, and that is the only difference.\n\n\n\n## 1. Install\n\n```bash\nnpm install @svgrid/grid @svgrid/enterprise\nnpm install jszip pdfmake # only needed for Excel and PDF export\n```\n\n## 2. Add Enterprise to a grid\n\n```svelte\n<script>\n import { SvGrid } from '@svgrid/grid'\n import { installEnterprise } from '@svgrid/enterprise'\n\n let api = $state(null)\n\n const rows = [\n { name: 'Ada Lovelace', team: 'Engineering', salary: 145000 },\n { name: 'Alan Turing', team: 'Research', salary: 160000 },\n ]\n const columns = [\n { field: 'name', header: 'Name' },\n { field: 'team', header: 'Team' },\n { field: 'salary', header: 'Salary' },\n ]\n</script>\n\n<SvGrid data={rows} {columns} onApiReady={(next) => (api = installEnterprise(next))} />\n\n<button onclick={() => api?.exportData({ format: 'xlsx', filename: 'team' })}>\n Export to Excel\n</button>\n```\n\nThe `<SvGrid>` component itself stays the same. `installEnterprise()` adds\nthe Enterprise methods to the grid API: `exportData`, `importData`,\n`print`, pivot and AI.\n\nFor a complete page with themes, PDF, CSV and print, see\n[Enterprise getting started](./getting-started.md).\n\n## 3. Try the features\n\nThe [demo gallery](https://svgrid.com/demos/) has a working demo for every\nEnterprise feature, with the source next to it. These pages cover each\none in detail:\n\n- [Export](../help/export.md) - Excel, PDF, CSV\n- [Import](../help/import.md) - column mapping and per-row validation\n\n## Without a key\n\nYou can skip `setLicenseKey()` entirely. Everything still runs, and you\nsee:\n\n- a small \"www.svgrid.com\" watermark on each grid, which fades after 5\n seconds\n- one console message per page load\n- a one-time upgrade card the first time you call an Enterprise feature\n\nNone of these make network calls or write cookies or storage (see\n[security](../help/security.md)).\n\nThis works the same on localhost, staging, or a demo deployment. You don't\nneed to ask anyone for a trial key. When you buy a license, call\n`setLicenseKey()` with your key and the watermark goes away.\n\n## Buying\n\n- **Indie Developer License**, $299 per developer: the enterprise grid for\n freelancers and companies under $1M revenue, without support.\n- **Grid Developer License**, $599 per developer: the enterprise grid.\n- **Suite Developer License**, $999 per developer: adds the spreadsheet\n (`<SvSheet>`) and Studio.\n\nAll three cover unlimited apps and are perpetual, with a year of updates\n(and support, except Indie). For 5+ developers, a PO, or redistribution as an SDK, contact\nsales. Details on the [pricing page](https://svgrid.com/pricing/).\n\n## See also\n\n- [Enterprise getting started](./getting-started.md) - a complete working page\n- [Enterprise licensing](./licensing.md) - key formats, seats, renewals\n- [Migration guides](../help/migrating-from-ag-grid.md) - moving from another grid\n"
|
|
3576
3576
|
},
|
|
3577
3577
|
{
|
|
3578
3578
|
"slug": "enterprise/getting-started",
|
|
@@ -3586,7 +3586,7 @@ export const docs = [
|
|
|
3586
3586
|
"path": "docs/enterprise/licensing.md",
|
|
3587
3587
|
"title": "Enterprise licensing",
|
|
3588
3588
|
"section": "Enterprise tier",
|
|
3589
|
-
"markdown": "# Enterprise licensing\n\nYou can evaluate `@svgrid/enterprise` without asking for a key. Loaded\nwithout a license key, the Enterprise module displays a watermark in the\nbottom-right corner of the grid and a console message about the\nEnterprise package; every feature still works. Set a key once at app\nstartup and both disappear.\n\n\n\n## Setting the key\n\n```ts\nimport { setLicenseKey } from '@svgrid/enterprise'\n\nsetLicenseKey(import.meta.env.VITE_SVPRO_KEY)\n```\n\nCall this before the first `<SvGrid>` mounts. In Vite/SvelteKit,\nexpose the key as `VITE_SVPRO_KEY=SVENTERPRISE-...` in your `.env` (NOT\nchecked in) - or read it from your config service.\n\n## License tiers\n\nEvery Enterprise license is a **perpetual license** that includes **1 year of\nupdates and support**. The price shown **renews automatically each year**\nto keep updates and support active; **cancel anytime** and you keep every\nversion released during your paid term.\n\n| License | What it covers | Price (per developer) | Support |\n| ---------------------------------- | ------------------------------------------------------------------ | --------------------- | ----------------------------------------- |\n| **Grid Developer License** | Enterprise grid features. No spreadsheet, no Studio | **$599** | Email (next business day) + private Slack |\n| **Suite Developer License** | Everything in Grid, plus the spreadsheet and Studio | **$999** | Email (next business day) + private Slack |\n| **Enterprise / volume** | Suite, site or organisation-wide | Custom quote | Priority + named contact, NDA / PO |\n| **OEM / redistribution** | Shipping SvGrid to third parties as a component or app builder | Custom quote | Priority + named contact, NDA / PO |\n\nBoth developer licenses cover an **unlimited number of production apps** in your\norganisation. The line between them is the feature set, not the app count.\n\n**Grid ($599)** is the enterprise grid: server-side row model, grouping and tree\ndata, pivot, export and import, print, the advanced filter, alerts, the selection\nbar, and the Kanban, scheduler and Gantt renderers.\n\n**Suite ($999)** adds the two things that are their own products:\n\n- the **spreadsheet**: `<SvSheet>`, the `<sv-sheet>` element, the formula engine,\n and the `.xlsx` / `.xls` / `.ods` / `.csv` readers and writers;\n- **Studio**: the designer, the code generator, and the SQL data sources.\n\n> Priced **per developer** - engineers who write or modify code that imports\n> `@svgrid/enterprise`. Production seats / end users are unlimited. One license key\n> activates every grid in scope - no per-page or per-component accounting.\n> Teams of 5+ and multi-year terms get volume discounts; email\n> `sales@jqwidgets.com`.\n\n### When you need an OEM license\n\nA developer seat covers your own application, including a SaaS product your\ncustomers pay for. It does not cover handing SvGrid to third parties as\nsomething they build with: shipping it as a component or SDK, embedding it in an\napp builder or low-code platform where your customers author their own screens,\nor reselling it white-labelled. Those need an OEM license, priced separately from\nseats. Section 4A of the [EULA](/docs/legal/EULA) has the exact test. If you are\nnot sure which side of the line you are on, email `sales@jqwidgets.com` and\ndescribe the product; the answer is usually one message.\n\n## License key format\n\n```\nSVENTERPRISE-SUITE-XXXX-XXXX-XXXX-XXXX\n│ │\n│ └── edition: GRID or SUITE\n└── prefix the runtime recognises; the rest identifies your license\n```\n\nA key issued before editions existed carries no edition segment. Those keys read\nas Suite, so nothing an existing customer already ships changes.\n\nThe check is purely client-side and **no network call** is ever made to\nvalidate, so air-gapped deployments work out of the box.\n\nIt is also deliberately not cryptography. The runtime classifies the key\nstring - prefix recognised, which edition it names, on the revoked list, a\n`DEV` / `EVAL` sentinel, or a paid key - and nothing more (`checkLicenseKey` in\n`packages/enterprise/src/license-core.ts`). Anyone with devtools can read a key\nout of a deployed bundle, and an unlicensed build still runs; it just shows a\nwatermark and logs a one-time notice. The license is a legal agreement, not a\ntechnical lock, and we would rather say so than imply a DRM scheme that isn't\nthere. Keys are revocable: a key we revoke stops being accepted in later\nreleases.\n\n## Per-environment keys\n\nDifferent keys for different deployment stages so revoking is surgical:\n\n```ts\nconst KEY = {\n development: import.meta.env.VITE_SVPRO_DEV_KEY,\n staging: import.meta.env.VITE_SVPRO_STAGING_KEY,\n production: import.meta.env.VITE_SVPRO_PROD_KEY,\n}[import.meta.env.MODE] ?? ''\n\nsetLicenseKey(KEY)\n```\n\n## What happens without a key\n\n| Surface | Behaviour |\n| --------------------------- | ---------------------------------------------------------- |\n| Grid render | Works. |\n| Editing, sort, filter | Works. |\n| `pro.exportData(...)` | Works. |\n| `pro.importData(...)` | Works. |\n| `pro.ai.*` | Works. |\n| `createPivotModel(...)` | Works. |\n| Studio: designer / panels | Works. |\n| Studio: `createSqlDataSource` | Works. |\n| Studio: MCP generator | Works; output carries a one-line notice. |\n| Watermark | Visible on every grid instance. |\n| Console message | About the Enterprise package, logged once per page load. |\n\nThat is the evaluation: every feature, with the watermark and the\nconsole message until a key is set. Once you're sold, drop in a key.\n\n## A Grid key on a Suite feature\n\nThe same rule, for the same reason. A Grid Developer License that opens\n`<SvSheet>`, calls the formula engine, or reaches a Studio data source gets the\nwatermark and a one-time console notice naming the feature. Nothing stops\nworking and nothing is hidden, so a Grid-tier team can try the spreadsheet in\ntheir own app before deciding to upgrade, exactly as an unlicensed team can.\n\n```ts\nimport { licenseCovers } from '@svgrid/enterprise'\n\nlicenseCovers('spreadsheet') // false on a GRID key, true on SUITE\n```\n\nUse `licenseCovers` if you want to hide a Suite-only entry point in your own UI\nrather than let it nudge.\n\n## Studio (data-app generator)\n\nThe Studio - the schema designer, edit panel, master-detail, the SQL,\nREST and Supabase data sources, and the AI generator - is covered by the\n**Suite Developer License**. There is no Studio-only key and no\nper-feature entitlement inside it: a Suite key covers the whole Studio\ntogether with the spreadsheet and the grid. Loaded without a Suite key,\nevery Studio surface still works and displays the watermark and the\nconsole message about the Enterprise package, as the rest of the package\ndoes.\n\nIt has two places you set the key, because it runs in two places:\n\n**1. In your app (the browser)** - the same `setLicenseKey()` you\nalready call. The designer, edit panel, master-detail, and data sources\nall read it. Nothing new to do.\n\n```ts\nimport { setLicenseKey } from '@svgrid/enterprise'\nsetLicenseKey(import.meta.env.VITE_SVPRO_KEY)\n```\n\n**2. In the AI generator (the MCP server)** - the generator runs in a\nNode process (Claude Code / Desktop), so it reads the key from the\n`SVGRID_LICENSE_KEY` environment variable in your MCP config. Set it\nonce:\n\n```jsonc\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"@svgrid/mcp\"],\n \"env\": { \"SVGRID_LICENSE_KEY\": \"SVENTERPRISE-...\" }\n }\n }\n}\n```\n\nWithout it, the generator still produces code - it just prepends a\none-line commercial notice, and the generated app carries the usual\nwatermark until you call `setLicenseKey()` in it. Same honor-system,\nsame key format, no network calls.\n\n## License renewal\n\nThe license itself is perpetual; what renews each year is your\n**updates-and-support term**. It renews automatically until you cancel\n(cancel anytime). The key keeps validating every version released during\na paid term, and if you cancel or let the term lapse, your installed\nversion keeps working - you just stop receiving new releases and support.\n\n- 60 days before the term ends: yellow nudge on the watermark\n- 30 days: orange\n- 7 days: red\n- After the term ends (if you cancelled): features keep working; only\n versions released after your paid term need a renewed term\n\nWe never disable working features on a paying customer.\n\n## Audit trail\n\nEach license key has a stable ID embedded. The same key activates as\nmany builds as you want; the ID is what we cross-reference against\nyour subscription in support tickets. **No telemetry is sent** -\nsupport uses the ID you give us, not anything we phoned home for.\n\n## See also\n\n- [Enterprise evaluation](./evaluation.md) - trying Enterprise without a key\n- [Enterprise support](./support.md) - SLAs, escalation, contact channels\n- [Pricing](https://svgrid.com/pricing/) - canonical pricing source\n"
|
|
3589
|
+
"markdown": "# Enterprise licensing\n\nYou can evaluate `@svgrid/enterprise` without asking for a key. Loaded\nwithout a license key, the Enterprise module displays a watermark in the\nbottom-right corner of the grid and a console message about the\nEnterprise package; every feature still works. Set a key once at app\nstartup and both disappear.\n\n\n\n## Setting the key\n\n```ts\nimport { setLicenseKey } from '@svgrid/enterprise'\n\nsetLicenseKey(import.meta.env.VITE_SVPRO_KEY)\n```\n\nCall this before the first `<SvGrid>` mounts. In Vite/SvelteKit,\nexpose the key as `VITE_SVPRO_KEY=YOUR-LICENSE-KEY` in your `.env` (NOT\nchecked in) - or read it from your config service.\n\n## License tiers\n\nEvery Enterprise license is a **perpetual license** that includes **1 year of\nupdates and support**. The price shown **renews automatically each year**\nto keep updates and support active; **cancel anytime** and you keep every\nversion released during your paid term.\n\n| License | What it covers | Price (per developer) | Support |\n| ---------------------------------- | ------------------------------------------------------------------ | --------------------- | ----------------------------------------- |\n| **Indie Developer License** | Grid features, for freelancers and companies under $1M revenue | **$299** | None (GitHub issues only), updates only |\n| **Grid Developer License** | Enterprise grid features. No spreadsheet, no Studio | **$599** | Email (next business day) + private Slack |\n| **Suite Developer License** | Everything in Grid, plus the spreadsheet and Studio | **$999** | Email (next business day) + private Slack |\n| **Enterprise / volume** | Suite, site or organisation-wide | Custom quote | Priority + named contact, NDA / PO |\n| **OEM / redistribution** | Shipping SvGrid to third parties as a component or app builder | Custom quote | Priority + named contact, NDA / PO |\n\nAll three developer licenses cover an **unlimited number of production apps** in your\norganisation. The line between them is the feature set, not the app count.\n\n**Grid ($599)** is the enterprise grid: server-side row model, grouping and tree\ndata, pivot, export and import, print, the advanced filter, alerts, the selection\nbar, and the Kanban, scheduler and Gantt renderers.\n\n**Indie ($299)** is the Grid feature set for freelancers and for companies with\nless than $1M in yearly revenue, self-declared at purchase. It comes without\nsupport (no email, no Slack; public GitHub issues only, as with the Community\ntier), and its yearly renewal pays for updates only. Indie orders are\nfulfilled with a standard Grid key. Grow past the threshold and you move the\nseats to Grid at your next renewal.\n\n**Suite ($999)** adds the two things that are their own products:\n\n- the **spreadsheet**: `<SvSheet>`, the `<sv-sheet>` element, the formula engine,\n and the `.xlsx` / `.xls` / `.ods` / `.csv` readers and writers;\n- **Studio**: the designer, the code generator, and the SQL data sources.\n\n> Priced **per developer** - engineers who write or modify code that imports\n> `@svgrid/enterprise`. Production seats / end users are unlimited. One license key\n> activates every grid in scope - no per-page or per-component accounting.\n> Teams of 5+ and multi-year terms get volume discounts; email\n> `sales@jqwidgets.com`.\n\n### When you need an OEM license\n\nA developer seat covers your own application, including a SaaS product your\ncustomers pay for. It does not cover handing SvGrid to third parties as\nsomething they build with: shipping it as a component or SDK, embedding it in an\napp builder or low-code platform where your customers author their own screens,\nor reselling it white-labelled. Those need an OEM license, priced separately from\nseats. Section 4A of the [EULA](/docs/legal/EULA) has the exact test. If you are\nnot sure which side of the line you are on, email `sales@jqwidgets.com` and\ndescribe the product; the answer is usually one message.\n\n## The license key\n\nEvery customer receives the same license key, a GUID, in the order email. Set\nit once at app startup with `setLicenseKey()`; it covers every edition and\ncarries no expiry date. Your edition, seat count and updates term are recorded\non your order and governed by the [EULA](/docs/legal/EULA), not encoded in the\nkey.\n\nThe check is client-side and **no network call** is ever made to validate, so\nair-gapped deployments work out of the box. The package keeps only a SHA-256 of\nthe key and compares the key you set against it\n(`packages/enterprise/src/license-core.ts`), so the key is not readable in\n`node_modules`.\n\nA key that is not the license key (a typo, or an `SVENTERPRISE-...` string from\nbefore October 2026) never throws: the features still run, with the watermark\nand a one-time console warning, exactly as if no key were set.\n\nIt is not DRM. Anyone with devtools can read a key out of a deployed bundle,\nwhich is why the key file must never be committed to a public repository. The\nlicense is a legal agreement, not a technical lock, and we would rather say so\nthan imply a scheme that isn't there.\n\n## Per-environment keys\n\nDifferent keys for different deployment stages so revoking is surgical:\n\n```ts\nconst KEY = {\n development: import.meta.env.VITE_SVPRO_DEV_KEY,\n staging: import.meta.env.VITE_SVPRO_STAGING_KEY,\n production: import.meta.env.VITE_SVPRO_PROD_KEY,\n}[import.meta.env.MODE] ?? ''\n\nsetLicenseKey(KEY)\n```\n\n## What happens without a key\n\n| Surface | Behaviour |\n| --------------------------- | ---------------------------------------------------------- |\n| Grid render | Works. |\n| Editing, sort, filter | Works. |\n| `pro.exportData(...)` | Works. |\n| `pro.importData(...)` | Works. |\n| `pro.ai.*` | Works. |\n| `createPivotModel(...)` | Works. |\n| Studio: designer / panels | Works. |\n| Studio: `createSqlDataSource` | Works. |\n| Studio: MCP generator | Works; output carries a one-line notice. |\n| Watermark | Visible on every grid instance. |\n| Console message | About the Enterprise package, logged once per page load. |\n\nThat is the evaluation: every feature, with the watermark and the\nconsole message until a key is set. Once you're sold, drop in a key.\n\n## A Grid key on a Suite feature\n\nThe same rule, for the same reason. A Grid Developer License that opens\n`<SvSheet>`, calls the formula engine, or reaches a Studio data source gets the\nwatermark and a one-time console notice naming the feature. Nothing stops\nworking and nothing is hidden, so a Grid-tier team can try the spreadsheet in\ntheir own app before deciding to upgrade, exactly as an unlicensed team can.\n\n```ts\nimport { licenseCovers } from '@svgrid/enterprise'\n\nlicenseCovers('spreadsheet') // false on a GRID key, true on SUITE\n```\n\nUse `licenseCovers` if you want to hide a Suite-only entry point in your own UI\nrather than let it nudge.\n\n## Studio (data-app generator)\n\nThe Studio - the schema designer, edit panel, master-detail, the SQL,\nREST and Supabase data sources, and the AI generator - is covered by the\n**Suite Developer License**. There is no Studio-only key and no\nper-feature entitlement inside it: a Suite key covers the whole Studio\ntogether with the spreadsheet and the grid. Loaded without a Suite key,\nevery Studio surface still works and displays the watermark and the\nconsole message about the Enterprise package, as the rest of the package\ndoes.\n\nIt has two places you set the key, because it runs in two places:\n\n**1. In your app (the browser)** - the same `setLicenseKey()` you\nalready call. The designer, edit panel, master-detail, and data sources\nall read it. Nothing new to do.\n\n```ts\nimport { setLicenseKey } from '@svgrid/enterprise'\nsetLicenseKey(import.meta.env.VITE_SVPRO_KEY)\n```\n\n**2. In the AI generator (the MCP server)** - the generator runs in a\nNode process (Claude Code / Desktop), so it reads the key from the\n`SVGRID_LICENSE_KEY` environment variable in your MCP config. Set it\nonce:\n\n```jsonc\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"@svgrid/mcp\"],\n \"env\": { \"SVGRID_LICENSE_KEY\": \"YOUR-LICENSE-KEY\" }\n }\n }\n}\n```\n\nWithout it, the generator still produces code - it just prepends a\none-line commercial notice, and the generated app carries the usual\nwatermark until you call `setLicenseKey()` in it. Same honor-system,\nsame key format, no network calls.\n\n## License renewal\n\nThe license itself is perpetual; what renews each year is your\n**updates-and-support term**. It renews automatically until you cancel\n(cancel anytime). The key keeps validating every version released during\na paid term, and if you cancel or let the term lapse, your installed\nversion keeps working - you just stop receiving new releases and support.\n\n- 60 days before the term ends: yellow nudge on the watermark\n- 30 days: orange\n- 7 days: red\n- After the term ends (if you cancelled): features keep working; only\n versions released after your paid term need a renewed term\n\nWe never disable working features on a paying customer.\n\n## Audit trail\n\nEach license key has a stable ID embedded. The same key activates as\nmany builds as you want; the ID is what we cross-reference against\nyour subscription in support tickets. **No telemetry is sent** -\nsupport uses the ID you give us, not anything we phoned home for.\n\n## See also\n\n- [Enterprise evaluation](./evaluation.md) - trying Enterprise without a key\n- [Enterprise support](./support.md) - SLAs, escalation, contact channels\n- [Pricing](https://svgrid.com/pricing/) - canonical pricing source\n"
|
|
3590
3590
|
},
|
|
3591
3591
|
{
|
|
3592
3592
|
"slug": "enterprise/studio",
|
|
@@ -3614,7 +3614,7 @@ export const docs = [
|
|
|
3614
3614
|
"path": "docs/enterprise/studio/ai-generation.md",
|
|
3615
3615
|
"title": "AI generation",
|
|
3616
3616
|
"section": "Studio",
|
|
3617
|
-
"markdown": "# AI generation\n\nThe `@svgrid/mcp` server exposes Studio to AI coding agents (Claude Code, Cursor,\nCodex, ...) through the Model Context Protocol. Ask your agent to build a screen\nfor a table and it introspects, scaffolds, and verifies - producing the same code\nthe [CLI](./cli.md) and [designer](./designer.md) do.\n\n\n\n## How it fits together\n\nThe MCP server makes **no model calls of its own**. It hands your agent a set of\ntools; the agent's own model decides when to call them. So the loop is:\n\n```\nyou -> your agent (its model) -> svgrid MCP tools -> files on disk\n ^ |\n +-------- svelte-check verify <----------+\n```\n\nYour schema and data stay on your machine; nothing is sent to our servers.\n\n## Configure the MCP server\n\nAdd it to your agent's MCP config (the key is passed as an env var, since the\nserver runs in a Node process):\n\n```jsonc\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"@svgrid/mcp\"],\n \"env\": { \"SVGRID_LICENSE_KEY\": \"
|
|
3617
|
+
"markdown": "# AI generation\n\nThe `@svgrid/mcp` server exposes Studio to AI coding agents (Claude Code, Cursor,\nCodex, ...) through the Model Context Protocol. Ask your agent to build a screen\nfor a table and it introspects, scaffolds, and verifies - producing the same code\nthe [CLI](./cli.md) and [designer](./designer.md) do.\n\n\n\n## How it fits together\n\nThe MCP server makes **no model calls of its own**. It hands your agent a set of\ntools; the agent's own model decides when to call them. So the loop is:\n\n```\nyou -> your agent (its model) -> svgrid MCP tools -> files on disk\n ^ |\n +-------- svelte-check verify <----------+\n```\n\nYour schema and data stay on your machine; nothing is sent to our servers.\n\n## Configure the MCP server\n\nAdd it to your agent's MCP config (the key is passed as an env var, since the\nserver runs in a Node process):\n\n```jsonc\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"@svgrid/mcp\"],\n \"env\": { \"SVGRID_LICENSE_KEY\": \"YOUR-LICENSE-KEY\" }\n }\n }\n}\n```\n\nThe same block works across hosts - only the file it lives in differs:\n\n| Host | Config location |\n| --- | --- |\n| Claude Code | `.mcp.json` at the project root, or `claude mcp add` |\n| Cursor | `.cursor/mcp.json` |\n| Windsurf | `~/.codeium/windsurf/mcp_config.json` |\n| Codex / other | the host's `mcpServers` config |\n\nRestart (or reload) the agent so it picks up the server, then confirm the\n`svgrid` tools are listed.\n\n## The tools\n\nAlongside the read-only knowledge tools (examples, docs, API reference), the\nserver exposes two generation tools:\n\n| Tool | What it does |\n| --- | --- |\n| `svgrid_scaffold` with `schemaOnly: true` | Infer an `EntitySchema` from a Drizzle schema file (`from:\"drizzle\"`) or sample JSON rows (`from:\"json\"`). Returns a **draft** to review. |\n| `svgrid_scaffold` | Generate the SvelteKit files - from a Drizzle schema, sample rows, or an `EntitySchema` you already have, in one call. The output is **compile-verified** (the generated page is run through the Svelte compiler) before it comes back, and each file carries `svgrid:managed` markers. |\n\n## Drive the whole project model\n\nBeyond single screens, the server exposes the full\n[project model](./concepts.md#the-project-model) - the same\n`studio.config.json` the visual designer edits - as four `studio_*` tools.\nYour agent can build a complete multi-screen app, or continue editing one the\ndesigner produced, and hand it back.\n\n**They are opt-in.** Set `SVGRID_MCP_STUDIO=1`, or a valid\n`SVGRID_LICENSE_KEY`, in the MCP server's env. Tools that need a licence to be\nuseful should not cost every other user context on every request.\n\n| Tool | What it does |\n| --- | --- |\n| `studio_project` | `new` an empty project, `load` a `studio.config.json`, `describe` the current one (entities, screens, block ids, theme, RBAC, auth, deploy), `config` to get it back as a string for round-tripping, `capabilities` to list the block kinds, UI component keys, theme presets, source kinds and deploy targets this version supports |\n| `studio_apply` | A **batch** of model changes applied in order: `add_entity`, `add_screen`, `add_block`, `add_component`, `update_block`, `remove_block`, `move_block`, `update_screen`, `remove_screen` |\n| `studio_configure` | Project-wide settings in one call: `theme`, `auth`, `access`, `tenancy`, `data_layer`, `job`, `deploy_target`, `screen_layout`, `form_layout`, `field_conditions`, `entity_source` |\n| `studio_build` | `validate` the project (errors + warnings), then `generate` the full runnable SvelteKit app - every file, ready to write and `svelte-check` |\n\nCall `studio_project` with `action: \"capabilities\"` before applying anything:\nit reports exactly what the installed version supports, so the agent uses real\nblock kinds and component keys rather than plausible-looking ones.\n\n`studio_apply` takes a batch on purpose. This was 27 separate tools, one per\nmutation, which made a five-screen app twenty-odd round trips and cost every\nuser of the free grid ~3,741 tokens of tool definitions on every request. A\nwhole screen is now one call:\n\n```json\n{\n \"ops\": [\n { \"op\": \"add_entity\", \"rows\": [{ \"id\": 1, \"subject\": \"Login fails\", \"status\": \"open\" }], \"name\": \"tickets\" },\n { \"op\": \"add_screen\", \"title\": \"Dashboard\" },\n { \"op\": \"add_block\", \"screen\": \"dashboard\", \"kind\": \"kpi\", \"entity\": \"tickets\" },\n { \"op\": \"add_block\", \"screen\": \"dashboard\", \"kind\": \"chart\", \"entity\": \"tickets\" }\n ]\n}\n```\n\nIf an op fails, the response says which one and what had already applied, so\nthe agent retries the tail rather than the whole batch.\n\nThe 27 individual tool names still answer, so an existing prompt keeps working\n- they are simply no longer advertised.\n\nA prompt that exercises the loop end to end:\n\n> \"Using the svgrid MCP: new project 'Support desk'. Add a `tickets` entity from\n> these sample rows, a dashboard screen with a KPI and a chart over tickets,\n> RBAC with an agent role that cannot delete, dark theme, then validate and\n> generate the app.\"\n\n## Step by step\n\n1. **Point it at a source.** A Drizzle schema file, or a handful of sample rows.\n2. **Introspect.** The agent calls `svgrid_scaffold` with `schemaOnly: true` and shows you the drafted\n `EntitySchema` - field names, types, primary key, guessed formats.\n3. **Refine (optional).** Correct a type, mark a field hidden or read-only, add\n validation - in chat, or later in the [visual designer](./app-designer.md).\n4. **Scaffold.** The agent calls `svgrid_scaffold` again without `schemaOnly`; the files come back already\n run through the Svelte compiler.\n5. **Verify.** The agent runs your project's `svelte-check`; if anything fails it\n iterates. This is the loop that keeps AI output trustworthy.\n\n## Prompts that work\n\nFrom a Drizzle schema:\n\n> \"Using the svgrid MCP, build a CRUD screen for the `customers` table in\n> `src/lib/db/schema.ts`.\"\n\nFrom sample data, when there is no schema yet:\n\n> \"Here are five example rows of our invoices. Use the svgrid MCP to introspect a\n> schema, then scaffold a CRUD screen at `/invoices`.\"\n>\n> ```json\n> [{ \"id\": \"INV-1\", \"customer\": \"Acme\", \"amount\": 4200, \"paid\": true, \"due\": \"2026-07-01\" }]\n> ```\n\nRefining before you commit:\n\n> \"Show me the drafted schema first. Mark `internalNotes` hidden, make `email`\n> required, and set `status` to an enum of draft/sent/paid before scaffolding.\"\n\n## What comes back\n\n`svgrid_scaffold` writes three files (the same layout as the CLI and designer):\n\n```\nsrc/lib/customers.schema.ts # the EntitySchema + row type\nsrc/routes/api/customers/+server.ts # createKitHandlers data endpoint\nsrc/routes/customers/+page.svelte # the grid + edit-panel screen\n```\n\nEach carries `svgrid:managed` markers so a re-generation updates the managed\nregions and leaves your hand-written code untouched. See\n[code generation](./code-generation.md) for the anatomy of each file.\n\n## Bring your own key\n\nThe generator uses **your** agent's model and API key - your schema and data\nnever touch our servers. The MCP server itself makes no model calls; it provides\nintrospection + scaffolding + verification tools that the host agent drives.\n\n## Licensing\n\nYou can evaluate generation without a key: it runs\nand prepends a one-line commercial notice, and the generated app displays\nthe watermark and the console message about the Enterprise package until\nyou call `setLicenseKey()`. Set `SVGRID_LICENSE_KEY` in the MCP config to license it. See\n[licensing](../licensing.md#studio-data-app-generator).\n\n## See also\n\n- [The Studio CLI](./cli.md) - the deterministic, no-AI path\n- [Visual app designer](./app-designer.md) - refine an AI draft by hand before generating\n- [Code generation](./code-generation.md) - the anatomy of the emitted files\n- [MCP server](../../help/mcp-server.md) - full MCP reference\n"
|
|
3618
3618
|
},
|
|
3619
3619
|
{
|
|
3620
3620
|
"slug": "enterprise/studio/api",
|
|
@@ -4027,7 +4027,7 @@ export const docs = [
|
|
|
4027
4027
|
"path": "docs/help/ai.md",
|
|
4028
4028
|
"title": "AI assistant",
|
|
4029
4029
|
"section": "Help",
|
|
4030
|
-
"markdown": "# AI assistant\n\nBring a language model into your grid with helpers that stay strictly\nmodel-agnostic: **natural-language filter**, **smart fill**, **summarise**,\n**classify**, **chart-this**, **find anomalies**, and **natural-language\nexport**. Built in and **free** in\n**[@svgrid/grid](https://www.npmjs.com/package/@svgrid/grid)** - no license key,\nno separate package. They ship no model client and do nothing until you\nregister a provider, so they add nothing to your bundle unless you import them.\n\n\n\nRun all four helpers live - the demo below is wired to the bundled\ndeterministic `mockAIProvider`, so no keys required:\n\n<div data-docs-demo=\"51-ai-assistant\" data-height=\"560\"></div>\n\n\n## What it is\n\nImport the helpers from `@svgrid/grid` and call them with your grid `api`\n(the one you get from `onApiReady`):\n\n```ts\nimport {\n aiFilter, aiSmartFill, aiSummarize, aiClassify, aiExport, aiFindAnomalies,\n} from '@svgrid/grid'\n\naiFilter(api, query, opts?) // NL query -> filter + sort plan\naiSmartFill(api, opts) // examples -> proposed column values\naiSummarize(api, opts) // row / selection / group / all -> text + bullets\naiClassify(api, opts) // free-text cells -> bucketed labels\naiExport(api, query, opts?) // NL query -> filter + group + format, then export*\naiFindAnomalies(api, opts?) // scan a slice for outliers / bad values\n```\n\nEvery call routes through one `AIProvider` you register at app boot.\nThe grid never bundles a model client - you keep full control of model\nchoice, routing, and data handling.\n\n> \\* `aiExport` plans the export for free; **writing** the enterprise formats\n> (xlsx / pdf) uses the `@svgrid/enterprise` export engine when it is installed,\n> otherwise it returns the plan without downloading a file.\n\n## When to use it\n\n- **NL filter** is the highest-leverage feature: it replaces a dozen\n per-column filter operators with one search box for analyst users.\n- **Smart fill** is the killer feature for spreadsheet-style entry: type\n one or two examples in a column, accept the rest with one click.\n- **Summarise** is for dashboards where the user wants a \"what's\n interesting here?\" paragraph without clicking through every cell.\n- **Classify** is for triage workflows where free-text rows need a\n consistent bucket label before downstream automation runs.\n\nIf you don't need natural-language anywhere, just don't import these\nhelpers - they tree-shake away and cost nothing.\n\n## Setting up the provider\n\nThe grid talks to your model through a single async function. Wire it\nonce at app startup:\n\n```ts\nimport { setAIProvider, type AIProvider } from '@svgrid/grid'\n\nconst myProvider: AIProvider = async ({ prompt, responseFormat, signal, task, maxOutputTokens }) => {\n const r = await fetch('/api/ai', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ prompt, responseFormat, task, maxOutputTokens }),\n signal,\n })\n if (!r.ok) throw new Error(`AI provider returned ${r.status}`)\n return r.text()\n}\n\nsetAIProvider(myProvider)\n```\n\nA few design points worth knowing:\n\n- **`responseFormat: 'json'`** is what `aiFilter`, `aiSmartFill`,\n `aiSummarize`, and `aiClassify` all request. Tell your model to return\n strict JSON only; the grid `JSON.parse`s the result. (A common\n resilience trick: the grid strips a single markdown code fence\n automatically so models that wrap JSON in ` ```json ... ``` ` still\n parse cleanly.)\n- **`signal`** is forwarded so consumers can cancel in-flight calls\n when the user moves on.\n- **`task`** is a tag (`'filter' | 'smart-fill' | 'summarize' | 'classify'`)\n - useful when you want to route different tasks to different models\n (a cheap one for filter, a stronger one for summarise).\n- **`maxOutputTokens`** is a soft hint, also useful for cost routing.\n\nFor testing or for demo purposes, the package ships a deterministic\n`mockAIProvider` that returns plausible canned shapes per task. Wire it\nin development:\n\n```ts\nimport { setAIProvider, mockAIProvider } from '@svgrid/grid'\nsetAIProvider(mockAIProvider)\n```\n\n## 1. Natural-language filter\n\nTranslate a sentence into a filter + sort plan against the current\ngrid's columns. The grid embeds the column schema (names, types, sample\nvalues) in the prompt so the model picks real field names rather than\nhallucinating.\n\n```ts\nconst plan = await aiFilter(api, 'accounts losing momentum in EMEA, by NPS')\n// {\n// filters: [\n// { field: 'region', operator: 'equals', value: 'EMEA' },\n// { field: 'nps', operator: 'lessThan', value: '30' },\n// ],\n// sort: [{ field: 'nps', desc: false }],\n// rationale: 'EMEA region, low NPS, sorted ascending.',\n// }\n```\n\nBy default `aiFilter` returns the plan but **does not apply it** to the\ngrid - that lets you show a preview (\"here's what I'd do, accept?\")\nbefore committing. Pass `{ apply: true }` to apply directly:\n\n```ts\nawait aiFilter(api, 'big EMEA deals', { apply: true })\n```\n\n### Hallucination guard\n\nIf the model invents a column name that doesn't exist in your data, the\nhelper silently drops that clause rather than passing it to `setFilter`,\nwhich would otherwise throw. This is intentional: you'd rather lose a\nclause than crash the page.\n\n## 2. Smart fill\n\nUser provides one or two worked examples for a column; the grid asks\nthe model to propose values for the remaining empty cells.\n\n```ts\nconst result = await aiSmartFill(api, {\n field: 'tier',\n examples: [\n { input: { company: 'Northwind' }, output: 'enterprise' },\n { input: { company: 'Helios' }, output: 'growth' },\n ],\n})\n// result.predictions: [{ rowIndex, value, confidence }, ...]\n```\n\nYou decide what to do with the predictions - accept-all, accept-per-cell,\nwrite them to a `proposedTier` field on the row data and render a \"✓\"\nbutton in the cell, etc. The example demo does per-cell accept with a\nconfidence-coloured pill.\n\nIf `targetRowIndices` is omitted, the helper auto-selects rows whose\ncurrent `field` value is `null`, `undefined`, or `''`.\n\n## 3. Summarise\n\nDrop a slice of the grid into the model and ask for a one-paragraph +\nbulleted summary. Four target modes:\n\n```ts\nawait aiSummarize(api, { target: { kind: 'all' } })\nawait aiSummarize(api, { target: { kind: 'row', rowIndex: 5 } })\nawait aiSummarize(api, { target: { kind: 'selection', rowIndices: [1,2,3] } })\nawait aiSummarize(api, { target: { kind: 'group', field: 'region', value: 'EMEA' } })\n```\n\nFor large slices the grid samples rows uniformly so the prompt stays\nunder a sensible token budget. The response shape:\n\n```ts\n{\n text: 'One paragraph...',\n bullets: ['punchy bullet 1', 'punchy bullet 2', ...],\n highlightedFields: ['arr', 'nps'], // columns the summary leans on\n}\n```\n\nThe optional `question` parameter biases the summary toward the columns\nthat answer the question.\n\n## 4. Classify\n\nBucket free-text cells into one of a known set of labels:\n\n```ts\nconst r = await aiClassify(api, {\n inputField: 'notes',\n outputField: 'sentiment',\n classes: ['at-risk', 'expanding', 'steady'],\n classDescriptions: {\n 'at-risk': 'churn signals, escalations, lost champion',\n 'expanding': 'new modules, more seats, additional regions',\n 'steady': 'no signals in either direction',\n },\n})\n```\n\nThe helper filters out any predictions whose value is not in `classes`,\nso downstream code can trust the output is a clean enum.\n\n## 5. Natural-language export\n\nDescribe an export in plain English; the model returns a\n`{ format, filters, sort, groupBy }` plan, which is applied to the grid and\nhanded to `exportData`:\n\n```ts\nconst plan = await aiExport(api, 'export EU orders from Q2 as a grouped PDF by country')\n// -> { format: 'pdf', filters: [...], groupBy: ['country'], rationale: '...' }\n```\n\n| Option | Type | Default | Notes |\n| ---------- | --------- | ---------- | ----- |\n| `apply` | `boolean` | `false` | Also apply the filter/sort/grouping to the grid view. Off by default so the export never disturbs the grid. |\n| `run` | `boolean` | `true` | Download the file. Set `false` to preview the plan first. |\n| `filename` | `string` | `'export'` | Base name (no extension). |\n\nThe export is **self-contained**: it computes its own rows from the plan\n(filter + sort + group applied to the full dataset), so the download is correct\nregardless of the grid's current view, and the grid is left untouched unless\nyou pass `apply: true`. It reuses the same hallucination guard as `filter`\n(unknown column names are dropped) and clamps `format` to a supported value\n(default `xlsx`). Preview before committing with `{ run: false }`, show the\n`rationale`, then re-run.\n\n## 6. Find anomalies\n\nScan a slice (all / selection / group) for outliers and inconsistent values:\n\n```ts\nconst { anomalies, summary } = await aiFindAnomalies(api, { target: { kind: 'all' } })\n// anomalies: [{ rowIndex?, field?, value?, reason, severity: 'low'|'medium'|'high' }]\n```\n\n`rowIndex` is relative to the scanned slice. Pairs naturally with export -\nfind the odd rows, then export just those.\n\n## Subscribing the grid to predictions\n\nCell snippets cache their output by `(row, column)`. If you store\npredictions in a *separate* state ref - e.g. a `Map<rowIndex, value>`\nthat the snippet looks up at render time - the grid won't know to\nre-render when that map changes. **Write the proposal onto the row\nitself instead:**\n\n```ts\nasync function runClassify() {\n const result = await aiClassify(api, { /* ... */ })\n const byIdx = new Map(result.predictions.map((p) => [p.rowIndex, p]))\n // Re-assign the data array - Svelte 5 reactivity picks this up and the\n // grid re-renders every visible cell.\n accounts = accounts.map((a, i) => {\n const p = byIdx.get(i)\n return p ? { ...a, proposedSentiment: p.value, sentimentConfidence: p.confidence } : a\n })\n}\n```\n\nThen your cell snippet reads `props.row.proposedSentiment` and re-renders\nexactly when expected.\n\n## No license gate\n\nThe AI helpers are built into the free `@svgrid/grid` and are **never** gated -\nno key, no watermark, no nudge. The only license interaction is `aiExport`'s\nfinal write step: emitting an enterprise format (xlsx / pdf) goes through\n`@svgrid/enterprise`'s export engine, which carries the usual enterprise\nwatermark until a `SVENTERPRISE-` key is set. Planning the export, and every\nother AI helper, is unconditionally free.\n\n## Frequently asked questions\n\n### What AI features does SvGrid have?\n\nThe `@svgrid/grid` package ships built-in, free, model-agnostic AI helpers:\nnatural-language filter, smart fill, summarise, classify, chart-this, find\nanomalies, and natural-language export. They run through a bring-your-own-model\nadapter, so you wire in your own LLM endpoint.\n\n### Which LLM does SvGrid use?\n\nNone by default - it is model-agnostic. You supply an adapter for OpenAI,\nAnthropic Claude, a local model, or anything else. The demo ships a mock\nprovider so you can evaluate the flow without an API key.\n\n### Is my grid data sent to an AI provider?\n\nOnly if you wire one up and invoke a helper. SvGrid itself makes no network\ncalls; the AI helpers send exactly the prompt you construct to the adapter you\nconfigure, so you control what leaves the browser.\n\n## More examples\n\n### NL filter bar (AI)\n\nType \"EMEA active over 50k\" - the AI Platform parses your phrase into api.setFilter / setSort / topN calls. Demo ships a rule-based fallback so you can evaluate without a key; production wiring needs an AI Platform key.\n\n<div data-docs-demo=\"92-nl-filter-bar\" data-height=\"460\"></div>\n\n### AI: chart this\n\nOpen the Chart panel, press the AI button, and describe the chart in words - the model reads the grid's column schema and returns a ChartSpec the built-in panel renders. Ships with a deterministic mock provider; swap in your own via setAIProvider.\n\nIt can ask for any type the panel builds from a dimension, a measure and an\noptional split: bar, line, area, pie, treemap, funnel, waterfall, radar,\nheatmap, box plot, gauge, calendar and sankey. Scatter, candlestick and OHLC are\ndeliberately out - they need a second (or a fourth) measure that a chart plan\ncannot express, so asking for one would return a plan the panel draws as an\nempty frame.\n\nEvery plan is validated against the real schema before it is applied, including\nits shape: a heatmap or sankey without a split, or a calendar whose dimension is\nnot a date column, falls back to a bar rather than rendering nothing.\n\nThe Explain button beside it runs `aiExplainChart(api)` on the active chart\n(or a `spec` you pass): the prompt is grounded on `chartSummary(spec)`, the\nplain-language reading the chart hands to screen readers, plus a compact\ntable of the first 50 categories, so the model comments on numbers it was\ngiven rather than on a picture. It returns `{ summary, insights }`, and\n`enableAiCharting(api)` registers both handlers.\n\n```ts\nconst { summary, insights } = await aiExplainChart(api)\n// summary: 'Revenue rises 42% from 1.2k at Jan to 1.7k at Dec, peaking at 2.0k at Aug.'\n// insights: ['The growth is front-loaded: ...', 'Compare the peak against ...']\n```\n\n<div data-docs-demo=\"357-ai-chart-this\" data-height=\"560\"></div>\n\n### AI export + anomaly scan\n\nNatural-language export: describe an export in English and the AI provider turns it into a filter + group + format plan, applies it, and downloads. Plus a one-click anomaly scan. Runs on the bundled mock model.\n\n<div data-docs-demo=\"203-ai-export-and-anomalies\" data-height=\"460\"></div>\n\n## See also\n\n- [Demo 21 - Export + Print](../../examples/src/demos/21-export-and-print.svelte) - the\n Enterprise export engine that `aiExport` writes through when it is installed.\n- [Demo 51 - AI assistant](../../examples/src/demos/51-ai-assistant.svelte) - the full demo this\n page documents, with all four helpers wired to the mock provider.\n"
|
|
4030
|
+
"markdown": "# AI assistant\n\nBring a language model into your grid with helpers that stay strictly\nmodel-agnostic: **natural-language filter**, **smart fill**, **summarise**,\n**classify**, **chart-this**, **find anomalies**, and **natural-language\nexport**. Built in and **free** in\n**[@svgrid/grid](https://www.npmjs.com/package/@svgrid/grid)** - no license key,\nno separate package. They ship no model client and do nothing until you\nregister a provider, so they add nothing to your bundle unless you import them.\n\n\n\nRun all four helpers live - the demo below is wired to the bundled\ndeterministic `mockAIProvider`, so no keys required:\n\n<div data-docs-demo=\"51-ai-assistant\" data-height=\"560\"></div>\n\n\n## What it is\n\nImport the helpers from `@svgrid/grid` and call them with your grid `api`\n(the one you get from `onApiReady`):\n\n```ts\nimport {\n aiFilter, aiSmartFill, aiSummarize, aiClassify, aiExport, aiFindAnomalies,\n} from '@svgrid/grid'\n\naiFilter(api, query, opts?) // NL query -> filter + sort plan\naiSmartFill(api, opts) // examples -> proposed column values\naiSummarize(api, opts) // row / selection / group / all -> text + bullets\naiClassify(api, opts) // free-text cells -> bucketed labels\naiExport(api, query, opts?) // NL query -> filter + group + format, then export*\naiFindAnomalies(api, opts?) // scan a slice for outliers / bad values\n```\n\nEvery call routes through one `AIProvider` you register at app boot.\nThe grid never bundles a model client - you keep full control of model\nchoice, routing, and data handling.\n\n> \\* `aiExport` plans the export for free; **writing** the enterprise formats\n> (xlsx / pdf) uses the `@svgrid/enterprise` export engine when it is installed,\n> otherwise it returns the plan without downloading a file.\n\n## When to use it\n\n- **NL filter** is the highest-leverage feature: it replaces a dozen\n per-column filter operators with one search box for analyst users.\n- **Smart fill** is the killer feature for spreadsheet-style entry: type\n one or two examples in a column, accept the rest with one click.\n- **Summarise** is for dashboards where the user wants a \"what's\n interesting here?\" paragraph without clicking through every cell.\n- **Classify** is for triage workflows where free-text rows need a\n consistent bucket label before downstream automation runs.\n\nIf you don't need natural-language anywhere, just don't import these\nhelpers - they tree-shake away and cost nothing.\n\n## Setting up the provider\n\nThe grid talks to your model through a single async function. Wire it\nonce at app startup:\n\n```ts\nimport { setAIProvider, type AIProvider } from '@svgrid/grid'\n\nconst myProvider: AIProvider = async ({ prompt, responseFormat, signal, task, maxOutputTokens }) => {\n const r = await fetch('/api/ai', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ prompt, responseFormat, task, maxOutputTokens }),\n signal,\n })\n if (!r.ok) throw new Error(`AI provider returned ${r.status}`)\n return r.text()\n}\n\nsetAIProvider(myProvider)\n```\n\nA few design points worth knowing:\n\n- **`responseFormat: 'json'`** is what `aiFilter`, `aiSmartFill`,\n `aiSummarize`, and `aiClassify` all request. Tell your model to return\n strict JSON only; the grid `JSON.parse`s the result. (A common\n resilience trick: the grid strips a single markdown code fence\n automatically so models that wrap JSON in ` ```json ... ``` ` still\n parse cleanly.)\n- **`signal`** is forwarded so consumers can cancel in-flight calls\n when the user moves on.\n- **`task`** is a tag (`'filter' | 'smart-fill' | 'summarize' | 'classify'`)\n - useful when you want to route different tasks to different models\n (a cheap one for filter, a stronger one for summarise).\n- **`maxOutputTokens`** is a soft hint, also useful for cost routing.\n\nFor testing or for demo purposes, the package ships a deterministic\n`mockAIProvider` that returns plausible canned shapes per task. Wire it\nin development:\n\n```ts\nimport { setAIProvider, mockAIProvider } from '@svgrid/grid'\nsetAIProvider(mockAIProvider)\n```\n\n## 1. Natural-language filter\n\nTranslate a sentence into a filter + sort plan against the current\ngrid's columns. The grid embeds the column schema (names, types, sample\nvalues) in the prompt so the model picks real field names rather than\nhallucinating.\n\n```ts\nconst plan = await aiFilter(api, 'accounts losing momentum in EMEA, by NPS')\n// {\n// filters: [\n// { field: 'region', operator: 'equals', value: 'EMEA' },\n// { field: 'nps', operator: 'lessThan', value: '30' },\n// ],\n// sort: [{ field: 'nps', desc: false }],\n// rationale: 'EMEA region, low NPS, sorted ascending.',\n// }\n```\n\nBy default `aiFilter` returns the plan but **does not apply it** to the\ngrid - that lets you show a preview (\"here's what I'd do, accept?\")\nbefore committing. Pass `{ apply: true }` to apply directly:\n\n```ts\nawait aiFilter(api, 'big EMEA deals', { apply: true })\n```\n\n### Hallucination guard\n\nIf the model invents a column name that doesn't exist in your data, the\nhelper silently drops that clause rather than passing it to `setFilter`,\nwhich would otherwise throw. This is intentional: you'd rather lose a\nclause than crash the page.\n\n## 2. Smart fill\n\nUser provides one or two worked examples for a column; the grid asks\nthe model to propose values for the remaining empty cells.\n\n```ts\nconst result = await aiSmartFill(api, {\n field: 'tier',\n examples: [\n { input: { company: 'Northwind' }, output: 'enterprise' },\n { input: { company: 'Helios' }, output: 'growth' },\n ],\n})\n// result.predictions: [{ rowIndex, value, confidence }, ...]\n```\n\nYou decide what to do with the predictions - accept-all, accept-per-cell,\nwrite them to a `proposedTier` field on the row data and render a \"✓\"\nbutton in the cell, etc. The example demo does per-cell accept with a\nconfidence-coloured pill.\n\nIf `targetRowIndices` is omitted, the helper auto-selects rows whose\ncurrent `field` value is `null`, `undefined`, or `''`.\n\n## 3. Summarise\n\nDrop a slice of the grid into the model and ask for a one-paragraph +\nbulleted summary. Four target modes:\n\n```ts\nawait aiSummarize(api, { target: { kind: 'all' } })\nawait aiSummarize(api, { target: { kind: 'row', rowIndex: 5 } })\nawait aiSummarize(api, { target: { kind: 'selection', rowIndices: [1,2,3] } })\nawait aiSummarize(api, { target: { kind: 'group', field: 'region', value: 'EMEA' } })\n```\n\nFor large slices the grid samples rows uniformly so the prompt stays\nunder a sensible token budget. The response shape:\n\n```ts\n{\n text: 'One paragraph...',\n bullets: ['punchy bullet 1', 'punchy bullet 2', ...],\n highlightedFields: ['arr', 'nps'], // columns the summary leans on\n}\n```\n\nThe optional `question` parameter biases the summary toward the columns\nthat answer the question.\n\n## 4. Classify\n\nBucket free-text cells into one of a known set of labels:\n\n```ts\nconst r = await aiClassify(api, {\n inputField: 'notes',\n outputField: 'sentiment',\n classes: ['at-risk', 'expanding', 'steady'],\n classDescriptions: {\n 'at-risk': 'churn signals, escalations, lost champion',\n 'expanding': 'new modules, more seats, additional regions',\n 'steady': 'no signals in either direction',\n },\n})\n```\n\nThe helper filters out any predictions whose value is not in `classes`,\nso downstream code can trust the output is a clean enum.\n\n## 5. Natural-language export\n\nDescribe an export in plain English; the model returns a\n`{ format, filters, sort, groupBy }` plan, which is applied to the grid and\nhanded to `exportData`:\n\n```ts\nconst plan = await aiExport(api, 'export EU orders from Q2 as a grouped PDF by country')\n// -> { format: 'pdf', filters: [...], groupBy: ['country'], rationale: '...' }\n```\n\n| Option | Type | Default | Notes |\n| ---------- | --------- | ---------- | ----- |\n| `apply` | `boolean` | `false` | Also apply the filter/sort/grouping to the grid view. Off by default so the export never disturbs the grid. |\n| `run` | `boolean` | `true` | Download the file. Set `false` to preview the plan first. |\n| `filename` | `string` | `'export'` | Base name (no extension). |\n\nThe export is **self-contained**: it computes its own rows from the plan\n(filter + sort + group applied to the full dataset), so the download is correct\nregardless of the grid's current view, and the grid is left untouched unless\nyou pass `apply: true`. It reuses the same hallucination guard as `filter`\n(unknown column names are dropped) and clamps `format` to a supported value\n(default `xlsx`). Preview before committing with `{ run: false }`, show the\n`rationale`, then re-run.\n\n## 6. Find anomalies\n\nScan a slice (all / selection / group) for outliers and inconsistent values:\n\n```ts\nconst { anomalies, summary } = await aiFindAnomalies(api, { target: { kind: 'all' } })\n// anomalies: [{ rowIndex?, field?, value?, reason, severity: 'low'|'medium'|'high' }]\n```\n\n`rowIndex` is relative to the scanned slice. Pairs naturally with export -\nfind the odd rows, then export just those.\n\n## Subscribing the grid to predictions\n\nCell snippets cache their output by `(row, column)`. If you store\npredictions in a *separate* state ref - e.g. a `Map<rowIndex, value>`\nthat the snippet looks up at render time - the grid won't know to\nre-render when that map changes. **Write the proposal onto the row\nitself instead:**\n\n```ts\nasync function runClassify() {\n const result = await aiClassify(api, { /* ... */ })\n const byIdx = new Map(result.predictions.map((p) => [p.rowIndex, p]))\n // Re-assign the data array - Svelte 5 reactivity picks this up and the\n // grid re-renders every visible cell.\n accounts = accounts.map((a, i) => {\n const p = byIdx.get(i)\n return p ? { ...a, proposedSentiment: p.value, sentimentConfidence: p.confidence } : a\n })\n}\n```\n\nThen your cell snippet reads `props.row.proposedSentiment` and re-renders\nexactly when expected.\n\n## No license gate\n\nThe AI helpers are built into the free `@svgrid/grid` and are **never** gated -\nno key, no watermark, no nudge. The only license interaction is `aiExport`'s\nfinal write step: emitting an enterprise format (xlsx / pdf) goes through\n`@svgrid/enterprise`'s export engine, which carries the usual enterprise\nwatermark until your license key is set. Planning the export, and every\nother AI helper, is unconditionally free.\n\n## Frequently asked questions\n\n### What AI features does SvGrid have?\n\nThe `@svgrid/grid` package ships built-in, free, model-agnostic AI helpers:\nnatural-language filter, smart fill, summarise, classify, chart-this, find\nanomalies, and natural-language export. They run through a bring-your-own-model\nadapter, so you wire in your own LLM endpoint.\n\n### Which LLM does SvGrid use?\n\nNone by default - it is model-agnostic. You supply an adapter for OpenAI,\nAnthropic Claude, a local model, or anything else. The demo ships a mock\nprovider so you can evaluate the flow without an API key.\n\n### Is my grid data sent to an AI provider?\n\nOnly if you wire one up and invoke a helper. SvGrid itself makes no network\ncalls; the AI helpers send exactly the prompt you construct to the adapter you\nconfigure, so you control what leaves the browser.\n\n## More examples\n\n### NL filter bar (AI)\n\nType \"EMEA active over 50k\" - the AI Platform parses your phrase into api.setFilter / setSort / topN calls. Demo ships a rule-based fallback so you can evaluate without a key; production wiring needs an AI Platform key.\n\n<div data-docs-demo=\"92-nl-filter-bar\" data-height=\"460\"></div>\n\n### AI: chart this\n\nOpen the Chart panel, press the AI button, and describe the chart in words - the model reads the grid's column schema and returns a ChartSpec the built-in panel renders. Ships with a deterministic mock provider; swap in your own via setAIProvider.\n\nIt can ask for any type the panel builds from a dimension, a measure and an\noptional split: bar, line, area, pie, treemap, funnel, waterfall, radar,\nheatmap, box plot, gauge, calendar and sankey. Scatter, candlestick and OHLC are\ndeliberately out - they need a second (or a fourth) measure that a chart plan\ncannot express, so asking for one would return a plan the panel draws as an\nempty frame.\n\nEvery plan is validated against the real schema before it is applied, including\nits shape: a heatmap or sankey without a split, or a calendar whose dimension is\nnot a date column, falls back to a bar rather than rendering nothing.\n\nThe Explain button beside it runs `aiExplainChart(api)` on the active chart\n(or a `spec` you pass): the prompt is grounded on `chartSummary(spec)`, the\nplain-language reading the chart hands to screen readers, plus a compact\ntable of the first 50 categories, so the model comments on numbers it was\ngiven rather than on a picture. It returns `{ summary, insights }`, and\n`enableAiCharting(api)` registers both handlers.\n\n```ts\nconst { summary, insights } = await aiExplainChart(api)\n// summary: 'Revenue rises 42% from 1.2k at Jan to 1.7k at Dec, peaking at 2.0k at Aug.'\n// insights: ['The growth is front-loaded: ...', 'Compare the peak against ...']\n```\n\n<div data-docs-demo=\"357-ai-chart-this\" data-height=\"560\"></div>\n\n### AI export + anomaly scan\n\nNatural-language export: describe an export in English and the AI provider turns it into a filter + group + format plan, applies it, and downloads. Plus a one-click anomaly scan. Runs on the bundled mock model.\n\n<div data-docs-demo=\"203-ai-export-and-anomalies\" data-height=\"460\"></div>\n\n## See also\n\n- [Demo 21 - Export + Print](../../examples/src/demos/21-export-and-print.svelte) - the\n Enterprise export engine that `aiExport` writes through when it is installed.\n- [Demo 51 - AI assistant](../../examples/src/demos/51-ai-assistant.svelte) - the full demo this\n page documents, with all four helpers wired to the mock provider.\n"
|
|
4031
4031
|
},
|
|
4032
4032
|
{
|
|
4033
4033
|
"slug": "help/alerts",
|
|
@@ -4391,7 +4391,7 @@ export const docs = [
|
|
|
4391
4391
|
"path": "docs/help/comparison.md",
|
|
4392
4392
|
"title": "Comparison: SvGrid vs AG Grid vs TanStack Table",
|
|
4393
4393
|
"section": "Help",
|
|
4394
|
-
"markdown": "\n# Comparison: SvGrid vs AG Grid vs TanStack Table\n\nThe three projects solve overlapping problems, and the right choice\ndepends on the framework you ship on, how much of the grid you want to\nbuild yourself, and your budget. Every number on this page is read from\nnpm or measured by a script in this repository on the date shown; the\nblock below is regenerated by `node tools/sync-guide-facts.mjs` and the\nper-competitor pages under [/compare/](https://svgrid.com/compare/) list\nthe sources for every feature claim.\n\n<!-- facts:start ag-grid,tanstack-table -->\n> **Facts, checked 12 Sep 2026.** `ag-grid-community` 36.1.0, MIT, last published 5 Aug 2026, 12,400,000 npm downloads in the 30 days to 10 Sep 2026. `@tanstack/svelte-table` 9.2.4, MIT, last published 28 Aug 2026, 231,000 npm downloads in the same window. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `ag-grid-community` 36.1.0 317.5 KB JS, no separate stylesheet (measured 12 Sep 2026); `@tanstack/svelte-table` 9.2.4 36.3 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). AG Grid pricing, as its site states it: AG Grid Community is free under MIT. AG Grid Enterprise is listed at $999 USD per developer with one year of updates and Zendesk support; the Enterprise Bundle with AG Charts Enterprise is $1,498 USD per developer (https://www.ag-grid.com/license-pricing/, read 12 Sep 2026). TanStack Table pricing, as its site states it: TanStack Table is MIT and free; tanstack.com is sponsor-supported and offers Enterprise Support as private consulting and expert support, with no licence sold for the table (https://tanstack.com/table/latest, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/), [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/).\n<!-- facts:end -->\n\n## TL;DR\n\n| Project | Lives in | Ships | Licence |\n| --------------------- | ---------------------------------------- | ---------------------------------------------------------- | ----------------------------------------- |\n| **SvGrid** | Svelte 5 | Headless core + Svelte render component + Enterprise pack | MIT (Community) / commercial (Enterprise) |\n| **AG Grid Community** | React, Angular, Vue, plain JS | Full grid + renderer; Svelte through community integrations | MIT |\n| **AG Grid Enterprise**| same | Adds the set filter, range selection, master/detail, tree, grouping, pivot, charts, Excel export, server-side row model | Commercial, per developer |\n| **TanStack Table** | React, Vue, Svelte, Solid, Qwik, Lit, JS | Headless engine **only**; the Svelte adapter is Svelte 5 | MIT |\n\nThe bundle sizes and prices are in the facts block above, with the date\nthey were read and the method behind the sizes.\n\n## When SvGrid is the right choice\n\n- You're on **Svelte 5** and want a grid that uses the runtime's idioms\n (snippets for cells, `$state` for data, `$derived` for aggregates) -\n not a React-port pretending to be Svelte.\n- You want a **headless core you can render yourself** AND a\n default-styled component for the 80% case. Most \"headless\" libraries\n make you write the markup; most \"monolith\" libraries make you fight\n the markup. SvGrid does both in one package.\n- You need **clean theming via CSS custom properties** and a documented\n `--sg-*` token surface, not a hard-coded class soup.\n- You ship under **strict CSP** (no `eval`, no `new Function`, no\n inline scripts). SvGrid runs clean; AG Grid Community does too.\n TanStack Table is engine-only so the question doesn't apply.\n- You want **SSR markup that is meaningful before hydration** (good\n first paint, SEO, SvelteKit `+page.server` integration). SvGrid +\n TanStack Table both qualify. AG Grid renders client-side.\n- You want the features AG Grid sells as Enterprise - the set filter,\n range selection, master/detail, tree data, grouping with aggregation,\n integrated charts, flat server-side infinite scroll - **in the MIT\n core**. (Server-side grouping, tree, pivot and transactions are\n Enterprise in both.)\n\n## When AG Grid is the right choice\n\n- You're on **React, Angular, or Vue**, not Svelte. SvGrid is\n Svelte-only, and ag-grid.com points Svelte users to community-built\n integrations rather than an official package.\n- You need a push-based **viewport row model** for a real-time trading\n blotter, where the server streams the visible window over a socket.\n SvGrid's server-side row model covers sort, filter, grouping, tree,\n pivot, transactions and select-all across unloaded rows, and its\n real-time page merges deltas into loaded rows, but it does not have the\n viewport model.\n- You need **pluggable custom filter components or custom tool panels**.\n SvGrid's tool panel is a fixed Columns + Filters pair.\n- You need **AG Charts** for maps, network graphs, 3D or a canvas renderer.\n SvGrid's chart is SVG with decimation, and it ships 29 types, a configurable\n axis model, synchronized charts, a financial toolkit with indicator panes\n and drawing tools, a builder and PDF export in the MIT core; it does not\n draw maps.\n- You want a vendor with **a decade of enterprise procurement paperwork**\n already on file.\n\n## When TanStack Table is the right choice\n\n- You want a **rendering-framework-agnostic engine** so the same\n business logic powers React + Svelte + Solid surfaces in your\n monorepo.\n- You're already in the TanStack ecosystem (Query, Router, Form,\n Virtual) and want one mental model.\n- You're happy writing **all the markup yourself** - the row recycling,\n the keyboard map, the ARIA roles, the focus management, the\n drag-to-resize. That's the cost of \"engine only\".\n\n## Feature parity at a glance\n\nYes: shipped in that edition. Partial: needs extra work or a companion\npackage. No: not available. The AG Grid columns follow ag-grid.com's\nCommunity vs Enterprise page and its Set Filter, Tree Data and CSV export\npages; the dated list of those sources is on the\n[SvGrid vs AG Grid](https://svgrid.com/compare/ag-grid/) page, and the\nTanStack sources on [SvGrid vs TanStack Table](https://svgrid.com/compare/tanstack-table/).\n\n| | SvGrid Community | SvGrid Enterprise | AG Grid Community | AG Grid Enterprise | TanStack Table |\n| ------------------------------- | ---------------- | ----------------- | ----------------- | ------------------ | -------------- |\n| Headless core (engine only) | Yes | Yes | No | No | Yes |\n| Default render component | Yes (Svelte 5) | Yes | Yes (each framework) | Yes | No |\n| Sort (multi-column) | Yes | Yes | Yes | Yes | Yes (engine) |\n| Filter menu (operator + facet) | Yes | Yes | Partial (text and number filters; the set filter is Enterprise) | Yes | No |\n| Filter row | Yes | Yes | Yes | Yes | No |\n| Pagination | Yes | Yes | Yes | Yes | Yes (engine) |\n| Grouping + aggregation | Yes | Yes | No (Enterprise) | Yes | Yes (engine) |\n| Tree / expand-collapse rows | Yes | Yes | No (Enterprise) | Yes | Yes (engine) |\n| Master/detail | Yes | Yes | No (Enterprise) | Yes | No |\n| Cell range selection + copy/paste | Yes | Yes | No (Enterprise) | Yes | No |\n| Fill handle | Yes | Yes | No (Enterprise) | Yes | No |\n| Inline editing (typed editors) | Yes | Yes | Yes | Yes | No |\n| Column virtualization | Yes | Yes | Yes | Yes | No |\n| Row virtualization | Yes | Yes | Yes | Yes | Partial (pair with TanStack Virtual) |\n| Column pinning (left/right) | Yes | Yes | Yes | Yes | No |\n| Column tool panel | Yes | Yes | No (Enterprise) | Yes | No |\n| Context menu | Yes | Yes | No (Enterprise) | Yes | No |\n| Fit-to-width with shrink | Yes | Yes | Partial | Yes | No |\n| WAI-ARIA grid pattern | Yes | Yes | Yes | Yes | No (your markup) |\n| Server-side data, flat (sort / filter / paging / infinite scroll) | Yes (built in) | Yes (built in) | Yes (infinite row model) | Yes (built in) | Partial (manual flags) |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | No (Enterprise) | Yes (built in) | No (Enterprise) | Yes (built in) | No |\n| Global search over server-side data | Yes (`filterModel.global`) | Yes | No (the quick filter is client-side only) | No | n/a |\n| CSP-clean (no eval, no inline) | Yes | Yes | Yes | Yes | n/a |\n| Meaningful SSR markup | Yes | Yes | No | No | depends on your markup |\n| CSV / TSV / JSON export | Yes | Yes | Yes (CSV) | Yes | No |\n| Excel (.xlsx) / PDF export | No | Yes | No | Yes (Excel) | No |\n| Print | No | Yes | No | No | No |\n| Excel / CSV import | No | Yes | No | No | No |\n| In-grid AI helpers (bring your own model) | Yes | Yes | No | No | No |\n| MCP server for AI assistants | Yes (`@svgrid/mcp`) | Yes | Yes (`ag-mcp`) | Yes | No (agent skills ship in the package) |\n| Pivot table | No | Yes | No | Yes | No (custom) |\n| Integrated charts | Yes (29 types, builder, financial toolkit) | Yes | No | Yes (AG Charts) | No |\n| Support response time | GitHub (best-effort) | 1 business day; 1h sev-1 on Enterprise | GitHub (best-effort) | no number published | GitHub; paid Enterprise Support offered |\n| Theming via CSS variables | Yes (`--sg-*`) | Yes | Yes (theme builder) | Yes | n/a |\n| Source button per demo | Yes (gallery) | Yes | No | No | No |\n\n## Bundle size\n\nThe facts block at the top of the page has the gzipped size of each\npackage, measured by the same method: each package built alone with Vite\nin library mode, minified, gzip level 9, Svelte external because it is a\npeer dependency. SvGrid's own number comes from `pnpm size:json`\n(`packages/grid/scripts/measure-size.mjs`), the competitors' from\n`pnpm competitors:measure`; both write `docs/_data` and the block is\nregenerated from there, so the page cannot quote a size nobody measured.\n\nWhat the SvGrid number contains: the whole render component -\nvirtualization, Excel-style filters, inline editing, grouping, tree,\nmaster/detail, cell selection and accessibility - in one import, plus a\nseparate stylesheet. Charts, date and time editors, menus and export split\ninto `import()` chunks that load on demand rather than shipping in the\ninitial bundle; the headless core on its own is a small fraction of the\nrender component, and `@svgrid/enterprise` features are separate subpath\nimports. The per-entry breakdown, including the headless core and the\nlazy chunks, is in the [bundle size reference](./bundle-size.md).\n\nWhat the AG Grid number contains: `createGrid` with every Community\nmodule registered and the Quartz theme, whose CSS ships inside the script\nunder the theming API, so there is no separate stylesheet to add. The\nTanStack number is the whole Svelte adapter with its engine: no\nvirtualizer, filter UI or editors, because a headless library has none.\n\n## Measured performance\n\nA vendor's own benchmark is worth nothing unless you can rerun it, so the\nharness is in the repository and takes an adapter per grid. Adding another\ngrid is about forty lines in `examples/src/bench/adapters.ts` and nothing\nelse.\n\n```bash\n# headless, prints the table and writes tests/perf/.last-compare.json\nBENCH_REPEATS=7 BENCH_GRIDS=svgrid,aggrid,svar,tanstack pnpm bench:compare\n\n# move that run into docs/_data/competitors.json, then regenerate this page\nnode tools/record-benchmarks.mjs && node tools/sync-guide-facts.mjs\n\n# or drive it by hand\npnpm --filter @svgrid/grid-example-gallery dev # then open /bench.html\n```\n\nEach operation is timed until the grid's DOM reflects it, plus one frame:\n\n- **Mount** - fresh container, create the grid, until rows are painted.\n- **Sort** - change the sort on one column, until the new order is painted.\n Text sorts `name` (tens of thousands of distinct values), numeric sorts\n `amount`.\n- **Filter** - apply a `contains` filter to one column.\n- **Scroll** - 180 frames at 60 px/frame, sampling frame intervals.\n\n### Results\n\nThe table is generated from the ledger by `tools/sync-guide-facts.mjs`;\nthe versions and the date are part of it.\n\n<!-- bench:start -->\nMeasured 12 Sep 2026 with `pnpm bench:compare` (tests/perf/compare.spec.ts, recorded by tools/record-benchmarks.mjs): 100,000 rows x 9 columns; 1000 x 520 px container, 32 px rows, 140 px columns, each grid with its default theme; fastest of 7 samples per operation, each grid in a fresh page; Chromium through Playwright, headless; win32 10.0.26200 x64, Intel(R) Core(TM) Ultra 7 255U; a developer workstation, not a dedicated bench rig. Lower is better.\n\n| Operation | SvGrid | AG Grid Community | SVAR Svelte DataGrid | TanStack Table, minimal DOM |\n| --- | --- | --- | --- | --- |\n| Mount | 75.5 ms | 51.4 ms | 11.4 ms | 196 ms |\n| Sort, text column | 149 ms | 282.8 ms | 187.2 ms | 466 ms |\n| Sort, numeric column | 115.7 ms | 270 ms | 165.1 ms | 374.6 ms |\n| Filter, one column (indicative only, see below) | 99.6 ms | 170.4 ms | 32.6 ms | 111.7 ms |\n| Scroll, p95 frame | 34.6 ms | 35.9 ms | 34.8 ms | 35.3 ms |\n| Frames dropped while scrolling, of 180 | 0 | 0 | 0 | 1 |\n| Rows kept in the DOM (virtualization on) | 27 | 35 | 19 | 27 |\n\nVersions: `@svgrid/grid` 3.0.3, `ag-grid-community` 36.1.0, `wx-svelte-grid` 2.7.0, `@tanstack/svelte-table` 9.2.4.\n<!-- bench:end -->\n\nRead that as: **SvGrid sorts faster than AG Grid Community and SVAR on both\ncolumn types, scrolling is level across all four, and mounting is where the\nlighter grids are ahead** - SVAR paints its first rows fastest, AG Grid is\nahead of SvGrid, and the TanStack renderer pays for building a row object\nper record before it can draw anything. Anyone claiming a single headline\nnumber for a grid comparison is selling something.\n\n**The filter row is not a like-for-like comparison and is shown only because\nhiding a number we win looks worse than explaining it.** The grids' single-\ncolumn filter APIs differ: the harness drives AG Grid's quick filter, which\nsearches every column and is strictly more work than the single-column\n`contains` SvGrid performs, while SVAR and TanStack run a predicate over the\none column. Do not read a ratio into that row.\n\n**The TanStack column is an engine plus the least DOM an app could draw.**\nTanStack Table renders nothing, so its adapter draws the row model through\na fixed-height windowed table with no virtualizer library, no filter UI and\nno editors. Its mount and sort numbers include creating the engine's row\nobjects for every record; the grids around it do the same work inside their\nown models.\n\nSorting is where SvGrid's distance comes from, and it is not subtle: SvGrid\nresolves each sort clause once and precomputes a key array, and for a\ncolumn whose distinct values are far fewer than its rows it collates the\ndistinct values once and sorts by rank. Mounting is the other direction -\nsee the accounting in [benchmarks](./benchmarks.md).\n\nTwo methodology notes, both of which were bugs in this harness before they\nwere notes, and both of which changed the numbers by more than any code\nchange did:\n\n- **Each grid runs in a fresh page.** They used to run one after another in\n the same one, where the first warmed the JIT, fragmented the heap and\n left a hundred thousand rows of garbage for the next. Back-to-back runs\n on an idle machine disagreed with themselves by a factor of two.\n Run-to-run variance is now a few percent.\n- **Operations are timed until the DOM changes, not for a fixed two\n frames.** The old fixed wait put a two-frame floor under every number -\n an operation that recomputed nothing at all measured the floor, and a\n mount whose rows were already in the DOM measured pure waiting - which\n flattered whichever grid was slower.\n- **Each figure is the fastest of the samples, not the median.** Noise\n only ever adds time, so the minimum is the cleanest estimate of what the\n machine can do, and medians on this box drifted by a third between\n consecutive runs - more than most of the differences being measured.\n Applied identically to every grid.\n\nWhat this table deliberately does not include:\n\n- **Features the grids do not measure the same way.** Grouping, pivot,\n editing and export all differ enough in shape that a single timing would\n compare two different amounts of work. The filter row above is the one\n case we publish anyway, labelled, rather than quietly dropping a result\n that happens to favour us.\n- **Any grid we cannot license for this.** The harness is grid-agnostic on\n purpose, but some commercial grids licence their software in ways that\n restrict using it to produce competitive claims. Where that is the case\n we do not ship an adapter, and we would rather have an obviously\n incomplete table than a legally dubious one. Run your own shortlist.\n- **Your workload.** One dataset shape, one machine, one browser, default\n configuration for every grid. If a grid decision rides on this, clone the\n harness and put your own data in it.\n\n## Migrating from AG Grid\n\nThe most common starting point. See\n[Migrating from AG Grid](./migrating-from-ag-grid.md) for a side-by-side\ntranslation of column defs, features, filtering, editing, and the\nimperative API. The example that guide is built around runs here:\n\n<div data-docs-demo=\"139-migration-from-ag-grid\" data-height=\"560\"></div>\n\n## Migrating from TanStack Table\n\nThe map is one-to-one - SvGrid's headless core speaks the vocabulary\nTanStack Table v9 introduced. The big differences:\n\n- Replace `createTable(opts)` with `createSvGrid(opts)`. Same state\n machine, same features object.\n- Replace the row-model factories with the same names from\n `@svgrid/grid`.\n- The render layer changes - TanStack hands you `FlexRender` + the\n row model; SvGrid lets you keep that headless approach OR drop in\n the default `<SvGrid>` component.\n\nThe headless demo below drives a plain `<table>` from `createSvGrid`, the\nway a TanStack app would:\n\n<div data-docs-demo=\"186-headless-table\" data-height=\"520\"></div>\n\nAnd the same rows through the render component, which is the part TanStack\nleaves to you. The example runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Order = {\n id: number\n customer: string\n region: string\n status: string\n amount: number\n }\n\n const orders: Order[] = [\n { id: 1, customer: 'Ada Lovelace', region: 'EMEA', status: 'open', amount: 1240 },\n { id: 2, customer: 'Grace Hopper', region: 'AMER', status: 'shipped', amount: 860 },\n { id: 3, customer: 'Linus Torvalds', region: 'EMEA', status: 'closed', amount: 2210 },\n { id: 4, customer: 'Radia Perlman', region: 'APAC', status: 'open', amount: 430 },\n { id: 5, customer: 'Barbara Liskov', region: 'AMER', status: 'pending', amount: 1780 },\n ]\n\n let rows = $state<Order[]>(orders)\n\n const columns: GridColumns<Order> = [\n { field: 'customer', header: 'Customer', width: 180 },\n { field: 'region', header: 'Region', width: 110 },\n { field: 'status', header: 'Status', width: 110 },\n { field: 'amount', header: 'Amount', width: 120, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable selectable />\n```\n\n## Pricing\n\nSvGrid Community is MIT - free for commercial use, no attribution\nrequired at runtime. SvGrid Enterprise is a per-developer licence: $599\nper developer per year for the enterprise grid or $999 with the\nspreadsheet and Studio, both for unlimited applications; see\n<https://svgrid.com/pricing/> for what each tier adds.\n\nAG Grid Community is MIT. AG Grid Enterprise is priced per developer with\none year of updates; the figure ag-grid.com listed on the date we read it\nis in the facts block at the top of this page, and the\n[SvGrid vs AG Grid](https://svgrid.com/compare/ag-grid/) page carries the\nlink. Compare what each paid tier adds before comparing prices: most of\nwhat AG Grid sells as Enterprise is in SvGrid's free core.\n\nTanStack Table is MIT and sponsor-funded; tanstack.com offers paid\nEnterprise Support as private consulting.\n\n## Frequently asked questions\n\n### What is the best data grid for Svelte 5?\n\nFor a Svelte-5-native grid with a batteries-included render component, SvGrid is\nbuilt around runes and snippets. TanStack Table is a strong headless-only\nchoice if you want to build the DOM layer yourself across frameworks, and its\nv9 Svelte adapter targets Svelte 5. AG Grid is the most feature-complete but\nlives in React, Angular and Vue first and reaches Svelte through\ncommunity-built integrations.\n\n### Is SvGrid a good AG Grid alternative?\n\nYes, for Svelte projects. SvGrid is a fraction of AG Grid Community's\nmeasured size on a Svelte page (the facts block has both numbers and the\nmethod), is MIT-licensed for commercial use, and offers `@svgrid/enterprise`\nfor export, print, import and pivot at a per-developer price. On the\nbenchmark above it sorts a hundred-thousand-row column faster on both\ncolumn types and scrolls level; AG Grid mounts quicker. It does not match\nevery AG Grid Enterprise feature - see the\n[missing-features list](./missing-features.md) for the gaps.\n\n### SvGrid vs TanStack Table - which should I pick?\n\nPick SvGrid if you want virtualization, Excel-style filters, selection, and\ninline editing working out of the box on Svelte 5. Pick TanStack Table if you\nwant a framework-agnostic headless engine and are happy to build the rendering,\nvirtualization, and editing UI yourself. Both are MIT-licensed.\n\n### Does the TanStack Svelte adapter support Svelte 5?\n\nYes. The `@tanstack/svelte-table` v9 line declares a Svelte 5 peer range\nand passes data through getters rather than stores; the facts block above\nshows the version read from npm. The earlier `createSvelteTable` constructor\nis gone in v9.\n\n### Does AG Grid have an MCP server like SvGrid?\n\nYes. `ag-mcp` (MIT) gives an assistant AG Grid's docs, examples and\nversion-specific upgrade prompts. `@svgrid/mcp` does the same for SvGrid\nand adds a code checker that validates props and imports against the real\nAPI surface, a scaffold tool and a preview. Neither is an in-grid feature;\nSvGrid's natural-language filter, smart fill and summarise helpers are, and\nthey ship free in `@svgrid/grid` with a model provider you register.\n\n### How big is the SvGrid bundle?\n\nThe facts block at the top of this page has the measured gzipped size of the\nfull `<SvGrid>` render component and its stylesheet, read from\n`docs/_data/svgrid-size.json`, which `pnpm size:json` writes. The\n[bundle size reference](./bundle-size.md) breaks it down by entry:\nthe headless core on its own, the core subpath, the charts, and the lazy\nchunks that load on demand.\n\n## See also\n\n- [Why headless?](../why-headless.md) - the design decision behind\n SvGrid's two-layer architecture.\n- [Migrating from AG Grid](./migrating-from-ag-grid.md) - the\n practical recipe.\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - the\n one-to-one API map.\n- [Benchmarks](./benchmarks.md) - how the numbers are produced and what\n they leave out.\n- [Enterprise feature pack](../enterprise/README.md) - what SvGrid charges for.\n- [Missing features](./missing-features.md) - the honest gap list\n versus AG Grid Enterprise.\n- [All comparisons](https://svgrid.com/compare/) - one page per grid, with\n dated sources for every claim.\n"
|
|
4394
|
+
"markdown": "\n# Comparison: SvGrid vs AG Grid vs TanStack Table\n\nThe three projects solve overlapping problems, and the right choice\ndepends on the framework you ship on, how much of the grid you want to\nbuild yourself, and your budget. Every number on this page is read from\nnpm or measured by a script in this repository on the date shown; the\nblock below is regenerated by `node tools/sync-guide-facts.mjs` and the\nper-competitor pages under [/compare/](https://svgrid.com/compare/) list\nthe sources for every feature claim.\n\n<!-- facts:start ag-grid,tanstack-table -->\n> **Facts, checked 12 Sep 2026.** `ag-grid-community` 36.1.0, MIT, last published 5 Aug 2026, 12,400,000 npm downloads in the 30 days to 10 Sep 2026. `@tanstack/svelte-table` 9.2.4, MIT, last published 28 Aug 2026, 231,000 npm downloads in the same window. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `ag-grid-community` 36.1.0 317.5 KB JS, no separate stylesheet (measured 12 Sep 2026); `@tanstack/svelte-table` 9.2.4 36.3 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). AG Grid pricing, as its site states it: AG Grid Community is free under MIT. AG Grid Enterprise is listed at $999 USD per developer with one year of updates and Zendesk support; the Enterprise Bundle with AG Charts Enterprise is $1,498 USD per developer (https://www.ag-grid.com/license-pricing/, read 12 Sep 2026). TanStack Table pricing, as its site states it: TanStack Table is MIT and free; tanstack.com is sponsor-supported and offers Enterprise Support as private consulting and expert support, with no licence sold for the table (https://tanstack.com/table/latest, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/), [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/).\n<!-- facts:end -->\n\n## TL;DR\n\n| Project | Lives in | Ships | Licence |\n| --------------------- | ---------------------------------------- | ---------------------------------------------------------- | ----------------------------------------- |\n| **SvGrid** | Svelte 5 | Headless core + Svelte render component + Enterprise pack | MIT (Community) / commercial (Enterprise) |\n| **AG Grid Community** | React, Angular, Vue, plain JS | Full grid + renderer; Svelte through community integrations | MIT |\n| **AG Grid Enterprise**| same | Adds the set filter, range selection, master/detail, tree, grouping, pivot, charts, Excel export, server-side row model | Commercial, per developer |\n| **TanStack Table** | React, Vue, Svelte, Solid, Qwik, Lit, JS | Headless engine **only**; the Svelte adapter is Svelte 5 | MIT |\n\nThe bundle sizes and prices are in the facts block above, with the date\nthey were read and the method behind the sizes.\n\n## When SvGrid is the right choice\n\n- You're on **Svelte 5** and want a grid that uses the runtime's idioms\n (snippets for cells, `$state` for data, `$derived` for aggregates) -\n not a React-port pretending to be Svelte.\n- You want a **headless core you can render yourself** AND a\n default-styled component for the 80% case. Most \"headless\" libraries\n make you write the markup; most \"monolith\" libraries make you fight\n the markup. SvGrid does both in one package.\n- You need **clean theming via CSS custom properties** and a documented\n `--sg-*` token surface, not a hard-coded class soup.\n- You ship under **strict CSP** (no `eval`, no `new Function`, no\n inline scripts). SvGrid runs clean; AG Grid Community does too.\n TanStack Table is engine-only so the question doesn't apply.\n- You want **SSR markup that is meaningful before hydration** (good\n first paint, SEO, SvelteKit `+page.server` integration). SvGrid +\n TanStack Table both qualify. AG Grid renders client-side.\n- You want the features AG Grid sells as Enterprise - the set filter,\n range selection, master/detail, tree data, grouping with aggregation,\n integrated charts, flat server-side infinite scroll - **in the MIT\n core**. (Server-side grouping, tree, pivot and transactions are\n Enterprise in both.)\n\n## When AG Grid is the right choice\n\n- You're on **React, Angular, or Vue**, not Svelte. SvGrid is\n Svelte-only, and ag-grid.com points Svelte users to community-built\n integrations rather than an official package.\n- You need a push-based **viewport row model** for a real-time trading\n blotter, where the server streams the visible window over a socket.\n SvGrid's server-side row model covers sort, filter, grouping, tree,\n pivot, transactions and select-all across unloaded rows, and its\n real-time page merges deltas into loaded rows, but it does not have the\n viewport model.\n- You need **pluggable custom filter components or custom tool panels**.\n SvGrid's tool panel is a fixed Columns + Filters pair.\n- You need **AG Charts** for maps, network graphs, 3D or a canvas renderer.\n SvGrid's chart is SVG with decimation, and it ships 29 types, a configurable\n axis model, synchronized charts, a financial toolkit with indicator panes\n and drawing tools, a builder and PDF export in the MIT core; it does not\n draw maps.\n- You want a vendor with **a decade of enterprise procurement paperwork**\n already on file.\n\n## When TanStack Table is the right choice\n\n- You want a **rendering-framework-agnostic engine** so the same\n business logic powers React + Svelte + Solid surfaces in your\n monorepo.\n- You're already in the TanStack ecosystem (Query, Router, Form,\n Virtual) and want one mental model.\n- You're happy writing **all the markup yourself** - the row recycling,\n the keyboard map, the ARIA roles, the focus management, the\n drag-to-resize. That's the cost of \"engine only\".\n\n## Feature parity at a glance\n\nYes: shipped in that edition. Partial: needs extra work or a companion\npackage. No: not available. The AG Grid columns follow ag-grid.com's\nCommunity vs Enterprise page and its Set Filter, Tree Data and CSV export\npages; the dated list of those sources is on the\n[SvGrid vs AG Grid](https://svgrid.com/compare/ag-grid/) page, and the\nTanStack sources on [SvGrid vs TanStack Table](https://svgrid.com/compare/tanstack-table/).\n\n| | SvGrid Community | SvGrid Enterprise | AG Grid Community | AG Grid Enterprise | TanStack Table |\n| ------------------------------- | ---------------- | ----------------- | ----------------- | ------------------ | -------------- |\n| Headless core (engine only) | Yes | Yes | No | No | Yes |\n| Default render component | Yes (Svelte 5) | Yes | Yes (each framework) | Yes | No |\n| Sort (multi-column) | Yes | Yes | Yes | Yes | Yes (engine) |\n| Filter menu (operator + facet) | Yes | Yes | Partial (text and number filters; the set filter is Enterprise) | Yes | No |\n| Filter row | Yes | Yes | Yes | Yes | No |\n| Pagination | Yes | Yes | Yes | Yes | Yes (engine) |\n| Grouping + aggregation | Yes | Yes | No (Enterprise) | Yes | Yes (engine) |\n| Tree / expand-collapse rows | Yes | Yes | No (Enterprise) | Yes | Yes (engine) |\n| Master/detail | Yes | Yes | No (Enterprise) | Yes | No |\n| Cell range selection + copy/paste | Yes | Yes | No (Enterprise) | Yes | No |\n| Fill handle | Yes | Yes | No (Enterprise) | Yes | No |\n| Inline editing (typed editors) | Yes | Yes | Yes | Yes | No |\n| Column virtualization | Yes | Yes | Yes | Yes | No |\n| Row virtualization | Yes | Yes | Yes | Yes | Partial (pair with TanStack Virtual) |\n| Column pinning (left/right) | Yes | Yes | Yes | Yes | No |\n| Column tool panel | Yes | Yes | No (Enterprise) | Yes | No |\n| Context menu | Yes | Yes | No (Enterprise) | Yes | No |\n| Fit-to-width with shrink | Yes | Yes | Partial | Yes | No |\n| WAI-ARIA grid pattern | Yes | Yes | Yes | Yes | No (your markup) |\n| Server-side data, flat (sort / filter / paging / infinite scroll) | Yes (built in) | Yes (built in) | Yes (infinite row model) | Yes (built in) | Partial (manual flags) |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | No (Enterprise) | Yes (built in) | No (Enterprise) | Yes (built in) | No |\n| Global search over server-side data | Yes (`filterModel.global`) | Yes | No (the quick filter is client-side only) | No | n/a |\n| CSP-clean (no eval, no inline) | Yes | Yes | Yes | Yes | n/a |\n| Meaningful SSR markup | Yes | Yes | No | No | depends on your markup |\n| CSV / TSV / JSON export | Yes | Yes | Yes (CSV) | Yes | No |\n| Excel (.xlsx) / PDF export | No | Yes | No | Yes (Excel) | No |\n| Print | No | Yes | No | No | No |\n| Excel / CSV import | No | Yes | No | No | No |\n| In-grid AI helpers (bring your own model) | Yes | Yes | No | No | No |\n| MCP server for AI assistants | Yes (`@svgrid/mcp`) | Yes | Yes (`ag-mcp`) | Yes | No (agent skills ship in the package) |\n| Pivot table | No | Yes | No | Yes | No (custom) |\n| Integrated charts | Yes (29 types, builder, financial toolkit) | Yes | No | Yes (AG Charts) | No |\n| Support response time | GitHub (best-effort) | 1 business day; 1h sev-1 on Enterprise | GitHub (best-effort) | no number published | GitHub; paid Enterprise Support offered |\n| Theming via CSS variables | Yes (`--sg-*`) | Yes | Yes (theme builder) | Yes | n/a |\n| Source button per demo | Yes (gallery) | Yes | No | No | No |\n\n## Bundle size\n\nThe facts block at the top of the page has the gzipped size of each\npackage, measured by the same method: each package built alone with Vite\nin library mode, minified, gzip level 9, Svelte external because it is a\npeer dependency. SvGrid's own number comes from `pnpm size:json`\n(`packages/grid/scripts/measure-size.mjs`), the competitors' from\n`pnpm competitors:measure`; both write `docs/_data` and the block is\nregenerated from there, so the page cannot quote a size nobody measured.\n\nWhat the SvGrid number contains: the whole render component -\nvirtualization, Excel-style filters, inline editing, grouping, tree,\nmaster/detail, cell selection and accessibility - in one import, plus a\nseparate stylesheet. Charts, date and time editors, menus and export split\ninto `import()` chunks that load on demand rather than shipping in the\ninitial bundle; the headless core on its own is a small fraction of the\nrender component, and `@svgrid/enterprise` features are separate subpath\nimports. The per-entry breakdown, including the headless core and the\nlazy chunks, is in the [bundle size reference](./bundle-size.md).\n\nWhat the AG Grid number contains: `createGrid` with every Community\nmodule registered and the Quartz theme, whose CSS ships inside the script\nunder the theming API, so there is no separate stylesheet to add. The\nTanStack number is the whole Svelte adapter with its engine: no\nvirtualizer, filter UI or editors, because a headless library has none.\n\n## Measured performance\n\nA vendor's own benchmark is worth nothing unless you can rerun it, so the\nharness is in the repository and takes an adapter per grid. Adding another\ngrid is about forty lines in `examples/src/bench/adapters.ts` and nothing\nelse.\n\n```bash\n# headless, prints the table and writes tests/perf/.last-compare.json\nBENCH_REPEATS=7 BENCH_GRIDS=svgrid,aggrid,svar,tanstack pnpm bench:compare\n\n# move that run into docs/_data/competitors.json, then regenerate this page\nnode tools/record-benchmarks.mjs && node tools/sync-guide-facts.mjs\n\n# or drive it by hand\npnpm --filter @svgrid/grid-example-gallery dev # then open /bench.html\n```\n\nEach operation is timed until the grid's DOM reflects it, plus one frame:\n\n- **Mount** - fresh container, create the grid, until rows are painted.\n- **Sort** - change the sort on one column, until the new order is painted.\n Text sorts `name` (tens of thousands of distinct values), numeric sorts\n `amount`.\n- **Filter** - apply a `contains` filter to one column.\n- **Scroll** - 180 frames at 60 px/frame, sampling frame intervals.\n\n### Results\n\nThe table is generated from the ledger by `tools/sync-guide-facts.mjs`;\nthe versions and the date are part of it.\n\n<!-- bench:start -->\nMeasured 12 Sep 2026 with `pnpm bench:compare` (tests/perf/compare.spec.ts, recorded by tools/record-benchmarks.mjs): 100,000 rows x 9 columns; 1000 x 520 px container, 32 px rows, 140 px columns, each grid with its default theme; fastest of 7 samples per operation, each grid in a fresh page; Chromium through Playwright, headless; win32 10.0.26200 x64, Intel(R) Core(TM) Ultra 7 255U; a developer workstation, not a dedicated bench rig. Lower is better.\n\n| Operation | SvGrid | AG Grid Community | SVAR Svelte DataGrid | TanStack Table, minimal DOM |\n| --- | --- | --- | --- | --- |\n| Mount | 75.5 ms | 51.4 ms | 11.4 ms | 196 ms |\n| Sort, text column | 149 ms | 282.8 ms | 187.2 ms | 466 ms |\n| Sort, numeric column | 115.7 ms | 270 ms | 165.1 ms | 374.6 ms |\n| Filter, one column (indicative only, see below) | 99.6 ms | 170.4 ms | 32.6 ms | 111.7 ms |\n| Scroll, p95 frame | 34.6 ms | 35.9 ms | 34.8 ms | 35.3 ms |\n| Frames dropped while scrolling, of 180 | 0 | 0 | 0 | 1 |\n| Rows kept in the DOM (virtualization on) | 27 | 35 | 19 | 27 |\n\nVersions: `@svgrid/grid` 3.0.3, `ag-grid-community` 36.1.0, `wx-svelte-grid` 2.7.0, `@tanstack/svelte-table` 9.2.4.\n<!-- bench:end -->\n\nRead that as: **SvGrid sorts faster than AG Grid Community and SVAR on both\ncolumn types, scrolling is level across all four, and mounting is where the\nlighter grids are ahead** - SVAR paints its first rows fastest, AG Grid is\nahead of SvGrid, and the TanStack renderer pays for building a row object\nper record before it can draw anything. Anyone claiming a single headline\nnumber for a grid comparison is selling something.\n\n**The filter row is not a like-for-like comparison and is shown only because\nhiding a number we win looks worse than explaining it.** The grids' single-\ncolumn filter APIs differ: the harness drives AG Grid's quick filter, which\nsearches every column and is strictly more work than the single-column\n`contains` SvGrid performs, while SVAR and TanStack run a predicate over the\none column. Do not read a ratio into that row.\n\n**The TanStack column is an engine plus the least DOM an app could draw.**\nTanStack Table renders nothing, so its adapter draws the row model through\na fixed-height windowed table with no virtualizer library, no filter UI and\nno editors. Its mount and sort numbers include creating the engine's row\nobjects for every record; the grids around it do the same work inside their\nown models.\n\nSorting is where SvGrid's distance comes from, and it is not subtle: SvGrid\nresolves each sort clause once and precomputes a key array, and for a\ncolumn whose distinct values are far fewer than its rows it collates the\ndistinct values once and sorts by rank. Mounting is the other direction -\nsee the accounting in [benchmarks](./benchmarks.md).\n\nTwo methodology notes, both of which were bugs in this harness before they\nwere notes, and both of which changed the numbers by more than any code\nchange did:\n\n- **Each grid runs in a fresh page.** They used to run one after another in\n the same one, where the first warmed the JIT, fragmented the heap and\n left a hundred thousand rows of garbage for the next. Back-to-back runs\n on an idle machine disagreed with themselves by a factor of two.\n Run-to-run variance is now a few percent.\n- **Operations are timed until the DOM changes, not for a fixed two\n frames.** The old fixed wait put a two-frame floor under every number -\n an operation that recomputed nothing at all measured the floor, and a\n mount whose rows were already in the DOM measured pure waiting - which\n flattered whichever grid was slower.\n- **Each figure is the fastest of the samples, not the median.** Noise\n only ever adds time, so the minimum is the cleanest estimate of what the\n machine can do, and medians on this box drifted by a third between\n consecutive runs - more than most of the differences being measured.\n Applied identically to every grid.\n\nWhat this table deliberately does not include:\n\n- **Features the grids do not measure the same way.** Grouping, pivot,\n editing and export all differ enough in shape that a single timing would\n compare two different amounts of work. The filter row above is the one\n case we publish anyway, labelled, rather than quietly dropping a result\n that happens to favour us.\n- **Any grid we cannot license for this.** The harness is grid-agnostic on\n purpose, but some commercial grids licence their software in ways that\n restrict using it to produce competitive claims. Where that is the case\n we do not ship an adapter, and we would rather have an obviously\n incomplete table than a legally dubious one. Run your own shortlist.\n- **Your workload.** One dataset shape, one machine, one browser, default\n configuration for every grid. If a grid decision rides on this, clone the\n harness and put your own data in it.\n\n## Migrating from AG Grid\n\nThe most common starting point. See\n[Migrating from AG Grid](./migrating-from-ag-grid.md) for a side-by-side\ntranslation of column defs, features, filtering, editing, and the\nimperative API. The example that guide is built around runs here:\n\n<div data-docs-demo=\"139-migration-from-ag-grid\" data-height=\"560\"></div>\n\n## Migrating from TanStack Table\n\nThe map is one-to-one - SvGrid's headless core speaks the vocabulary\nTanStack Table v9 introduced. The big differences:\n\n- Replace `createTable(opts)` with `createSvGrid(opts)`. Same state\n machine, same features object.\n- Replace the row-model factories with the same names from\n `@svgrid/grid`.\n- The render layer changes - TanStack hands you `FlexRender` + the\n row model; SvGrid lets you keep that headless approach OR drop in\n the default `<SvGrid>` component.\n\nThe headless demo below drives a plain `<table>` from `createSvGrid`, the\nway a TanStack app would:\n\n<div data-docs-demo=\"186-headless-table\" data-height=\"520\"></div>\n\nAnd the same rows through the render component, which is the part TanStack\nleaves to you. The example runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Order = {\n id: number\n customer: string\n region: string\n status: string\n amount: number\n }\n\n const orders: Order[] = [\n { id: 1, customer: 'Ada Lovelace', region: 'EMEA', status: 'open', amount: 1240 },\n { id: 2, customer: 'Grace Hopper', region: 'AMER', status: 'shipped', amount: 860 },\n { id: 3, customer: 'Linus Torvalds', region: 'EMEA', status: 'closed', amount: 2210 },\n { id: 4, customer: 'Radia Perlman', region: 'APAC', status: 'open', amount: 430 },\n { id: 5, customer: 'Barbara Liskov', region: 'AMER', status: 'pending', amount: 1780 },\n ]\n\n let rows = $state<Order[]>(orders)\n\n const columns: GridColumns<Order> = [\n { field: 'customer', header: 'Customer', width: 180 },\n { field: 'region', header: 'Region', width: 110 },\n { field: 'status', header: 'Status', width: 110 },\n { field: 'amount', header: 'Amount', width: 120, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable selectable />\n```\n\n## Pricing\n\nSvGrid Community is MIT - free for commercial use, no attribution\nrequired at runtime. SvGrid Enterprise is a per-developer licence: $599\nper developer per year for the enterprise grid or $999 with the\nspreadsheet and Studio, both for unlimited applications; see\n<https://svgrid.com/pricing/> for what each tier adds.\n\nAG Grid Community is MIT. AG Grid Enterprise is priced per developer with\none year of updates; the figure ag-grid.com listed on the date we read it\nis in the facts block at the top of this page, and the\n[SvGrid vs AG Grid](https://svgrid.com/compare/ag-grid/) page carries the\nlink. Compare what each paid tier adds before comparing prices: most of\nwhat AG Grid sells as Enterprise is in SvGrid's free core.\n\nTanStack Table is MIT and sponsor-funded; tanstack.com offers paid\nEnterprise Support as private consulting.\n\n## Frequently asked questions\n\n### What is the best data grid for Svelte 5?\n\nFor a Svelte-5-native grid with a batteries-included render component, SvGrid is\nbuilt around runes and snippets. TanStack Table is a strong headless-only\nchoice if you want to build the DOM layer yourself across frameworks, and its\nv9 Svelte adapter targets Svelte 5. AG Grid is the most feature-complete but\nlives in React, Angular and Vue first and reaches Svelte through\ncommunity-built integrations.\n\n### Is SvGrid a good AG Grid alternative?\n\nYes, for Svelte projects. SvGrid is a fraction of AG Grid Community's\nmeasured size on a Svelte page (the facts block has both numbers and the\nmethod), is MIT-licensed for commercial use, and offers `@svgrid/enterprise`\nfor export, print, import and pivot at a per-developer price. On the\nbenchmark above it sorts a hundred-thousand-row column faster on both\ncolumn types and scrolls level; AG Grid mounts quicker. It does not match\nevery AG Grid Enterprise feature - see the\n[missing-features list](./missing-features.md) for the gaps.\n\n### SvGrid vs TanStack Table - which should I pick?\n\nPick SvGrid if you want virtualization, Excel-style filters, selection, and\ninline editing working out of the box on Svelte 5. Pick TanStack Table if you\nwant a framework-agnostic headless engine and are happy to build the rendering,\nvirtualization, and editing UI yourself. Both are MIT-licensed.\n\n### Does the TanStack Svelte adapter support Svelte 5?\n\nYes. The `@tanstack/svelte-table` v9 line declares a Svelte 5 peer range\nand passes data through getters rather than stores; the facts block above\nshows the version read from npm. The earlier `createSvelteTable` constructor\nis gone in v9.\n\n### Does AG Grid have an MCP server like SvGrid?\n\nYes. `ag-mcp` (MIT) gives an assistant AG Grid's docs, examples and\nversion-specific upgrade prompts. `@svgrid/mcp` does the same for SvGrid\nand adds a code checker that validates props and imports against the real\nAPI surface, a scaffold tool and a preview. Neither is an in-grid feature;\nSvGrid's natural-language filter, smart fill and summarise helpers are, and\nthey ship free in `@svgrid/grid` with a model provider you register.\n\n### How big is the SvGrid bundle?\n\nThe facts block at the top of this page has the measured gzipped size of the\nfull `<SvGrid>` render component and its stylesheet, read from\n`docs/_data/svgrid-size.json`, which `pnpm size:json` writes. The\n[bundle size reference](./bundle-size.md) breaks it down by entry:\nthe headless core on its own, the core subpath, the charts, and the lazy\nchunks that load on demand.\n\n## See also\n\n- [Why headless?](../why-headless.md) - the design decision behind\n SvGrid's two-layer architecture.\n- [Migrating from AG Grid](./migrating-from-ag-grid.md) - the\n practical recipe.\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - the\n one-to-one API map.\n- [Benchmarks](./benchmarks.md) - how the numbers are produced and what\n they leave out.\n- [Enterprise feature pack](../enterprise/README.md) - what SvGrid charges for.\n- [Missing features](./missing-features.md) - the honest gap list\n versus AG Grid Enterprise.\n- [All comparisons](https://svgrid.com/compare/) - one page per grid, with\n dated sources for every claim.\n"
|
|
4395
4395
|
},
|
|
4396
4396
|
{
|
|
4397
4397
|
"slug": "help/conditional-form-schema",
|
|
@@ -4475,14 +4475,14 @@ export const docs = [
|
|
|
4475
4475
|
"path": "docs/help/errors.md",
|
|
4476
4476
|
"title": "Error reference",
|
|
4477
4477
|
"section": "Help",
|
|
4478
|
-
"markdown": "# Error reference\n\nEvery `Error` thrown by `@svgrid/grid` or `@svgrid/enterprise` with the\nexact message text, the trigger condition, and the fix. If a runtime\nmessage you see isn't on this list, it's coming from your own code or\na peer dependency.\n\n## How to read this page\n\nEach entry has four pieces:\n\n1. **Message** - the exact text after `Error:`. Searchable.\n2. **Class / type** - the thrown object's `.name`.\n3. **When** - what action triggered it.\n4. **Fix** - the smallest change that resolves it.\n\nError classes are part of the [API stability](./api-stability.md)\ncontract: the `.name` and message structure are Stable; we may reword\nthe trailing detail at the patch level if the diagnostic improves.\n\n## @svgrid/grid\n\n### `Error: SvGrid: cannot mount inside a non-element parent`\n\n- **Class:** `Error`\n- **When:** You passed something other than an `Element` to\n `mount(SvGrid, { target })`. Common cause: passing a Svelte\n component reference instead of a DOM node.\n- **Fix:** Use `bind:this={el}` on a real `<div>` and pass `el` as the\n target.\n\n### `Error: Column \"<id>\" has no field, fieldFn, or cell renderer`\n\n- **Class:** `Error`\n- **When:** A `ColumnDef` was registered with neither a `field`, an\n `fieldFn`, nor a `cell` template. The grid has no way to produce\n a value for that column.\n- **Fix:** Add one of the three. For computed display-only columns,\n `fieldFn: (row) => /* ... */` is usually right.\n\n### `Error: Duplicate column id \"<id>\"`\n\n- **Class:** `Error`\n- **When:** Two `ColumnDef` entries resolve to the same id - either\n because they share a `field` and neither has an explicit `id`, or\n because their explicit `id` collides.\n- **Fix:** Give each column an explicit unique `id`.\n\n### `Error: Sort comparator failed: <reason>`\n\n- **Class:** `Error`\n- **When:** A custom `sortingFn` returned `NaN` or threw.\n- **Fix:** Make the comparator total (always returns a number) and\n null-safe.\n\n### `RuneError: state_referenced_locally`\n\n- **Class:** Svelte runtime\n- **When:** Initialising one `$state` from another `$state` in the\n same script - not specifically a SvGrid error, but the most common\n one users hit when seeding the grid's data.\n- **Fix:** Add `// svelte-ignore state_referenced_locally` above the\n line, or restructure so the initial value isn't read from another\n `$state`.\n\n### `each_key_duplicate`\n\n- **Class:** Svelte runtime\n- **When:** Two `ColumnDef` entries share the same key in the grid's\n internal keyed-`{#each}` over columns. Most often when you have two\n columns both pointing at the same `field` (e.g. one computed\n \"Total\" column that uses `field: 'qty'` to satisfy the type but\n duplicates an existing data column).\n- **Fix:** Give the computed column an explicit `id` and drop its\n `field`.\n\n## @svgrid/enterprise - License\n\n### `Error: @svgrid/enterprise: setLicenseKey() requires a non-empty string`\n\n- **Class:** `Error`\n- **When:** `setLicenseKey('')` or `setLicenseKey(null)`.\n- **Fix:** Pass a valid `SVENTERPRISE-...` string.\n\n### `Error: @svgrid/enterprise: invalid license key format (expected \"SVENTERPRISE-...\" prefix).`\n\n- **Class:** `Error`\n- **When:** A key that doesn't start with `SVENTERPRISE-` was set; the first\n Enterprise call throws.\n- **Fix:** Use the key issued by jQWidgets. The free Community grid is\n the right choice if you don't have a key.\n\n### `Error: @svgrid/enterprise: this license key has been revoked. Contact sales@jqwidgets.com for a replacement.`\n\n- **Class:** `Error`\n- **When:** A key matching an entry in the package's revoked-keys list.\n- **Fix:** Contact `sales@jqwidgets.com` for a replacement.\n\n## @svgrid/enterprise - Export\n\n### `Error: @svgrid/enterprise: export requires a browser environment`\n\n- **Class:** `Error`\n- **When:** `exportGrid` / `api.exportData` was called during SSR.\n- **Fix:** Guard with `if (typeof window === 'undefined') return` or\n defer to `onMount`.\n\n### `Error: @svgrid/enterprise: failed to load Smart.Utilities.DataExporter`\n\n- **Class:** `Error`\n- **When:** The Smart exporter shim couldn't initialise. Usually a\n bundler config issue blocking dynamic `import()` of a vendored\n asset.\n- **Fix:** Confirm the package is installed cleanly and your bundler\n permits dynamic imports.\n\n### `Error: @svgrid/enterprise: xlsx export requires the \"jszip\" peer dependency. Install it with: pnpm add jszip`\n\n- **Class:** `Error`\n- **When:** First xlsx export when `jszip` isn't installed.\n- **Fix:** `pnpm add jszip` (or `npm` / `yarn`).\n\n### `Error: @svgrid/enterprise: pdf export requires the \"pdfmake\" peer dependency. Install it with: pnpm add pdfmake`\n\n- **Class:** `Error`\n- **When:** First pdf export when `pdfmake` isn't installed.\n- **Fix:** `pnpm add pdfmake`.\n\n## @svgrid/enterprise - Import\n\n### `Error: @svgrid/enterprise: importData requires a browser environment`\n\n- **Class:** `Error`\n- **When:** `importData` was called during SSR.\n- **Fix:** Guard with `if (typeof window === 'undefined') return`.\n\n### `Error: @svgrid/enterprise: xlsx import requires the \"jszip\" peer dependency. Install it with: pnpm add jszip`\n\n- **Class:** `Error`\n- **When:** First xlsx import when `jszip` isn't installed.\n- **Fix:** `pnpm add jszip`.\n\n### `Error: @svgrid/enterprise: xlsx import expects a File or Blob, not a string. Use format: \"csv\" or \"tsv\" for inline text.`\n\n- **Class:** `Error`\n- **When:** Passing a string with `format: 'xlsx'`.\n- **Fix:** Either give the helper a `File` / `Blob` of the xlsx data\n or switch the format to `csv` / `tsv` for inline text.\n\n### `Error: @svgrid/enterprise: could not locate sheet1.xml in the .xlsx archive`\n\n- **Class:** `Error`\n- **When:** The uploaded `.xlsx` is malformed or non-standard (e.g. a\n workbook saved by an exotic tool that places the first sheet\n somewhere other than `xl/worksheets/sheet1.xml`).\n- **Fix:** Open the file in Excel or LibreOffice and re-save. If the\n file is correct and the grid still fails, please file an issue with\n a redacted sample.\n\n### `Error: @svgrid/enterprise: JSON import expects a top-level array`\n\n- **Class:** `Error`\n- **When:** The JSON parses to an object (or any non-array) instead of\n an array of records.\n- **Fix:** Wrap the data in `[]` or write a wrapper that extracts the\n array from the response.\n\n## @svgrid/enterprise - AI\n\n### `NoProviderError: @svgrid/grid ai: no AI provider registered. Call setAIProvider(fn) with an adapter that talks to OpenAI / Anthropic / your proxy.`\n\n- **Class:** `NoProviderError` (extends `Error`)\n- **When:** Any `api.ai.*` call before `setAIProvider(fn)` ran.\n- **Fix:** Wire your adapter at app boot. For demos, use\n `setAIProvider(mockAIProvider)`.\n\n### `BadJsonError: @svgrid/grid ai: provider returned non-JSON for a json-format request. First 200 chars: <prefix>`\n\n- **Class:** `BadJsonError` (extends `Error`)\n- **When:** A helper asked the provider for JSON and got prose back.\n The first 200 characters of the response are included so you can\n see what the model actually returned.\n- **Fix:** Make sure your provider passes `responseFormat: 'json'` to\n the model, or instruct the model in your system prompt to return\n JSON only. The package strips a single markdown code fence\n automatically before parsing; multiple fences or surrounding prose\n trip this error.\n\n### `Error: @svgrid/grid ai: aiSmartFill requires at least one example.`\n\n- **Class:** `Error`\n- **When:** `aiSmartFill({ examples: [] })`.\n- **Fix:** Pass at least one worked example. Two or more locks the\n pattern more reliably.\n\n## How to report a missing entry\n\nIf you hit a thrown message that isn't on this page:\n\n1. Copy the exact message text and class name.\n2. File an issue with `[error reference]` in the title.\n3. We treat this list as **canonical** - every new error added in a\n release lands here in the same PR.\n\n## Try it\n\n`error` replaces the grid body with a message; `emptyMessage` covers the\nno-rows case, which is a different state and deserves different words.\n\n```svelte {runnable}\n<SvGrid data={[]} {columns} emptyMessage=\"No people match this filter.\" />\n\n<SvGrid data={[]} {columns} error=\"Could not reach the server. Retry in a moment.\" />\n```\n\n## See also\n\n- [API stability](./api-stability.md) - the contract around these\n classes and messages.\n- [Testing and quality](./testing-and-quality.md) - the test suite\n that produces every error here as part of its expected-throw\n assertions.\n\n\nThe examples on this page run against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n const data = people\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200 },\n { field: 'department', header: 'Department', width: 150 },\n { field: 'city', header: 'City', width: 140 },\n { field: 'age', header: 'Age', width: 90 },\n { field: 'salary', header: 'Salary', width: 130, format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n"
|
|
4478
|
+
"markdown": "# Error reference\n\nEvery `Error` thrown by `@svgrid/grid` or `@svgrid/enterprise` with the\nexact message text, the trigger condition, and the fix. If a runtime\nmessage you see isn't on this list, it's coming from your own code or\na peer dependency.\n\n## How to read this page\n\nEach entry has four pieces:\n\n1. **Message** - the exact text after `Error:`. Searchable.\n2. **Class / type** - the thrown object's `.name`.\n3. **When** - what action triggered it.\n4. **Fix** - the smallest change that resolves it.\n\nError classes are part of the [API stability](./api-stability.md)\ncontract: the `.name` and message structure are Stable; we may reword\nthe trailing detail at the patch level if the diagnostic improves.\n\n## @svgrid/grid\n\n### `Error: SvGrid: cannot mount inside a non-element parent`\n\n- **Class:** `Error`\n- **When:** You passed something other than an `Element` to\n `mount(SvGrid, { target })`. Common cause: passing a Svelte\n component reference instead of a DOM node.\n- **Fix:** Use `bind:this={el}` on a real `<div>` and pass `el` as the\n target.\n\n### `Error: Column \"<id>\" has no field, fieldFn, or cell renderer`\n\n- **Class:** `Error`\n- **When:** A `ColumnDef` was registered with neither a `field`, an\n `fieldFn`, nor a `cell` template. The grid has no way to produce\n a value for that column.\n- **Fix:** Add one of the three. For computed display-only columns,\n `fieldFn: (row) => /* ... */` is usually right.\n\n### `Error: Duplicate column id \"<id>\"`\n\n- **Class:** `Error`\n- **When:** Two `ColumnDef` entries resolve to the same id - either\n because they share a `field` and neither has an explicit `id`, or\n because their explicit `id` collides.\n- **Fix:** Give each column an explicit unique `id`.\n\n### `Error: Sort comparator failed: <reason>`\n\n- **Class:** `Error`\n- **When:** A custom `sortingFn` returned `NaN` or threw.\n- **Fix:** Make the comparator total (always returns a number) and\n null-safe.\n\n### `RuneError: state_referenced_locally`\n\n- **Class:** Svelte runtime\n- **When:** Initialising one `$state` from another `$state` in the\n same script - not specifically a SvGrid error, but the most common\n one users hit when seeding the grid's data.\n- **Fix:** Add `// svelte-ignore state_referenced_locally` above the\n line, or restructure so the initial value isn't read from another\n `$state`.\n\n### `each_key_duplicate`\n\n- **Class:** Svelte runtime\n- **When:** Two `ColumnDef` entries share the same key in the grid's\n internal keyed-`{#each}` over columns. Most often when you have two\n columns both pointing at the same `field` (e.g. one computed\n \"Total\" column that uses `field: 'qty'` to satisfy the type but\n duplicates an existing data column).\n- **Fix:** Give the computed column an explicit `id` and drop its\n `field`.\n\n## @svgrid/enterprise - License\n\n### `Error: @svgrid/enterprise: setLicenseKey() requires a non-empty string`\n\n- **Class:** `Error`\n- **When:** `setLicenseKey('')` or `setLicenseKey(null)`.\n- **Fix:** Pass the license key from your order email.\n\n### Console warning: `@svgrid/enterprise: the license key passed to setLicenseKey() is not valid`\n\n- **Class:** `console.warn`, once per page. Not an error: nothing throws.\n- **When:** `setLicenseKey()` was given a string that is not the license key,\n for example a typo or an `SVENTERPRISE-...` key from before October 2026.\n The Enterprise features keep running, with the watermark and upgrade card.\n- **Fix:** Copy the key from your order email. The free Community grid is the\n right choice if you don't have a key.\n\n### Revoked keys (before October 2026)\n\nKeys are no longer revoked one by one, and a revoked key no longer throws.\nSince October 2026 there is one license key; any other string, including a\npreviously revoked one, gets the watermark and the console warning above.\n\n## @svgrid/enterprise - Export\n\n### `Error: @svgrid/enterprise: export requires a browser environment`\n\n- **Class:** `Error`\n- **When:** `exportGrid` / `api.exportData` was called during SSR.\n- **Fix:** Guard with `if (typeof window === 'undefined') return` or\n defer to `onMount`.\n\n### `Error: @svgrid/enterprise: failed to load Smart.Utilities.DataExporter`\n\n- **Class:** `Error`\n- **When:** The Smart exporter shim couldn't initialise. Usually a\n bundler config issue blocking dynamic `import()` of a vendored\n asset.\n- **Fix:** Confirm the package is installed cleanly and your bundler\n permits dynamic imports.\n\n### `Error: @svgrid/enterprise: xlsx export requires the \"jszip\" peer dependency. Install it with: pnpm add jszip`\n\n- **Class:** `Error`\n- **When:** First xlsx export when `jszip` isn't installed.\n- **Fix:** `pnpm add jszip` (or `npm` / `yarn`).\n\n### `Error: @svgrid/enterprise: pdf export requires the \"pdfmake\" peer dependency. Install it with: pnpm add pdfmake`\n\n- **Class:** `Error`\n- **When:** First pdf export when `pdfmake` isn't installed.\n- **Fix:** `pnpm add pdfmake`.\n\n## @svgrid/enterprise - Import\n\n### `Error: @svgrid/enterprise: importData requires a browser environment`\n\n- **Class:** `Error`\n- **When:** `importData` was called during SSR.\n- **Fix:** Guard with `if (typeof window === 'undefined') return`.\n\n### `Error: @svgrid/enterprise: xlsx import requires the \"jszip\" peer dependency. Install it with: pnpm add jszip`\n\n- **Class:** `Error`\n- **When:** First xlsx import when `jszip` isn't installed.\n- **Fix:** `pnpm add jszip`.\n\n### `Error: @svgrid/enterprise: xlsx import expects a File or Blob, not a string. Use format: \"csv\" or \"tsv\" for inline text.`\n\n- **Class:** `Error`\n- **When:** Passing a string with `format: 'xlsx'`.\n- **Fix:** Either give the helper a `File` / `Blob` of the xlsx data\n or switch the format to `csv` / `tsv` for inline text.\n\n### `Error: @svgrid/enterprise: could not locate sheet1.xml in the .xlsx archive`\n\n- **Class:** `Error`\n- **When:** The uploaded `.xlsx` is malformed or non-standard (e.g. a\n workbook saved by an exotic tool that places the first sheet\n somewhere other than `xl/worksheets/sheet1.xml`).\n- **Fix:** Open the file in Excel or LibreOffice and re-save. If the\n file is correct and the grid still fails, please file an issue with\n a redacted sample.\n\n### `Error: @svgrid/enterprise: JSON import expects a top-level array`\n\n- **Class:** `Error`\n- **When:** The JSON parses to an object (or any non-array) instead of\n an array of records.\n- **Fix:** Wrap the data in `[]` or write a wrapper that extracts the\n array from the response.\n\n## @svgrid/enterprise - AI\n\n### `NoProviderError: @svgrid/grid ai: no AI provider registered. Call setAIProvider(fn) with an adapter that talks to OpenAI / Anthropic / your proxy.`\n\n- **Class:** `NoProviderError` (extends `Error`)\n- **When:** Any `api.ai.*` call before `setAIProvider(fn)` ran.\n- **Fix:** Wire your adapter at app boot. For demos, use\n `setAIProvider(mockAIProvider)`.\n\n### `BadJsonError: @svgrid/grid ai: provider returned non-JSON for a json-format request. First 200 chars: <prefix>`\n\n- **Class:** `BadJsonError` (extends `Error`)\n- **When:** A helper asked the provider for JSON and got prose back.\n The first 200 characters of the response are included so you can\n see what the model actually returned.\n- **Fix:** Make sure your provider passes `responseFormat: 'json'` to\n the model, or instruct the model in your system prompt to return\n JSON only. The package strips a single markdown code fence\n automatically before parsing; multiple fences or surrounding prose\n trip this error.\n\n### `Error: @svgrid/grid ai: aiSmartFill requires at least one example.`\n\n- **Class:** `Error`\n- **When:** `aiSmartFill({ examples: [] })`.\n- **Fix:** Pass at least one worked example. Two or more locks the\n pattern more reliably.\n\n## How to report a missing entry\n\nIf you hit a thrown message that isn't on this page:\n\n1. Copy the exact message text and class name.\n2. File an issue with `[error reference]` in the title.\n3. We treat this list as **canonical** - every new error added in a\n release lands here in the same PR.\n\n## Try it\n\n`error` replaces the grid body with a message; `emptyMessage` covers the\nno-rows case, which is a different state and deserves different words.\n\n```svelte {runnable}\n<SvGrid data={[]} {columns} emptyMessage=\"No people match this filter.\" />\n\n<SvGrid data={[]} {columns} error=\"Could not reach the server. Retry in a moment.\" />\n```\n\n## See also\n\n- [API stability](./api-stability.md) - the contract around these\n classes and messages.\n- [Testing and quality](./testing-and-quality.md) - the test suite\n that produces every error here as part of its expected-throw\n assertions.\n\n\nThe examples on this page run against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n const data = people\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200 },\n { field: 'department', header: 'Department', width: 150 },\n { field: 'city', header: 'City', width: 140 },\n { field: 'age', header: 'Age', width: 90 },\n { field: 'salary', header: 'Salary', width: 130, format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n"
|
|
4479
4479
|
},
|
|
4480
4480
|
{
|
|
4481
4481
|
"slug": "help/export",
|
|
4482
4482
|
"path": "docs/help/export.md",
|
|
4483
4483
|
"title": "Data export and printing",
|
|
4484
4484
|
"section": "Import & export",
|
|
4485
|
-
"markdown": "# Data export and printing\n\n**CSV / TSV / JSON export and copy-to-clipboard are free** in the community\n**[@svgrid/grid](https://www.npmjs.com/package/@svgrid/grid)** - the commodity\n\"data out\" every grid needs. The richer formats - **Excel (xlsx)**, **legacy\nExcel (xls)**, **PDF**, styled **HTML**, **XML**, **Markdown**, multi-sheet\nworkbooks, password protection, conditional-format export, and the drop-in\nexport menu - ship in the paid\n**[@svgrid/enterprise](https://www.npmjs.com/package/@svgrid/enterprise)** add-on,\nwhich reuses the exact same serializers so the two tiers feel like one product.\n\nFor the report built step by step, with a live grid under most steps, see [Export: a report to Excel and PDF](./export/report.md); this page is the reference.\n\n\n\n| Capability | Package |\n| ---------- | ------- |\n| CSV / TSV / JSON export, copy-to-clipboard (TSV / CSV / Markdown) | **Free** (`@svgrid/grid`) |\n| Excel `.xlsx` (typed cells, styles, conditional formatting, tables, multi-sheet) | Enterprise |\n| PDF, styled HTML, XML, legacy `.xls`, password-protected export | Enterprise |\n| `exportValue` hook, conditional-format export, `SvExportMenu`, `print()` | Enterprise |\n\n## Free: CSV / TSV / JSON + clipboard\n\nThe community grid's `SvGridApi` carries four zero-dependency methods - no\nlicense, no peer deps:\n\nThe examples on this page run against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns, tableFeatures, rowSortingFeature, columnFilteringFeature } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n email: string\n department: string\n age: number\n salary: number\n city: string\n startDate: string\n active: boolean\n }\n\n type Order = {\n id: string\n customer: string\n product: string\n quantity: number\n total: number\n status: 'pending' | 'shipped' | 'delivered'\n orderedAt: string\n }\n\n type Row = Person\n\n const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', email: 'ada@example.com', department: 'Engineering', age: 36, salary: 142000, city: 'London', startDate: '2021-03-01', active: true },\n { id: 2, name: 'Grace Hopper', email: 'grace@example.com', department: 'Engineering', age: 45, salary: 168000, city: 'New York', startDate: '2019-07-15', active: true },\n { id: 3, name: 'Linus Torvalds', email: 'linus@example.com', department: 'Platform', age: 54, salary: 155000, city: 'Portland', startDate: '2020-01-20', active: false },\n { id: 4, name: 'Radia Perlman', email: 'radia@example.com', department: 'Networking', age: 49, salary: 161000, city: 'Seattle', startDate: '2022-09-05', active: true },\n { id: 5, name: 'Barbara Liskov', email: 'barbara@example.com', department: 'Platform', age: 52, salary: 172000, city: 'Boston', startDate: '2018-11-11', active: true },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200 },\n { field: 'department', header: 'Department', width: 150 },\n { field: 'city', header: 'City', width: 140 },\n { field: 'age', header: 'Age', width: 90 },\n { field: 'salary', header: 'Salary', width: 130, format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```ts\nawait api.exportCsv({ filename: 'orders' }) // orders.csv (BOM + Excel-friendly)\nawait api.exportTsv() // grid.tsv\nawait api.exportJson({ rows: 'selected' }) // grid.json, checked rows only\nawait api.copyToClipboard({ format: 'tsv' }) // paste straight into Excel / Sheets\n```\n\nEvery method:\n\n- defaults to the **current view** (`rows: 'selected' | 'all'` to change),\n- formats values **as shown on screen** (currency, dates) - pass\n `rawValues: true` for the underlying values,\n- accepts a `columns: string[]` field subset (in that order),\n- runs on a chunked, cancelable loop (`signal`, `onProgress`) so a 100k-row\n export never freezes the tab,\n- returns the serialized text; pass `download: false` to skip the download\n and just get the string.\n\n```svelte {runnable}\n<script lang=\"ts\">\n import { SvGrid, tableFeatures, type SvGridApi } from '@svgrid/grid'\n let api = $state<SvGridApi<any, Row> | null>(null)\n</script>\n\n<button onclick={() => api?.exportCsv({ filename: 'orders' })}>Export CSV</button>\n<button onclick={() => api?.copyToClipboard()}>Copy for Excel</button>\n<SvGrid data={rows} columns={columns} features={features} onApiReady={(a) => (api = a)} />\n```\n\nThe rest of this page covers the **Enterprise** formats.\n\nTry the export bar below - downloads run in your browser; the bundled\nlicense key removes the unlicensed watermark:\n\n<div data-docs-demo=\"21-export-and-print\" data-height=\"500\"></div>\n\n\n## What it is\n\n`@svgrid/enterprise` augments the `SvGridApi` you already get from\n`<SvGrid onApiReady>` with two methods:\n\n- `api.exportData({ format, filename?, columns?, rows?, pageOrientation? })`\n- `api.print({ title?, columns?, rows?, orientation? })`\n\nBoth methods default to **the currently displayed rows** - sort, filter,\nor paginate the grid, and the export reflects that view automatically.\n\n## When to use it\n\n- Reporting flows where users want to take the grid offline (spreadsheets,\n emailed PDFs).\n- Compliance / audit trails that require a printable artifact.\n- Quick CSV/TSV pulls for downstream pipelines.\n\nIf you only need machine-readable data, prefer CSV / TSV - they have no\npeer dependencies and produce the smallest files. Use xlsx / PDF only\nwhen the recipient expects formatted documents.\n\n## Minimal example\n\n```svelte {runnable}\n<script lang=\"ts\">\n import { SvGrid, tableFeatures, rowSortingFeature, type SvGridApi, type ColumnDef } from '@svgrid/grid'\n import { installEnterprise, type EnterpriseGridApi } from '@svgrid/enterprise'\n\n // Without a key, the feature still works but the grid shows an\n // \"unlicensed\" watermark and the console emits a one-time nudge directing\n // users to the pricing page. After you buy, call setLicenseKey(yourKey)\n // once at startup.\n\n const features = tableFeatures({ rowSortingFeature })\n\n type Order = { company: string; product: string; price: number }\n const rows: Order[] = [\n { company: 'ACME', product: 'Widget', price: 19.95 },\n { company: 'Globex', product: 'Gadget', price: 49.00 },\n ]\n const columns: ColumnDef<typeof features, Order>[] = [\n { field: 'company', header: 'Company' },\n { field: 'product', header: 'Product' },\n { field: 'price', header: 'Price', format: { type: 'currency', currency: 'USD' } },\n ]\n\n let api = $state<EnterpriseGridApi<typeof features, Order> | null>(null)\n\n function onReady(next: SvGridApi<typeof features, Order>) {\n api = installEnterprise(next)\n }\n</script>\n\n<button onclick={() => api?.exportData({ format: 'xlsx', filename: 'orders' })}>\n Export Excel\n</button>\n<button onclick={() => api?.exportData({ format: 'pdf', filename: 'orders', pageOrientation: 'landscape' })}>\n Export PDF\n</button>\n<button onclick={() => api?.print({ title: 'Orders' })}>\n Print\n</button>\n\n<SvGrid data={rows} columns={columns} features={features} onApiReady={onReady} />\n```\n\n## Install\n\n```bash\npnpm add @svgrid/enterprise\n# Optional - install only the peers you actually use:\npnpm add jszip # required for xlsx\npnpm add pdfmake # required for pdf\n```\n\nCSV, TSV, HTML, and Print have **no extra dependencies**. The peer\ndependencies are lazy-loaded only when you call the format that needs\nthem.\n\n## Licensing\n\n`@svgrid/enterprise` has a tiered license gate:\n\n| Key state | Behavior |\n| ------------------------------------------ | -------- |\n| No key set (`setLicenseKey()` not called) | Feature works. Grid shows an unlicensed watermark linking to svgrid.com/pricing; console.log emits a one-time nudge. |\n| Key doesn't start with `SVENTERPRISE-` | Throws - programmer error. |\n| Key is in the revoked list | Throws - contact support for a replacement. |\n| Your license key | Works silently. |\n\nBuy a production key at <https://svgrid.com/pricing/> ($599 / developer /\nyear). To evaluate, you need no key at all: everything runs with a watermark.\n\n## Reference\n\n### `setLicenseKey(key: string): void`\n\nStores the key in module state. Call once at app startup (e.g. in\n`main.ts`). Subsequent calls overwrite.\n\n### `clearLicenseKey(): void` · `hasValidLicense(): boolean` · `dismissUnlicensedNudge(): void`\n\nProgrammatic helpers. `hasValidLicense()` is useful when you want UI to\nbranch on license status. `dismissUnlicensedNudge()` removes the\nwatermark and stops the MutationObserver - call it after setting a\nvalid key if you loaded the module without one during testing.\n\n### `installEnterprise(api): EnterpriseGridApi`\n\nMutates the given `SvGridApi` to add `exportData` and `print`. Returns\nthe same object with the augmented type, so existing references keep\nworking.\n\n### `api.exportData(opts)` - `Promise<void>`\n\n| Option | Type | Default | Notes |\n| ----------------- | ----------------------------------------------------- | -------------------- | ----- |\n| `format` | `'xlsx' \\| 'xls' \\| 'pdf' \\| 'csv' \\| 'tsv' \\| 'html' \\| 'json' \\| 'xml' \\| 'md'` | required | `xlsx` needs `jszip`, `pdf` needs `pdfmake`. `xls` / CSV / TSV / HTML / JSON / XML / Markdown are dependency-free. |\n| `pdf` | `PdfExportOptions` | - | PDF layout: page size, margins, title / subtitle / logo, theme colors, column widths, repeated header, page numbers. See \"PDF options\". |\n| `conditionalFormats` | `ConditionalFormat[]` | - | Same array as `<SvGrid conditionalFormats>`; carried into pdf / xlsx / html. See \"Conditional formatting in exports\". |\n| `freezeHeader` | `boolean` | `true` | Freeze the header row (xlsx / xls). |\n| `freezeColumns` | `number` | pinned cols | Freeze this many leading columns (xlsx / xls). Defaults to the grid's left-pinned columns. |\n| `autoFitColumns` | `boolean` | `true` | Size columns to content (xlsx / xls); a column's explicit `width` wins. |\n| `precisionSafe` | `boolean` | `false` | Export long integer IDs (> 15 digits) as text so Excel's float precision doesn't round them (xlsx / xls). |\n| `excelTable` | `boolean \\| { totalsRow?; style? }` | - | Wrap single-sheet xlsx in a native Excel Table (filter dropdowns, banded rows; `{ totalsRow: true }` adds SUM formulas). |\n| `download` | `boolean` | `true` | When false, return the {@link ExportResult} without downloading. |\n| `filename` | `string` | `\"grid\"` | Extension is appended if missing. |\n| `columns` | `{ field; header?; format?; align?; exportValue? }[]` | grid's own columns | Drives column selection + header labels. Auto-derived from the grid (with each column's `format`) when omitted. See `exportValue` below. |\n| `rows` | `ReadonlyArray<TData> \\| 'displayed' \\| 'selected' \\| 'all'` | `'displayed'` | `'displayed'` = current filtered/sorted/paged view, `'selected'` = checked rows, `'all'` = full dataset, or pass an explicit array. |\n| `rawValues` | `boolean` | `false` | By default the exporter writes the **formatted display value** (what you see). Set `true` to write raw underlying values (numbers stay numeric in xlsx). |\n| `autoGroup` | `boolean` | `true` | Carry the grid's active row grouping into xlsx outline rows. Pass your own `groupBy` to override, or `false` to ignore. |\n| `csv` | `{ delimiter?; eol?; bom? }` | `{ ',', '\\r\\n', BOM }` | CSV / TSV tuning. UTF-8 BOM is on by default so Excel opens it without mojibake. |\n| `onProgress` | `(p) => void` | - | Progress for large exports: `{ phase, ratio, row?, total? }`, `phase` = `'project' \\| 'serialize' \\| 'write'`. |\n| `signal` | `AbortSignal` | - | Cancel an in-flight export (checked between chunks). Rejects with `AbortError`. |\n| `pageOrientation` | `'portrait' \\| 'landscape'` | `\"portrait\"` | PDF only. |\n| `merges` | `{ row; col; rowSpan?; colSpan? }[]` | `[]` | Merged cells (xlsx / pdf). Zero-based **body** row/col (header excluded). Single-sheet only; mutually exclusive with `groupBy` / `hierarchical`. |\n\n### Faithful values (what you see is what you export)\n\nBy default the export renders each cell the way the grid does on screen: a\ncolumn with `format: { type: 'currency', currency: 'USD' }` exports `$19.95`,\na date column exports its formatted date, a percent column exports `42%`. This\nholds for **every** format (csv / tsv / html / pdf / xlsx). Pass\n`rawValues: true` to write the underlying values instead (e.g. feeding a data\npipeline that wants the numeric `19.95`).\n\nFor columns whose on-screen value comes from a **custom cell renderer**, a\n`fieldFn`, or a lookup, give the column an `exportValue` hook - it takes\nprecedence over `format` and the raw field:\n\n```ts\nawait api.exportData({\n format: 'xlsx',\n columns: [\n { field: 'company', header: 'Company' },\n // a column rendered with a custom snippet on screen:\n { field: 'status', header: 'Status', exportValue: (row) => STATUS_LABELS[row.status] },\n ],\n})\n```\n\n### Export only what's selected\n\n```ts\n// current view (default)\nawait api.exportData({ format: 'xlsx' })\n// only the checked rows\nawait api.exportData({ format: 'xlsx', rows: 'selected' })\n// the entire underlying dataset, ignoring filters/paging\nawait api.exportData({ format: 'csv', rows: 'all' })\n```\n\n### Large exports: progress + cancel\n\nCSV / TSV / HTML are serialized natively (no peer dependency) and stream in\nchunks, yielding to the event loop so a big export doesn't freeze the tab:\n\n```ts\nconst controller = new AbortController()\nawait api.exportData({\n format: 'csv',\n rows: 'all',\n signal: controller.signal,\n onProgress: ({ ratio }) => updateProgressBar(ratio),\n})\n// controller.abort() rejects the export with an AbortError\n```\n\n### Excel-native numbers (xlsx)\n\nA single-sheet `xlsx` export writes numeric, currency, percent, and date\ncolumns as **real typed cells** with an Excel number format - so Excel can sum\nand sort them, and they still display formatted (currency symbol, thousands,\n`%`, date pattern) - via SvGrid's own OOXML writer. Set `rawValues: true` for\nunformatted raw values. The grouped-outline, multi-sheet, image, and merged-cell\npaths use the bundled writer (formatted-string cells). The legacy `xls` format\nis always typed.\n\n### Excel fidelity: freeze, auto-fit, hyperlinks\n\n`xlsx` and `xls` exports polish the spreadsheet automatically:\n\n- **Freeze header** - the header row stays visible when scrolling. On by\n default; `freezeHeader: false` to disable, `freezeColumns: n` to also freeze\n leading columns.\n- **Auto-fit column widths** - columns are sized to their content. On by\n default (`autoFitColumns: false` to disable); a column's explicit `width`\n (pixels) always wins.\n- **Hyperlinks** - give a column a `link(row)` hook to render clickable links.\n Works in `xlsx`, `xls`, `html`, `pdf`, and `print`.\n\nSingle-sheet `xlsx` is written by SvGrid's own OOXML writer, so numbers/dates\nstay typed with number formats, conditional-format colors are **real per-cell\nfills**, and freeze/widths/hyperlinks all apply. (Grouped/outline, multi-sheet,\nembedded-image, and merged-cell exports use the bundled writer.)\n\n```ts\nawait api.exportData({\n format: 'xlsx',\n freezeHeader: true, // default\n columns: [\n { field: 'name', header: 'Company', width: 220,\n link: (row) => `https://crm.example.com/accounts/${row.id}` },\n { field: 'revenue', header: 'Revenue', format: { type: 'currency', currency: 'USD' } },\n ],\n})\n```\n\nConditional-format colors (data bars / color scales) already render as real\ncell fills in `xlsx`, which is higher fidelity than the writer's built-in\nrule-only conditional formatting - so we keep the per-cell approach.\n\n### Get the file instead of downloading (`download: false`)\n\n`exportData` returns an **`ExportResult`** for the dependency-free paths\n(csv/tsv/html/json/xml/md, xls, pdf, single-sheet xlsx) so you can preview,\nupload, email, or attach the file. With `download: false` it builds and returns\nthe file **without** triggering a browser download:\n\n```ts\nconst res = await api.exportData({ format: 'xlsx', download: false })\n// res: { blob, filename, mime, rowCount, byteSize }\nawait uploadToStorage(res.blob, res.filename)\n```\n\nThe grouped / multi-sheet / image / blanket-styled xlsx paths use the vendored\nwriter, which downloads directly and returns `undefined` (and throws on\n`download: false`).\n\n### Excel Table (filter dropdowns + totals row)\n\nWrap a single-sheet xlsx in a native **Excel Table** - the user gets column\nfilter dropdowns, banded rows, structured references, and (optionally) a totals\nrow with live `SUM()` formulas:\n\n```ts\nawait api.exportData({ format: 'xlsx', excelTable: { totalsRow: true } })\n// or just `excelTable: true` for the table without a totals row\n```\n\nColumn widths auto-fit and leading **pinned columns are frozen automatically**\n(override with `freezeColumns`). For long IDs, `precisionSafe: true` writes them\nas text so Excel's 15-digit float limit doesn't silently round `1002000300040005`.\n\n### JSON / XML / Markdown\n\n```ts\nawait api.exportData({ format: 'json' }) // array of { field: value } - defaults to raw values\nawait api.exportData({ format: 'xml' }) // <rows><row><field>value</field>…\nawait api.exportData({ format: 'md' }) // GitHub-flavored Markdown table (great for docs / LLMs)\n```\n\nJSON defaults to **raw** values (real numbers/dates) since it's a data format;\npass `rawValues: false` for formatted strings. XML and Markdown use the\nformatted display values.\n\n### Copy to clipboard\n\n`api.copyExport(opts)` serializes to the clipboard instead of downloading a\nfile - handy for \"copy these rows into a spreadsheet or an email\":\n\n```ts\nawait api.copyExport({ format: 'tsv' }) // pastes into Excel / Sheets as columns (default)\nawait api.copyExport({ format: 'md', rows: 'selected' }) // Markdown table of the checked rows\nawait api.copyExport({ format: 'html' }) // rich text/html - keeps the table when pasted\n```\n\nSupported formats: `csv`, `tsv`, `html`, `json`, `xml`, `md`. `html` writes\nboth `text/html` (rich paste) and a `text/plain` fallback. Needs a secure\ncontext and a user gesture (call it from a click).\n\n### Conditional formatting in exports\n\nPass the same `conditionalFormats` array you give `<SvGrid>` to carry the grid's\ncolor scales, data bars, icon sets, and predicate rules into the **styled**\nformats - PDF, xlsx, and HTML (and `print()`):\n\n```ts\nconst conditionalFormats = [\n { type: 'colorScale', columns: ['score'], min: '#dcfce7', max: '#fee2e2' },\n { type: 'rule', columns: ['status'], when: ({ value }) => value === 'Overdue', background: '#fecaca' },\n]\n\nawait api.exportData({ format: 'pdf', conditionalFormats })\nawait api.exportData({ format: 'xlsx', conditionalFormats }) // real cell fills in Excel\nawait api.print({ conditionalFormats })\n```\n\nCell background, text color, and bold carry through as **real cell fills** in\n`xlsx` (single-sheet), `xls`, `html`, and `pdf`; icon sets prepend their glyph\nto the cell text.\n\nIn **xlsx**, **data bars** and **color scales** become **native Excel\nconditional formatting** (`<conditionalFormatting>` rules) - Excel draws and\nrecomputes them itself, so they're interactive, not a static snapshot.\nPredicate `rule` formats stay as computed per-cell fills. In the other styled\nformats (`xls` / `html` / `pdf`) a data bar degrades to a light fill of the bar\ncolor (cells can't hold a partial-width bar). The data formats (csv / tsv /\njson / xml / md) are unstyled, so conditional formatting is ignored there.\nGrouped PDF exports skip conditional formatting (the group/subtotal rows own the\nlayout).\n\n### PDF options\n\nThe PDF is built from a full pdfmake document you control via `pdf`:\n\n```ts\nawait api.exportData({\n format: 'pdf',\n filename: 'orders',\n pdf: {\n pageSize: 'A4', // 'A4' | 'A3' | 'A5' | 'LETTER' | 'LEGAL'\n pageOrientation: 'landscape',\n title: 'Q3 Orders',\n subtitle: 'Generated by Ops',\n logo: logoDataUrl, // top-left image (data URL)\n headerColor: '#334155', // header row fill\n zebra: true, // striped rows\n columnWidths: '*', // '*' fill, 'auto', or a per-column pt array\n // repeatHeader (default true), showPageNumbers (default true) also available\n },\n})\n```\n\nThe header row repeats on every page, each page gets a `Page X of Y` +\ndate footer, per-column alignment is honored, and wide grids auto-switch to\nlandscape (override with `pdf.pageOrientation`).\n\nThe PDF looks like the grid it came from. With `pdf.matchTheme` (default\ntrue) the exporter reads the mounted grid's computed colours - header fill\nand text, body text, the zebra stripe, the lines, a group row's fill - so a\ngrid on the Ember theme or a Theme Builder palette prints in those colours\nrather than the slate defaults. A dark theme lends only its header: the\npage is white, so its body text and stripes would not read. The order of\nprecedence is explicit `pdf` colours (`headerColor`, `headerTextColor`,\n`textColor`, `zebraColor`, `borderColor`, `groupColor`, ...), then\n`styles`, then the theme, then the defaults. `styles.headerRow` /\n`styles.rows` / `styles.rowAlternate` / `styles.cells` (A1 references, row\n1 being the header) apply to the PDF table the way they do to xlsx and\nhtml, `header` / `footer` lines print above and below the table, and\n`merges` span data cells.\n\nWhen the grid is grouped, the PDF carries the grouping: a bold **group header**\nper cluster (nested for multi-level grouping) and a **subtotal row** summing the\nnumber / currency columns - matching the xlsx outline export. It's on by\ndefault (`autoGroup`); pass `groupBy` to override or `autoGroup: false` to get a\nflat table.\n\n#### Charts and a KPI strip\n\nA report is rarely just the table. `pdf.charts` prints charts with it: hand\nover the rendered chart's element (the `SvChart` wrapper or its `<svg>`) and\nthe export rasterises it at 2x through the chart's own PNG path, so the page\ngets the picture on screen, theme and all; or pass an image data URL you\nalready have. Each takes a `title`, a `caption` and a `width` in pt\n(default: the content width). `pdf.kpis` prints a strip of headline numbers\nabove the table, each with a label, the value and an optional `delta` line\nin its own colour:\n\n```svelte\n<div bind:this={chartEl}><SvChart {spec} /></div>\n\n<button onclick={() => api.exportData({\n format: 'pdf',\n filename: 'q3-report',\n pdf: {\n title: 'Q3 Orders',\n kpis: [\n { label: 'Revenue', value: '$1.24M', delta: '+4.2% vs Q2', color: '#16a34a' },\n { label: 'Orders', value: '842' },\n { label: 'Avg order', value: '$1,473', delta: '-1.1%', color: '#ef4444' },\n ],\n charts: [{ element: chartEl, title: 'Revenue by region', caption: 'Displayed rows, grouped by region' }],\n chartsPosition: 'above', // or 'below' the table\n },\n})}>Export report</button>\n```\n\nA chart block never splits across a page break. `resolvePdfCharts` and\n`buildPdfDocDefinition` are exported for a document you assemble yourself.\n\n#### Merged cells\n\nPass `merges` to write real merged regions into the sheet. Row / column\nindices are zero-based over the exported **body** (the header row is not\ncounted), and the shape lines up with the grid's own `MergeSpec`:\n\n```ts\n// Merge the first two data rows of column 0, and span a 3-column banner\nawait api.exportData({\n format: 'xlsx',\n merges: [\n { row: 0, col: 0, rowSpan: 2 }, // vertical merge (e.g. a repeated group key)\n { row: 5, col: 0, colSpan: 3 }, // horizontal merge (a section banner)\n ],\n})\n```\n\nTo export the merges you already show in the grid, take your `MergeSpec[]`\n(`{ rowIndex, columnId, rowspan, colspan }`) and map `columnId` to its column\nindex: `{ row: m.rowIndex, col: colIndex(m.columnId), rowSpan: m.rowspan, colSpan: m.colspan }`.\n\nThrows on missing peer (`jszip` / `pdfmake`), revoked / malformed\nlicense, or empty result set. With no license set, it runs but the\ngrid is watermarked.\n\n### `api.print(opts?)` - `Promise<void>`\n\nOpens a new window with a paginated, printable rendering of the grid and\ntriggers the browser print dialog. This is the **zero-dependency \"Save as PDF\"**\nroute: it uses the browser's own engine, so it has excellent font + CSS\nfidelity (including CJK / RTL) and needs no `pdfmake`. The header row repeats on\nevery page, values print **formatted** (matching the grid), and columns keep\ntheir alignment.\n\n| Option | Type | Default |\n| ------------- | -------------------------------------- | ----------- |\n| `title` | `string` | `\"Grid\"` |\n| `subtitle` | `string` | - |\n| `logo` | `string` (data URL) | - |\n| `columns` | `{ field; header?; format?; align? }[]`| grid's own columns |\n| `rows` | `ReadonlyArray<TData> \\| 'displayed' \\| 'selected' \\| 'all'` | `'displayed'` |\n| `rawValues` | `boolean` | `false` |\n| `orientation` | `'portrait' \\| 'landscape'` | `\"portrait\"` |\n| `pageSize` | `string` (e.g. `'A4'`, `'Letter'`) | browser default |\n| `margin` | `string` (e.g. `'14mm'`) | `'14mm'` |\n| `zebra` | `boolean` | `true` |\n| `headerColor` | `string` | `'#f1f5f9'` |\n\nBrowsers may block the popup unless `print()` is called from a user\ngesture (a click handler is fine - automatic on-load print is not). Page\nnumbers come from the browser's own print header/footer.\n\n**`exportData({ format: 'pdf' })` vs `print()`** - use PDF export for a\nprogrammatic, silent file download with full layout control (see \"PDF\noptions\"); use `print()` when you want best-fidelity output and the user to\npick print or \"Save as PDF\" from the dialog.\n\n## Drop-in Export menu (`SvExportMenu`)\n\nRather than wiring your own toolbar, drop in the bundled `SvExportMenu`\ncomponent. It renders an \"Export\" button with a format picker, a row-scope\ntoggle (current view / selected / all), and a built-in progress bar + Cancel\nfor large exports:\n\n```svelte\n<script lang=\"ts\">\n import { SvGrid, type SvGridApi } from '@svgrid/grid'\n import { installEnterprise, SvExportMenu, type EnterpriseGridApi } from '@svgrid/enterprise'\n\n let api = $state<EnterpriseGridApi<typeof features, Order> | null>(null)\n</script>\n\n<div class=\"toolbar\">\n <SvExportMenu {api} filename=\"orders\" />\n</div>\n\n<SvGrid data={rows} columns={columns} features={features}\n onApiReady={(a) => (api = installEnterprise(a))} />\n```\n\n| Prop | Type | Default | Notes |\n| ------------ | ------------------------------------------------ | --------------------------- | ----- |\n| `api` | `EnterpriseGridApi \\| null` | required | Button is disabled until the api is ready. |\n| `filename` | `string` | `'grid'` | Base name, no extension. |\n| `formats` | `ExportFormat[]` | xlsx/xls/pdf/csv/tsv/html | Which formats to offer, in order. |\n| `allowScope` | `boolean` | `true` | Show the current-view / selected / all toggle. |\n| `allowColumns` | `boolean` | `true` | Show per-column include checkboxes (choose which columns to export). |\n| `allowCopy` | `boolean` | `true` | Show \"Copy for Excel\" (tsv) + \"Copy Markdown\" clipboard actions. |\n| `allowPrint` | `boolean` | `false` | Show a \"Print…\" action (`api.print`). |\n| `scope` | `'displayed' \\| 'selected' \\| 'all'` | `'displayed'` | Initial row scope. |\n| `label` | `string` | `'Export'` | Button text. |\n| `conditionalFormats` | `ConditionalFormat[]` | - | Carried into pdf / xlsx / html exports. |\n\nThe menu is sectioned into **Rows** (scope), **Columns** (a picker), and\n**Download** (each format shown with an icon + one-line description), plus\n**copy-to-clipboard** and optional **print** actions. It's **keyboard\naccessible** (arrow keys move between items, Tab is trapped inside, Esc closes\nand returns focus to the button, with `role=\"menu\"` / `menuitem`), handles\nerrors inline (missing peer dependency, empty grid), and wires `onProgress` +\nan `AbortController` for you.\n\nFor large exports, the single-sheet xlsx writer builds in **chunks that yield to\nthe event loop** (and zips asynchronously), so the tab stays responsive and\n`onProgress` ticks; pass a `signal` to cancel.\n\n## Gotchas\n\n- **Empty grids** - both `exportData` and `print` throw if there are no\n displayed rows. Catch the error and show a notice in the UI.\n- **Column ordering** - if you don't pass `columns`, the export uses\n `Object.keys(rows[0])` order. Pass `columns` explicitly when the row\n shape doesn't match the column order you want.\n- **Cell formatters** - column-level format hints (date, number, currency,\n percent) are applied to the exported value by default, so the file matches\n the grid. Custom snippet renderers are **not** auto-serialized - give those\n columns an `exportValue` hook (see \"Faithful values\" above), or set\n `rawValues: true` if you want the raw underlying values.\n- **Print popup blocked** - `print()` resolves but the browser silently\n blocks the new window. Always trigger from a user click, and surface\n the thrown error.\n- **Bundle size** - the vendored exporter is ~50 KB minified. It is\n loaded lazily on first call so it does not bloat the initial bundle\n for users who never export.\n\n## Frequently asked questions\n\n### How do I export a Svelte data grid to Excel?\n\nInstall `@svgrid/enterprise`, call `installEnterprise(api)`, then call the export helper with\n`format: 'xlsx'`. The exporter writes a real OOXML workbook in the browser - no\nserver round-trip. CSV, TSV, PDF, and HTML use the same call with a different\nformat.\n\n### What's the difference between `xls` and `xlsx`?\n\n`xlsx` is the modern OOXML workbook (Excel 2007+); it needs the `jszip` peer\ndependency and supports the richest output (styles, images, multi-sheet,\nformulas). `xls` is the **legacy Excel 2003 XML Spreadsheet** format: pick it\nfor maximum compatibility with old Excel installs or systems that only accept\n`.xls`. It has **no peer dependency**, streams in the browser, and keeps\nnumbers and dates typed (so sums and sorting still work in Excel) with number\nformats applied. It's single-sheet - use `xlsx` for multi-tab workbooks.\n\n```ts\nawait api.exportData({ format: 'xls', filename: 'orders' })\n```\n\n### Is export part of the free Community package?\n\nNo. Export and printing ship in the paid `@svgrid/enterprise` add-on. The free\n`@svgrid/grid` package covers the full grid (sorting, filtering, grouping,\nediting, virtualization) but not export/print/pivot/import.\n\n### Does exporting bloat my bundle?\n\nNo. The ~50 KB exporter is lazy-loaded on the first export call, so users who\nnever export never download it.\n\n## More examples\n\n### Password-protected export\n\nPBKDF2 (100k iters) + AES-GCM 256 client-side. Strength meter, encrypt + download, in-page decrypt tool to verify the round-trip. Enterprise pack maps to ECMA-376 Agile encryption.\n\n<div data-docs-demo=\"93-password-protected-export\" data-height=\"460\"></div>\n\n### Formulas preserved in xlsx\n\nBuilds a real OOXML workbook in the browser via JSZip; computed columns export as <f>...</f> formula cells. Open in Excel and the math recomputes when you edit a number.\n\n<div data-docs-demo=\"101-formulas-in-xlsx\" data-height=\"460\"></div>\n\n### Export grouped grid to Excel\n\nA flat sales grid (Region → Country) exported via api.exportData({ format: \"xlsx\", groupBy }) which uses Smart's NATIVE Excel row outline grouping. Opens in Excel with +/- buttons in the row header gutter for every group level.\n\n<div data-docs-demo=\"126-export-grouped-grid\" data-height=\"460\"></div>\n\n### Export pivot grid to Excel\n\ncreatePivotModel leaves projected into an xlsx via api.exportData with groupBy: [\"region\"] - each region becomes an Excel outline group. Engine column ids (\"pv__Q1__m0\") translate to readable headers (\"Q1 · Revenue\").\n\n<div data-docs-demo=\"127-export-pivot-grid\" data-height=\"460\"></div>\n\n### Export - Formatting, scope + XLS\n\nFaithful export: currency / date / percent render as shown (toggle raw values), pick a row scope (view / selected / all), legacy .xls (Excel 2003 XML, no jszip), an exportValue hook, and the drop-in SvExportMenu.\n\n<div data-docs-demo=\"201-export-formatting-and-xls\" data-height=\"460\"></div>\n\n### Export - Grouped PDF + Print\n\nGroup the grid and export: the PDF + xlsx carry bold group headers and per-cluster subtotal rows (auto-carried from grouping state). Polished Print is the zero-dependency \"Save as PDF\" route with a repeated header and title.\n\n<div data-docs-demo=\"202-export-pdf-grouped-and-print\" data-height=\"460\"></div>\n\n## Try the export API\n\nEvery exporter is on the grid api and takes the same\n`GridExportOptions`. `rows: 'displayed'` is the default and is almost always\nwhat a user means by \"export this\" - it follows their filter and sort.\n\n```svelte\n<script lang=\"ts\">\n let api = $state<SvGridApi<{}, Person> | null>(null)\n</script>\n\n<div>\n <button type=\"button\" onclick={() => api?.exportCsv({ filename: 'people' })}>CSV</button>\n <button type=\"button\" onclick={() => api?.exportTsv({ filename: 'people' })}>TSV</button>\n <button type=\"button\" onclick={() => api?.exportJson({ filename: 'people' })}>JSON</button>\n <button type=\"button\" onclick={() => api?.print()}>Print</button>\n</div>\n\n<SvGrid data={people} {columns} sortable filterable onApiReady={(next) => (api = next)} />\n```\n\nSort or filter first, then export: the file follows the view.\n\n## Exporting a subset\n\n`columns` restricts the fields and fixes their order, and `rawValues` decides\nwhether the file carries what the screen shows or what the row holds. The\nsalary column is the one to watch - formatted it is `$142,000`, raw it is\n`142000`, and a spreadsheet can only do arithmetic on the second.\n\n```svelte\n<script lang=\"ts\">\n let api = $state<SvGridApi<{}, Person> | null>(null)\n</script>\n\n<div>\n <button type=\"button\" onclick={() => api?.exportCsv({ filename: 'formatted', columns: ['name', 'salary'] })}>\n Name + salary, as displayed\n </button>\n <button type=\"button\" onclick={() => api?.exportCsv({ filename: 'raw', columns: ['name', 'salary'], rawValues: true })}>\n Name + salary, raw values\n </button>\n</div>\n\n<SvGrid data={people} {columns} onApiReady={(next) => (api = next)} />\n```\n"
|
|
4485
|
+
"markdown": "# Data export and printing\n\n**CSV / TSV / JSON export and copy-to-clipboard are free** in the community\n**[@svgrid/grid](https://www.npmjs.com/package/@svgrid/grid)** - the commodity\n\"data out\" every grid needs. The richer formats - **Excel (xlsx)**, **legacy\nExcel (xls)**, **PDF**, styled **HTML**, **XML**, **Markdown**, multi-sheet\nworkbooks, password protection, conditional-format export, and the drop-in\nexport menu - ship in the paid\n**[@svgrid/enterprise](https://www.npmjs.com/package/@svgrid/enterprise)** add-on,\nwhich reuses the exact same serializers so the two tiers feel like one product.\n\nFor the report built step by step, with a live grid under most steps, see [Export: a report to Excel and PDF](./export/report.md); this page is the reference.\n\n\n\n| Capability | Package |\n| ---------- | ------- |\n| CSV / TSV / JSON export, copy-to-clipboard (TSV / CSV / Markdown) | **Free** (`@svgrid/grid`) |\n| Excel `.xlsx` (typed cells, styles, conditional formatting, tables, multi-sheet) | Enterprise |\n| PDF, styled HTML, XML, legacy `.xls`, password-protected export | Enterprise |\n| `exportValue` hook, conditional-format export, `SvExportMenu`, `print()` | Enterprise |\n\n## Free: CSV / TSV / JSON + clipboard\n\nThe community grid's `SvGridApi` carries four zero-dependency methods - no\nlicense, no peer deps:\n\nThe examples on this page run against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns, tableFeatures, rowSortingFeature, columnFilteringFeature } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n email: string\n department: string\n age: number\n salary: number\n city: string\n startDate: string\n active: boolean\n }\n\n type Order = {\n id: string\n customer: string\n product: string\n quantity: number\n total: number\n status: 'pending' | 'shipped' | 'delivered'\n orderedAt: string\n }\n\n type Row = Person\n\n const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', email: 'ada@example.com', department: 'Engineering', age: 36, salary: 142000, city: 'London', startDate: '2021-03-01', active: true },\n { id: 2, name: 'Grace Hopper', email: 'grace@example.com', department: 'Engineering', age: 45, salary: 168000, city: 'New York', startDate: '2019-07-15', active: true },\n { id: 3, name: 'Linus Torvalds', email: 'linus@example.com', department: 'Platform', age: 54, salary: 155000, city: 'Portland', startDate: '2020-01-20', active: false },\n { id: 4, name: 'Radia Perlman', email: 'radia@example.com', department: 'Networking', age: 49, salary: 161000, city: 'Seattle', startDate: '2022-09-05', active: true },\n { id: 5, name: 'Barbara Liskov', email: 'barbara@example.com', department: 'Platform', age: 52, salary: 172000, city: 'Boston', startDate: '2018-11-11', active: true },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200 },\n { field: 'department', header: 'Department', width: 150 },\n { field: 'city', header: 'City', width: 140 },\n { field: 'age', header: 'Age', width: 90 },\n { field: 'salary', header: 'Salary', width: 130, format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```ts\nawait api.exportCsv({ filename: 'orders' }) // orders.csv (BOM + Excel-friendly)\nawait api.exportTsv() // grid.tsv\nawait api.exportJson({ rows: 'selected' }) // grid.json, checked rows only\nawait api.copyToClipboard({ format: 'tsv' }) // paste straight into Excel / Sheets\n```\n\nEvery method:\n\n- defaults to the **current view** (`rows: 'selected' | 'all'` to change),\n- formats values **as shown on screen** (currency, dates) - pass\n `rawValues: true` for the underlying values,\n- accepts a `columns: string[]` field subset (in that order),\n- runs on a chunked, cancelable loop (`signal`, `onProgress`) so a 100k-row\n export never freezes the tab,\n- returns the serialized text; pass `download: false` to skip the download\n and just get the string.\n\n```svelte {runnable}\n<script lang=\"ts\">\n import { SvGrid, tableFeatures, type SvGridApi } from '@svgrid/grid'\n let api = $state<SvGridApi<any, Row> | null>(null)\n</script>\n\n<button onclick={() => api?.exportCsv({ filename: 'orders' })}>Export CSV</button>\n<button onclick={() => api?.copyToClipboard()}>Copy for Excel</button>\n<SvGrid data={rows} columns={columns} features={features} onApiReady={(a) => (api = a)} />\n```\n\nThe rest of this page covers the **Enterprise** formats.\n\nTry the export bar below - downloads run in your browser; the bundled\nlicense key removes the unlicensed watermark:\n\n<div data-docs-demo=\"21-export-and-print\" data-height=\"500\"></div>\n\n\n## What it is\n\n`@svgrid/enterprise` augments the `SvGridApi` you already get from\n`<SvGrid onApiReady>` with two methods:\n\n- `api.exportData({ format, filename?, columns?, rows?, pageOrientation? })`\n- `api.print({ title?, columns?, rows?, orientation? })`\n\nBoth methods default to **the currently displayed rows** - sort, filter,\nor paginate the grid, and the export reflects that view automatically.\n\n## When to use it\n\n- Reporting flows where users want to take the grid offline (spreadsheets,\n emailed PDFs).\n- Compliance / audit trails that require a printable artifact.\n- Quick CSV/TSV pulls for downstream pipelines.\n\nIf you only need machine-readable data, prefer CSV / TSV - they have no\npeer dependencies and produce the smallest files. Use xlsx / PDF only\nwhen the recipient expects formatted documents.\n\n## Minimal example\n\n```svelte {runnable}\n<script lang=\"ts\">\n import { SvGrid, tableFeatures, rowSortingFeature, type SvGridApi, type ColumnDef } from '@svgrid/grid'\n import { installEnterprise, type EnterpriseGridApi } from '@svgrid/enterprise'\n\n // Without a key, the feature still works but the grid shows an\n // \"unlicensed\" watermark and the console emits a one-time nudge directing\n // users to the pricing page. After you buy, call setLicenseKey(yourKey)\n // once at startup.\n\n const features = tableFeatures({ rowSortingFeature })\n\n type Order = { company: string; product: string; price: number }\n const rows: Order[] = [\n { company: 'ACME', product: 'Widget', price: 19.95 },\n { company: 'Globex', product: 'Gadget', price: 49.00 },\n ]\n const columns: ColumnDef<typeof features, Order>[] = [\n { field: 'company', header: 'Company' },\n { field: 'product', header: 'Product' },\n { field: 'price', header: 'Price', format: { type: 'currency', currency: 'USD' } },\n ]\n\n let api = $state<EnterpriseGridApi<typeof features, Order> | null>(null)\n\n function onReady(next: SvGridApi<typeof features, Order>) {\n api = installEnterprise(next)\n }\n</script>\n\n<button onclick={() => api?.exportData({ format: 'xlsx', filename: 'orders' })}>\n Export Excel\n</button>\n<button onclick={() => api?.exportData({ format: 'pdf', filename: 'orders', pageOrientation: 'landscape' })}>\n Export PDF\n</button>\n<button onclick={() => api?.print({ title: 'Orders' })}>\n Print\n</button>\n\n<SvGrid data={rows} columns={columns} features={features} onApiReady={onReady} />\n```\n\n## Install\n\n```bash\npnpm add @svgrid/enterprise\n# Optional - install only the peers you actually use:\npnpm add jszip # required for xlsx\npnpm add pdfmake # required for pdf\n```\n\nCSV, TSV, HTML, and Print have **no extra dependencies**. The peer\ndependencies are lazy-loaded only when you call the format that needs\nthem.\n\n## Licensing\n\n`@svgrid/enterprise` has a tiered license gate:\n\n| Key state | Behavior |\n| ------------------------------------------ | -------- |\n| No key set (`setLicenseKey()` not called) | Feature works. Grid shows an unlicensed watermark linking to svgrid.com/pricing; console.log emits a one-time nudge. |\n| A key that is not your license key | Same as no key: the feature works, with the watermark and a one-time console warning. |\n| Your license key | Works silently. |\n\nBuy a production key at <https://svgrid.com/pricing/> ($599 / developer /\nyear). To evaluate, you need no key at all: everything runs with a watermark.\n\n## Reference\n\n### `setLicenseKey(key: string): void`\n\nStores the key in module state. Call once at app startup (e.g. in\n`main.ts`). Subsequent calls overwrite.\n\n### `clearLicenseKey(): void` · `hasValidLicense(): boolean` · `dismissUnlicensedNudge(): void`\n\nProgrammatic helpers. `hasValidLicense()` is useful when you want UI to\nbranch on license status. `dismissUnlicensedNudge()` removes the\nwatermark and stops the MutationObserver - call it after setting a\nvalid key if you loaded the module without one during testing.\n\n### `installEnterprise(api): EnterpriseGridApi`\n\nMutates the given `SvGridApi` to add `exportData` and `print`. Returns\nthe same object with the augmented type, so existing references keep\nworking.\n\n### `api.exportData(opts)` - `Promise<void>`\n\n| Option | Type | Default | Notes |\n| ----------------- | ----------------------------------------------------- | -------------------- | ----- |\n| `format` | `'xlsx' \\| 'xls' \\| 'pdf' \\| 'csv' \\| 'tsv' \\| 'html' \\| 'json' \\| 'xml' \\| 'md'` | required | `xlsx` needs `jszip`, `pdf` needs `pdfmake`. `xls` / CSV / TSV / HTML / JSON / XML / Markdown are dependency-free. |\n| `pdf` | `PdfExportOptions` | - | PDF layout: page size, margins, title / subtitle / logo, theme colors, column widths, repeated header, page numbers. See \"PDF options\". |\n| `conditionalFormats` | `ConditionalFormat[]` | - | Same array as `<SvGrid conditionalFormats>`; carried into pdf / xlsx / html. See \"Conditional formatting in exports\". |\n| `freezeHeader` | `boolean` | `true` | Freeze the header row (xlsx / xls). |\n| `freezeColumns` | `number` | pinned cols | Freeze this many leading columns (xlsx / xls). Defaults to the grid's left-pinned columns. |\n| `autoFitColumns` | `boolean` | `true` | Size columns to content (xlsx / xls); a column's explicit `width` wins. |\n| `precisionSafe` | `boolean` | `false` | Export long integer IDs (> 15 digits) as text so Excel's float precision doesn't round them (xlsx / xls). |\n| `excelTable` | `boolean \\| { totalsRow?; style? }` | - | Wrap single-sheet xlsx in a native Excel Table (filter dropdowns, banded rows; `{ totalsRow: true }` adds SUM formulas). |\n| `download` | `boolean` | `true` | When false, return the {@link ExportResult} without downloading. |\n| `filename` | `string` | `\"grid\"` | Extension is appended if missing. |\n| `columns` | `{ field; header?; format?; align?; exportValue? }[]` | grid's own columns | Drives column selection + header labels. Auto-derived from the grid (with each column's `format`) when omitted. See `exportValue` below. |\n| `rows` | `ReadonlyArray<TData> \\| 'displayed' \\| 'selected' \\| 'all'` | `'displayed'` | `'displayed'` = current filtered/sorted/paged view, `'selected'` = checked rows, `'all'` = full dataset, or pass an explicit array. |\n| `rawValues` | `boolean` | `false` | By default the exporter writes the **formatted display value** (what you see). Set `true` to write raw underlying values (numbers stay numeric in xlsx). |\n| `autoGroup` | `boolean` | `true` | Carry the grid's active row grouping into xlsx outline rows. Pass your own `groupBy` to override, or `false` to ignore. |\n| `csv` | `{ delimiter?; eol?; bom? }` | `{ ',', '\\r\\n', BOM }` | CSV / TSV tuning. UTF-8 BOM is on by default so Excel opens it without mojibake. |\n| `onProgress` | `(p) => void` | - | Progress for large exports: `{ phase, ratio, row?, total? }`, `phase` = `'project' \\| 'serialize' \\| 'write'`. |\n| `signal` | `AbortSignal` | - | Cancel an in-flight export (checked between chunks). Rejects with `AbortError`. |\n| `pageOrientation` | `'portrait' \\| 'landscape'` | `\"portrait\"` | PDF only. |\n| `merges` | `{ row; col; rowSpan?; colSpan? }[]` | `[]` | Merged cells (xlsx / pdf). Zero-based **body** row/col (header excluded). Single-sheet only; mutually exclusive with `groupBy` / `hierarchical`. |\n\n### Faithful values (what you see is what you export)\n\nBy default the export renders each cell the way the grid does on screen: a\ncolumn with `format: { type: 'currency', currency: 'USD' }` exports `$19.95`,\na date column exports its formatted date, a percent column exports `42%`. This\nholds for **every** format (csv / tsv / html / pdf / xlsx). Pass\n`rawValues: true` to write the underlying values instead (e.g. feeding a data\npipeline that wants the numeric `19.95`).\n\nFor columns whose on-screen value comes from a **custom cell renderer**, a\n`fieldFn`, or a lookup, give the column an `exportValue` hook - it takes\nprecedence over `format` and the raw field:\n\n```ts\nawait api.exportData({\n format: 'xlsx',\n columns: [\n { field: 'company', header: 'Company' },\n // a column rendered with a custom snippet on screen:\n { field: 'status', header: 'Status', exportValue: (row) => STATUS_LABELS[row.status] },\n ],\n})\n```\n\n### Export only what's selected\n\n```ts\n// current view (default)\nawait api.exportData({ format: 'xlsx' })\n// only the checked rows\nawait api.exportData({ format: 'xlsx', rows: 'selected' })\n// the entire underlying dataset, ignoring filters/paging\nawait api.exportData({ format: 'csv', rows: 'all' })\n```\n\n### Large exports: progress + cancel\n\nCSV / TSV / HTML are serialized natively (no peer dependency) and stream in\nchunks, yielding to the event loop so a big export doesn't freeze the tab:\n\n```ts\nconst controller = new AbortController()\nawait api.exportData({\n format: 'csv',\n rows: 'all',\n signal: controller.signal,\n onProgress: ({ ratio }) => updateProgressBar(ratio),\n})\n// controller.abort() rejects the export with an AbortError\n```\n\n### Excel-native numbers (xlsx)\n\nA single-sheet `xlsx` export writes numeric, currency, percent, and date\ncolumns as **real typed cells** with an Excel number format - so Excel can sum\nand sort them, and they still display formatted (currency symbol, thousands,\n`%`, date pattern) - via SvGrid's own OOXML writer. Set `rawValues: true` for\nunformatted raw values. The grouped-outline, multi-sheet, image, and merged-cell\npaths use the bundled writer (formatted-string cells). The legacy `xls` format\nis always typed.\n\n### Excel fidelity: freeze, auto-fit, hyperlinks\n\n`xlsx` and `xls` exports polish the spreadsheet automatically:\n\n- **Freeze header** - the header row stays visible when scrolling. On by\n default; `freezeHeader: false` to disable, `freezeColumns: n` to also freeze\n leading columns.\n- **Auto-fit column widths** - columns are sized to their content. On by\n default (`autoFitColumns: false` to disable); a column's explicit `width`\n (pixels) always wins.\n- **Hyperlinks** - give a column a `link(row)` hook to render clickable links.\n Works in `xlsx`, `xls`, `html`, `pdf`, and `print`.\n\nSingle-sheet `xlsx` is written by SvGrid's own OOXML writer, so numbers/dates\nstay typed with number formats, conditional-format colors are **real per-cell\nfills**, and freeze/widths/hyperlinks all apply. (Grouped/outline, multi-sheet,\nembedded-image, and merged-cell exports use the bundled writer.)\n\n```ts\nawait api.exportData({\n format: 'xlsx',\n freezeHeader: true, // default\n columns: [\n { field: 'name', header: 'Company', width: 220,\n link: (row) => `https://crm.example.com/accounts/${row.id}` },\n { field: 'revenue', header: 'Revenue', format: { type: 'currency', currency: 'USD' } },\n ],\n})\n```\n\nConditional-format colors (data bars / color scales) already render as real\ncell fills in `xlsx`, which is higher fidelity than the writer's built-in\nrule-only conditional formatting - so we keep the per-cell approach.\n\n### Get the file instead of downloading (`download: false`)\n\n`exportData` returns an **`ExportResult`** for the dependency-free paths\n(csv/tsv/html/json/xml/md, xls, pdf, single-sheet xlsx) so you can preview,\nupload, email, or attach the file. With `download: false` it builds and returns\nthe file **without** triggering a browser download:\n\n```ts\nconst res = await api.exportData({ format: 'xlsx', download: false })\n// res: { blob, filename, mime, rowCount, byteSize }\nawait uploadToStorage(res.blob, res.filename)\n```\n\nThe grouped / multi-sheet / image / blanket-styled xlsx paths use the vendored\nwriter, which downloads directly and returns `undefined` (and throws on\n`download: false`).\n\n### Excel Table (filter dropdowns + totals row)\n\nWrap a single-sheet xlsx in a native **Excel Table** - the user gets column\nfilter dropdowns, banded rows, structured references, and (optionally) a totals\nrow with live `SUM()` formulas:\n\n```ts\nawait api.exportData({ format: 'xlsx', excelTable: { totalsRow: true } })\n// or just `excelTable: true` for the table without a totals row\n```\n\nColumn widths auto-fit and leading **pinned columns are frozen automatically**\n(override with `freezeColumns`). For long IDs, `precisionSafe: true` writes them\nas text so Excel's 15-digit float limit doesn't silently round `1002000300040005`.\n\n### JSON / XML / Markdown\n\n```ts\nawait api.exportData({ format: 'json' }) // array of { field: value } - defaults to raw values\nawait api.exportData({ format: 'xml' }) // <rows><row><field>value</field>…\nawait api.exportData({ format: 'md' }) // GitHub-flavored Markdown table (great for docs / LLMs)\n```\n\nJSON defaults to **raw** values (real numbers/dates) since it's a data format;\npass `rawValues: false` for formatted strings. XML and Markdown use the\nformatted display values.\n\n### Copy to clipboard\n\n`api.copyExport(opts)` serializes to the clipboard instead of downloading a\nfile - handy for \"copy these rows into a spreadsheet or an email\":\n\n```ts\nawait api.copyExport({ format: 'tsv' }) // pastes into Excel / Sheets as columns (default)\nawait api.copyExport({ format: 'md', rows: 'selected' }) // Markdown table of the checked rows\nawait api.copyExport({ format: 'html' }) // rich text/html - keeps the table when pasted\n```\n\nSupported formats: `csv`, `tsv`, `html`, `json`, `xml`, `md`. `html` writes\nboth `text/html` (rich paste) and a `text/plain` fallback. Needs a secure\ncontext and a user gesture (call it from a click).\n\n### Conditional formatting in exports\n\nPass the same `conditionalFormats` array you give `<SvGrid>` to carry the grid's\ncolor scales, data bars, icon sets, and predicate rules into the **styled**\nformats - PDF, xlsx, and HTML (and `print()`):\n\n```ts\nconst conditionalFormats = [\n { type: 'colorScale', columns: ['score'], min: '#dcfce7', max: '#fee2e2' },\n { type: 'rule', columns: ['status'], when: ({ value }) => value === 'Overdue', background: '#fecaca' },\n]\n\nawait api.exportData({ format: 'pdf', conditionalFormats })\nawait api.exportData({ format: 'xlsx', conditionalFormats }) // real cell fills in Excel\nawait api.print({ conditionalFormats })\n```\n\nCell background, text color, and bold carry through as **real cell fills** in\n`xlsx` (single-sheet), `xls`, `html`, and `pdf`; icon sets prepend their glyph\nto the cell text.\n\nIn **xlsx**, **data bars** and **color scales** become **native Excel\nconditional formatting** (`<conditionalFormatting>` rules) - Excel draws and\nrecomputes them itself, so they're interactive, not a static snapshot.\nPredicate `rule` formats stay as computed per-cell fills. In the other styled\nformats (`xls` / `html` / `pdf`) a data bar degrades to a light fill of the bar\ncolor (cells can't hold a partial-width bar). The data formats (csv / tsv /\njson / xml / md) are unstyled, so conditional formatting is ignored there.\nGrouped PDF exports skip conditional formatting (the group/subtotal rows own the\nlayout).\n\n### PDF options\n\nThe PDF is built from a full pdfmake document you control via `pdf`:\n\n```ts\nawait api.exportData({\n format: 'pdf',\n filename: 'orders',\n pdf: {\n pageSize: 'A4', // 'A4' | 'A3' | 'A5' | 'LETTER' | 'LEGAL'\n pageOrientation: 'landscape',\n title: 'Q3 Orders',\n subtitle: 'Generated by Ops',\n logo: logoDataUrl, // top-left image (data URL)\n headerColor: '#334155', // header row fill\n zebra: true, // striped rows\n columnWidths: '*', // '*' fill, 'auto', or a per-column pt array\n // repeatHeader (default true), showPageNumbers (default true) also available\n },\n})\n```\n\nThe header row repeats on every page, each page gets a `Page X of Y` +\ndate footer, per-column alignment is honored, and wide grids auto-switch to\nlandscape (override with `pdf.pageOrientation`).\n\nThe PDF looks like the grid it came from. With `pdf.matchTheme` (default\ntrue) the exporter reads the mounted grid's computed colours - header fill\nand text, body text, the zebra stripe, the lines, a group row's fill - so a\ngrid on the Ember theme or a Theme Builder palette prints in those colours\nrather than the slate defaults. A dark theme lends only its header: the\npage is white, so its body text and stripes would not read. The order of\nprecedence is explicit `pdf` colours (`headerColor`, `headerTextColor`,\n`textColor`, `zebraColor`, `borderColor`, `groupColor`, ...), then\n`styles`, then the theme, then the defaults. `styles.headerRow` /\n`styles.rows` / `styles.rowAlternate` / `styles.cells` (A1 references, row\n1 being the header) apply to the PDF table the way they do to xlsx and\nhtml, `header` / `footer` lines print above and below the table, and\n`merges` span data cells.\n\nWhen the grid is grouped, the PDF carries the grouping: a bold **group header**\nper cluster (nested for multi-level grouping) and a **subtotal row** summing the\nnumber / currency columns - matching the xlsx outline export. It's on by\ndefault (`autoGroup`); pass `groupBy` to override or `autoGroup: false` to get a\nflat table.\n\n#### Charts and a KPI strip\n\nA report is rarely just the table. `pdf.charts` prints charts with it: hand\nover the rendered chart's element (the `SvChart` wrapper or its `<svg>`) and\nthe export rasterises it at 2x through the chart's own PNG path, so the page\ngets the picture on screen, theme and all; or pass an image data URL you\nalready have. Each takes a `title`, a `caption` and a `width` in pt\n(default: the content width). `pdf.kpis` prints a strip of headline numbers\nabove the table, each with a label, the value and an optional `delta` line\nin its own colour:\n\n```svelte\n<div bind:this={chartEl}><SvChart {spec} /></div>\n\n<button onclick={() => api.exportData({\n format: 'pdf',\n filename: 'q3-report',\n pdf: {\n title: 'Q3 Orders',\n kpis: [\n { label: 'Revenue', value: '$1.24M', delta: '+4.2% vs Q2', color: '#16a34a' },\n { label: 'Orders', value: '842' },\n { label: 'Avg order', value: '$1,473', delta: '-1.1%', color: '#ef4444' },\n ],\n charts: [{ element: chartEl, title: 'Revenue by region', caption: 'Displayed rows, grouped by region' }],\n chartsPosition: 'above', // or 'below' the table\n },\n})}>Export report</button>\n```\n\nA chart block never splits across a page break. `resolvePdfCharts` and\n`buildPdfDocDefinition` are exported for a document you assemble yourself.\n\n#### Merged cells\n\nPass `merges` to write real merged regions into the sheet. Row / column\nindices are zero-based over the exported **body** (the header row is not\ncounted), and the shape lines up with the grid's own `MergeSpec`:\n\n```ts\n// Merge the first two data rows of column 0, and span a 3-column banner\nawait api.exportData({\n format: 'xlsx',\n merges: [\n { row: 0, col: 0, rowSpan: 2 }, // vertical merge (e.g. a repeated group key)\n { row: 5, col: 0, colSpan: 3 }, // horizontal merge (a section banner)\n ],\n})\n```\n\nTo export the merges you already show in the grid, take your `MergeSpec[]`\n(`{ rowIndex, columnId, rowspan, colspan }`) and map `columnId` to its column\nindex: `{ row: m.rowIndex, col: colIndex(m.columnId), rowSpan: m.rowspan, colSpan: m.colspan }`.\n\nThrows on missing peer (`jszip` / `pdfmake`), revoked / malformed\nlicense, or empty result set. With no license set, it runs but the\ngrid is watermarked.\n\n### `api.print(opts?)` - `Promise<void>`\n\nOpens a new window with a paginated, printable rendering of the grid and\ntriggers the browser print dialog. This is the **zero-dependency \"Save as PDF\"**\nroute: it uses the browser's own engine, so it has excellent font + CSS\nfidelity (including CJK / RTL) and needs no `pdfmake`. The header row repeats on\nevery page, values print **formatted** (matching the grid), and columns keep\ntheir alignment.\n\n| Option | Type | Default |\n| ------------- | -------------------------------------- | ----------- |\n| `title` | `string` | `\"Grid\"` |\n| `subtitle` | `string` | - |\n| `logo` | `string` (data URL) | - |\n| `columns` | `{ field; header?; format?; align? }[]`| grid's own columns |\n| `rows` | `ReadonlyArray<TData> \\| 'displayed' \\| 'selected' \\| 'all'` | `'displayed'` |\n| `rawValues` | `boolean` | `false` |\n| `orientation` | `'portrait' \\| 'landscape'` | `\"portrait\"` |\n| `pageSize` | `string` (e.g. `'A4'`, `'Letter'`) | browser default |\n| `margin` | `string` (e.g. `'14mm'`) | `'14mm'` |\n| `zebra` | `boolean` | `true` |\n| `headerColor` | `string` | `'#f1f5f9'` |\n\nBrowsers may block the popup unless `print()` is called from a user\ngesture (a click handler is fine - automatic on-load print is not). Page\nnumbers come from the browser's own print header/footer.\n\n**`exportData({ format: 'pdf' })` vs `print()`** - use PDF export for a\nprogrammatic, silent file download with full layout control (see \"PDF\noptions\"); use `print()` when you want best-fidelity output and the user to\npick print or \"Save as PDF\" from the dialog.\n\n## Drop-in Export menu (`SvExportMenu`)\n\nRather than wiring your own toolbar, drop in the bundled `SvExportMenu`\ncomponent. It renders an \"Export\" button with a format picker, a row-scope\ntoggle (current view / selected / all), and a built-in progress bar + Cancel\nfor large exports:\n\n```svelte\n<script lang=\"ts\">\n import { SvGrid, type SvGridApi } from '@svgrid/grid'\n import { installEnterprise, SvExportMenu, type EnterpriseGridApi } from '@svgrid/enterprise'\n\n let api = $state<EnterpriseGridApi<typeof features, Order> | null>(null)\n</script>\n\n<div class=\"toolbar\">\n <SvExportMenu {api} filename=\"orders\" />\n</div>\n\n<SvGrid data={rows} columns={columns} features={features}\n onApiReady={(a) => (api = installEnterprise(a))} />\n```\n\n| Prop | Type | Default | Notes |\n| ------------ | ------------------------------------------------ | --------------------------- | ----- |\n| `api` | `EnterpriseGridApi \\| null` | required | Button is disabled until the api is ready. |\n| `filename` | `string` | `'grid'` | Base name, no extension. |\n| `formats` | `ExportFormat[]` | xlsx/xls/pdf/csv/tsv/html | Which formats to offer, in order. |\n| `allowScope` | `boolean` | `true` | Show the current-view / selected / all toggle. |\n| `allowColumns` | `boolean` | `true` | Show per-column include checkboxes (choose which columns to export). |\n| `allowCopy` | `boolean` | `true` | Show \"Copy for Excel\" (tsv) + \"Copy Markdown\" clipboard actions. |\n| `allowPrint` | `boolean` | `false` | Show a \"Print…\" action (`api.print`). |\n| `scope` | `'displayed' \\| 'selected' \\| 'all'` | `'displayed'` | Initial row scope. |\n| `label` | `string` | `'Export'` | Button text. |\n| `conditionalFormats` | `ConditionalFormat[]` | - | Carried into pdf / xlsx / html exports. |\n\nThe menu is sectioned into **Rows** (scope), **Columns** (a picker), and\n**Download** (each format shown with an icon + one-line description), plus\n**copy-to-clipboard** and optional **print** actions. It's **keyboard\naccessible** (arrow keys move between items, Tab is trapped inside, Esc closes\nand returns focus to the button, with `role=\"menu\"` / `menuitem`), handles\nerrors inline (missing peer dependency, empty grid), and wires `onProgress` +\nan `AbortController` for you.\n\nFor large exports, the single-sheet xlsx writer builds in **chunks that yield to\nthe event loop** (and zips asynchronously), so the tab stays responsive and\n`onProgress` ticks; pass a `signal` to cancel.\n\n## Gotchas\n\n- **Empty grids** - both `exportData` and `print` throw if there are no\n displayed rows. Catch the error and show a notice in the UI.\n- **Column ordering** - if you don't pass `columns`, the export uses\n `Object.keys(rows[0])` order. Pass `columns` explicitly when the row\n shape doesn't match the column order you want.\n- **Cell formatters** - column-level format hints (date, number, currency,\n percent) are applied to the exported value by default, so the file matches\n the grid. Custom snippet renderers are **not** auto-serialized - give those\n columns an `exportValue` hook (see \"Faithful values\" above), or set\n `rawValues: true` if you want the raw underlying values.\n- **Print popup blocked** - `print()` resolves but the browser silently\n blocks the new window. Always trigger from a user click, and surface\n the thrown error.\n- **Bundle size** - the vendored exporter is ~50 KB minified. It is\n loaded lazily on first call so it does not bloat the initial bundle\n for users who never export.\n\n## Frequently asked questions\n\n### How do I export a Svelte data grid to Excel?\n\nInstall `@svgrid/enterprise`, call `installEnterprise(api)`, then call the export helper with\n`format: 'xlsx'`. The exporter writes a real OOXML workbook in the browser - no\nserver round-trip. CSV, TSV, PDF, and HTML use the same call with a different\nformat.\n\n### What's the difference between `xls` and `xlsx`?\n\n`xlsx` is the modern OOXML workbook (Excel 2007+); it needs the `jszip` peer\ndependency and supports the richest output (styles, images, multi-sheet,\nformulas). `xls` is the **legacy Excel 2003 XML Spreadsheet** format: pick it\nfor maximum compatibility with old Excel installs or systems that only accept\n`.xls`. It has **no peer dependency**, streams in the browser, and keeps\nnumbers and dates typed (so sums and sorting still work in Excel) with number\nformats applied. It's single-sheet - use `xlsx` for multi-tab workbooks.\n\n```ts\nawait api.exportData({ format: 'xls', filename: 'orders' })\n```\n\n### Is export part of the free Community package?\n\nNo. Export and printing ship in the paid `@svgrid/enterprise` add-on. The free\n`@svgrid/grid` package covers the full grid (sorting, filtering, grouping,\nediting, virtualization) but not export/print/pivot/import.\n\n### Does exporting bloat my bundle?\n\nNo. The ~50 KB exporter is lazy-loaded on the first export call, so users who\nnever export never download it.\n\n## More examples\n\n### Password-protected export\n\nPBKDF2 (100k iters) + AES-GCM 256 client-side. Strength meter, encrypt + download, in-page decrypt tool to verify the round-trip. Enterprise pack maps to ECMA-376 Agile encryption.\n\n<div data-docs-demo=\"93-password-protected-export\" data-height=\"460\"></div>\n\n### Formulas preserved in xlsx\n\nBuilds a real OOXML workbook in the browser via JSZip; computed columns export as <f>...</f> formula cells. Open in Excel and the math recomputes when you edit a number.\n\n<div data-docs-demo=\"101-formulas-in-xlsx\" data-height=\"460\"></div>\n\n### Export grouped grid to Excel\n\nA flat sales grid (Region → Country) exported via api.exportData({ format: \"xlsx\", groupBy }) which uses Smart's NATIVE Excel row outline grouping. Opens in Excel with +/- buttons in the row header gutter for every group level.\n\n<div data-docs-demo=\"126-export-grouped-grid\" data-height=\"460\"></div>\n\n### Export pivot grid to Excel\n\ncreatePivotModel leaves projected into an xlsx via api.exportData with groupBy: [\"region\"] - each region becomes an Excel outline group. Engine column ids (\"pv__Q1__m0\") translate to readable headers (\"Q1 · Revenue\").\n\n<div data-docs-demo=\"127-export-pivot-grid\" data-height=\"460\"></div>\n\n### Export - Formatting, scope + XLS\n\nFaithful export: currency / date / percent render as shown (toggle raw values), pick a row scope (view / selected / all), legacy .xls (Excel 2003 XML, no jszip), an exportValue hook, and the drop-in SvExportMenu.\n\n<div data-docs-demo=\"201-export-formatting-and-xls\" data-height=\"460\"></div>\n\n### Export - Grouped PDF + Print\n\nGroup the grid and export: the PDF + xlsx carry bold group headers and per-cluster subtotal rows (auto-carried from grouping state). Polished Print is the zero-dependency \"Save as PDF\" route with a repeated header and title.\n\n<div data-docs-demo=\"202-export-pdf-grouped-and-print\" data-height=\"460\"></div>\n\n## Try the export API\n\nEvery exporter is on the grid api and takes the same\n`GridExportOptions`. `rows: 'displayed'` is the default and is almost always\nwhat a user means by \"export this\" - it follows their filter and sort.\n\n```svelte\n<script lang=\"ts\">\n let api = $state<SvGridApi<{}, Person> | null>(null)\n</script>\n\n<div>\n <button type=\"button\" onclick={() => api?.exportCsv({ filename: 'people' })}>CSV</button>\n <button type=\"button\" onclick={() => api?.exportTsv({ filename: 'people' })}>TSV</button>\n <button type=\"button\" onclick={() => api?.exportJson({ filename: 'people' })}>JSON</button>\n <button type=\"button\" onclick={() => api?.print()}>Print</button>\n</div>\n\n<SvGrid data={people} {columns} sortable filterable onApiReady={(next) => (api = next)} />\n```\n\nSort or filter first, then export: the file follows the view.\n\n## Exporting a subset\n\n`columns` restricts the fields and fixes their order, and `rawValues` decides\nwhether the file carries what the screen shows or what the row holds. The\nsalary column is the one to watch - formatted it is `$142,000`, raw it is\n`142000`, and a spreadsheet can only do arithmetic on the second.\n\n```svelte\n<script lang=\"ts\">\n let api = $state<SvGridApi<{}, Person> | null>(null)\n</script>\n\n<div>\n <button type=\"button\" onclick={() => api?.exportCsv({ filename: 'formatted', columns: ['name', 'salary'] })}>\n Name + salary, as displayed\n </button>\n <button type=\"button\" onclick={() => api?.exportCsv({ filename: 'raw', columns: ['name', 'salary'], rawValues: true })}>\n Name + salary, raw values\n </button>\n</div>\n\n<SvGrid data={people} {columns} onApiReady={(next) => (api = next)} />\n```\n"
|
|
4486
4486
|
},
|
|
4487
4487
|
{
|
|
4488
4488
|
"slug": "help/export/import-spreadsheet",
|
|
@@ -4587,7 +4587,7 @@ export const docs = [
|
|
|
4587
4587
|
"path": "docs/help/glossary.md",
|
|
4588
4588
|
"title": "Glossary",
|
|
4589
4589
|
"section": "Help",
|
|
4590
|
-
"markdown": "# Glossary\n\nTerminology used across the docs and the source. Sorted A-Z. If a term\nis unclear in a topic page and isn't on this list, please file an\nissue.\n\n## A\n\n**Accessor.** How a column gets its value out of a row. There are two\nforms: `field`, a key on the row (`row[field]`, no dot paths), and\n`fieldFn`, a function that computes the value. `getValue()` applies\nwhichever the column declares. Reach for `fieldFn` when the value is\nnested or derived - it is what pivot tables and computed columns use,\nand a `fieldFn` column needs an explicit `id`, since there is no\n`field` to name it after.\n\n**Active cell.** The cell with focus. Tracked through every keyboard\nmove + click; exposed via `onActiveCellChange`. At most one cell is\nactive per grid. Has `tabindex=\"0\"`; every other cell has\n`tabindex=\"-1\"` (roving-tabindex pattern).\n\n**Aggregator.** A function that reduces a group's values to a single\ncell value (sum, avg, count, min, max, custom). Used by\n`columnGroupingFeature` and the pivot engine.\n\n**API (`SvGridApi`).** The imperative interface exposed via\n`<SvGrid onApiReady>`. Methods like `setSort`, `setFilter`, `addRow`,\n`getDisplayedRows`. See [API reference](https://svgrid.com/api/).\n\n## C\n\n**Cell context.** The `ctx` object passed to `cell`, `editable`, and\n`formatter` callbacks. Contains `cell`, `row`, `column`, `table`,\n`getValue`. Used inside custom cell snippets to access surrounding\nstate.\n\n**Column definition (`ColumnDef`).** The plain object that describes\none column: how to read its value (`field` / `fieldFn`), how to\nrender it (`cell`, `header`), and which features apply (`editable`,\n`format`, `editorType`). See [Column definitions](./columns/column-definitions.md).\n\n**Column group.** A `ColumnDef` whose `columns` array contains child\ncolumn defs. The grid emits one header row per nesting depth with\nproper `colSpan`. See [Column groups](./columns/column-groups.md).\n\n**Controlled vs uncontrolled state.** *Controlled*: the consumer owns\nthe state (a `$state` in your component) and listens to change events.\n*Uncontrolled*: the engine owns the state internally. Most grid state\nis uncontrollable-by-default; opt in via the `onXxxChange` props.\n\n## D\n\n**Density.** The vertical compaction of rows. Controlled by the\n`rowHeight` prop (not a CSS token - the virtualizer needs the height as\na number). Default is 30 px; 28 px is \"compact\", 48 px is \"loose\".\n\n**Display rows.** The rows the grid is currently showing AFTER the\npipeline runs (filter -> sort -> group -> page). Accessible via\n`api.getDisplayedRows()`. NOT the same as the raw `data` prop.\n\n## E\n\n**Editor type.** A string on the `ColumnDef` that picks which built-in\neditor the grid uses when a user edits the cell. Values:\n`'text'` / `'number'` / `'date'` / `'datetime'` / `'checkbox'` /\n`'list'` / `'chips'`. A column without `editorType` is read-only even\nwhen `enableInlineEditing` is true.\n\n**Engine.** Layer 2 in the [architecture](./architecture.md). The\npure-function row-and-column model pipeline. Lives in\n`packages/grid/src/core.ts` + the `row-models/` folder.\n\n## F\n\n**Feature.** A bundle of row-model + state + behaviour you register\nvia `tableFeatures({...})`. Examples: `rowSortingFeature`,\n`columnFilteringFeature`. Features compose - registering five of them\nis normal.\n\n**Field.** The row property a column reads + writes by default. A\nshortcut for `fieldFn: (row) => row[field]`. When you can use\n`field`, prefer it - the engine has a fast path for property-keyed\ncolumns.\n\n**Filter mode.** A single prop on `<SvGrid>` that picks which filter\nUI the grid renders: `'menu'` (icon in each header), `'row'` (input\nunder each header), `'global'` (one search box), or `'none'`.\n\n**Format / formatter.** `format` is a declarative config (`{ type:\n'currency', currency: 'USD' }`) that the grid hands to `Intl`.\n`formatter` is a free-form callback that returns a string. Use\n`format` for standard types; `formatter` for custom output.\n\n## G\n\n**Group by.** A list of column ids whose unique values become rollup\ngroup rows. Set via `api.setGroupBy([...])` or the column menu's \"Group\nby this column\" entry. Drives `columnGroupingFeature`.\n\n## H\n\n**Header context.** The `ctx` object passed to `header` and `footer`\ntemplates. Contains `header`, `column`, `table`. Used inside custom\nheader snippets.\n\n**Headless.** Layer 2 without the renderer. `createSvGrid(...)`\nreturns a headless instance that emits the same row model + state but\ndoesn't paint anything. See [Why headless?](../why-headless.md).\n\n## I\n\n**Imperative API.** See *API (`SvGridApi`)*.\n\n**Inline editing.** Editing that happens inside the cell itself, vs\nin a side form. Toggled via `enableInlineEditing` on `<SvGrid>` +\n`editorType` on each column.\n\n## L\n\n**Layer 1, 2, 3.** See [Architecture overview](./architecture.md).\nLayer 1 is your data; Layer 2 is the engine; Layer 3 is the\n`<SvGrid>` renderer.\n\n**License key.**
|
|
4590
|
+
"markdown": "# Glossary\n\nTerminology used across the docs and the source. Sorted A-Z. If a term\nis unclear in a topic page and isn't on this list, please file an\nissue.\n\n## A\n\n**Accessor.** How a column gets its value out of a row. There are two\nforms: `field`, a key on the row (`row[field]`, no dot paths), and\n`fieldFn`, a function that computes the value. `getValue()` applies\nwhichever the column declares. Reach for `fieldFn` when the value is\nnested or derived - it is what pivot tables and computed columns use,\nand a `fieldFn` column needs an explicit `id`, since there is no\n`field` to name it after.\n\n**Active cell.** The cell with focus. Tracked through every keyboard\nmove + click; exposed via `onActiveCellChange`. At most one cell is\nactive per grid. Has `tabindex=\"0\"`; every other cell has\n`tabindex=\"-1\"` (roving-tabindex pattern).\n\n**Aggregator.** A function that reduces a group's values to a single\ncell value (sum, avg, count, min, max, custom). Used by\n`columnGroupingFeature` and the pivot engine.\n\n**API (`SvGridApi`).** The imperative interface exposed via\n`<SvGrid onApiReady>`. Methods like `setSort`, `setFilter`, `addRow`,\n`getDisplayedRows`. See [API reference](https://svgrid.com/api/).\n\n## C\n\n**Cell context.** The `ctx` object passed to `cell`, `editable`, and\n`formatter` callbacks. Contains `cell`, `row`, `column`, `table`,\n`getValue`. Used inside custom cell snippets to access surrounding\nstate.\n\n**Column definition (`ColumnDef`).** The plain object that describes\none column: how to read its value (`field` / `fieldFn`), how to\nrender it (`cell`, `header`), and which features apply (`editable`,\n`format`, `editorType`). See [Column definitions](./columns/column-definitions.md).\n\n**Column group.** A `ColumnDef` whose `columns` array contains child\ncolumn defs. The grid emits one header row per nesting depth with\nproper `colSpan`. See [Column groups](./columns/column-groups.md).\n\n**Controlled vs uncontrolled state.** *Controlled*: the consumer owns\nthe state (a `$state` in your component) and listens to change events.\n*Uncontrolled*: the engine owns the state internally. Most grid state\nis uncontrollable-by-default; opt in via the `onXxxChange` props.\n\n## D\n\n**Density.** The vertical compaction of rows. Controlled by the\n`rowHeight` prop (not a CSS token - the virtualizer needs the height as\na number). Default is 30 px; 28 px is \"compact\", 48 px is \"loose\".\n\n**Display rows.** The rows the grid is currently showing AFTER the\npipeline runs (filter -> sort -> group -> page). Accessible via\n`api.getDisplayedRows()`. NOT the same as the raw `data` prop.\n\n## E\n\n**Editor type.** A string on the `ColumnDef` that picks which built-in\neditor the grid uses when a user edits the cell. Values:\n`'text'` / `'number'` / `'date'` / `'datetime'` / `'checkbox'` /\n`'list'` / `'chips'`. A column without `editorType` is read-only even\nwhen `enableInlineEditing` is true.\n\n**Engine.** Layer 2 in the [architecture](./architecture.md). The\npure-function row-and-column model pipeline. Lives in\n`packages/grid/src/core.ts` + the `row-models/` folder.\n\n## F\n\n**Feature.** A bundle of row-model + state + behaviour you register\nvia `tableFeatures({...})`. Examples: `rowSortingFeature`,\n`columnFilteringFeature`. Features compose - registering five of them\nis normal.\n\n**Field.** The row property a column reads + writes by default. A\nshortcut for `fieldFn: (row) => row[field]`. When you can use\n`field`, prefer it - the engine has a fast path for property-keyed\ncolumns.\n\n**Filter mode.** A single prop on `<SvGrid>` that picks which filter\nUI the grid renders: `'menu'` (icon in each header), `'row'` (input\nunder each header), `'global'` (one search box), or `'none'`.\n\n**Format / formatter.** `format` is a declarative config (`{ type:\n'currency', currency: 'USD' }`) that the grid hands to `Intl`.\n`formatter` is a free-form callback that returns a string. Use\n`format` for standard types; `formatter` for custom output.\n\n## G\n\n**Group by.** A list of column ids whose unique values become rollup\ngroup rows. Set via `api.setGroupBy([...])` or the column menu's \"Group\nby this column\" entry. Drives `columnGroupingFeature`.\n\n## H\n\n**Header context.** The `ctx` object passed to `header` and `footer`\ntemplates. Contains `header`, `column`, `table`. Used inside custom\nheader snippets.\n\n**Headless.** Layer 2 without the renderer. `createSvGrid(...)`\nreturns a headless instance that emits the same row model + state but\ndoesn't paint anything. See [Why headless?](../why-headless.md).\n\n## I\n\n**Imperative API.** See *API (`SvGridApi`)*.\n\n**Inline editing.** Editing that happens inside the cell itself, vs\nin a side form. Toggled via `enableInlineEditing` on `<SvGrid>` +\n`editorType` on each column.\n\n## L\n\n**Layer 1, 2, 3.** See [Architecture overview](./architecture.md).\nLayer 1 is your data; Layer 2 is the engine; Layer 3 is the\n`<SvGrid>` renderer.\n\n**License key.** The key from your `@svgrid/enterprise` order email, set via\n`setLicenseKey(...)`. Removes the unlicensed watermark + console\nnudge. See [API stability](./api-stability.md) for license-related\nerrors.\n\n## P\n\n**Pinned column.** A column sticky-positioned to the left or right\nedge while the rest scroll. Set via the column menu, the\n`initialColumnPinning` prop, or\n`api.setColumnPinning({ left: [...], right: [...] })`.\n\n**Pipeline.** The chain of row-model transformations: core ->\nfiltered -> sorted -> grouped -> expanded -> paginated. Runs once per\nstate change, NOT per scroll frame.\n\n**Pivot.** A reshape of facts into a grid of intersections - row\ndimensions cross column dimensions, with measures (aggregated values)\nat each intersection. SvGrid doesn't have a `pivot` prop; the pivot\nengine in [pivot.md](./pivot.md) builds the pivoted data + nested\nColumnDef tree the renderer needs.\n\n**Placeholder row.** A frozen \"stand-in\" row used by sparse infinite\nscroll. Renders skeleton cells until the real row loads. See\n[Server-side data](./server-side-data.md).\n\n**Enterprise.** The paid `@svgrid/enterprise` companion package adding export,\nimport, print, pivot helpers, and the AI assistant. Installed\nseparately; activated by `installEnterprise(api)`.\n\n## R\n\n**Render template.** A `cell` / `header` / `footer` value that\nreturns a Svelte snippet via `renderSnippet(SnippetRef, props)`. The\ngrid mounts the snippet inside the cell.\n\n**Roving tabindex.** The pattern of giving only the active cell\n`tabindex=\"0\"` while every other cell has `tabindex=\"-1\"`. Puts the\ngrid in the tab order exactly once. See\n[Accessibility](./accessibility.md).\n\n**Row data.** The `data` prop. Anything assignable to `RowData[]`\n(which is `Record<string, unknown>[]`). Plain objects; the grid never\nintrospects beyond `field` reads.\n\n**Row model.** A pipeline stage that takes rows in and emits rows\nout. Examples: `createSortedRowModel`, `createFilteredRowModel`. Pipe\nthem in via `tableFeatures(...)`. See [Architecture](./architecture.md).\n\n## S\n\n**Selection range.** A rectangular cell selection (anchor + focus\ncells), enabled by `enableCellSelection={true}`. Copy + paste (TSV)\nand the fill handle both operate on this range.\n\n**Snippet.** A Svelte 5 `{#snippet Foo(props)}` block. Used by the\ngrid as the render template format for cells, headers, and editors.\n`renderSnippet(Foo, props)` is the wrapper the column passes to\n`cell`.\n\n**Evaluation period.** The Enterprise package without a license key:\nevery feature still runs, and loading the module displays a small\nwatermark and a console message about the Enterprise package. No key is\nneeded to evaluate; a license key removes them\n(`setLicenseKey('YOUR-LICENSE-KEY')`).\n\n## T\n\n**Table features.** The bag returned by `tableFeatures({...})` -\na typed object identifying which row models + state slices the grid\nshould enable. Pass to `<SvGrid features={...}>` and use as the first\ngeneric of `ColumnDef<...>`.\n\n**Tree row.** A row with a `depth` field + `childIds` (or\nequivalent). Renders with indented chevron + connector lines. The grid\ndoesn't have a `treeData` prop; you derive `visibleRows` from\n`allRows` + `expanded`. See [Tree rows](./rows/tree-rows.md).\n\n## V\n\n**Virtualization.** Rendering only the rows + columns currently in\nview + a small overscan buffer. Enabled by default for any grid with\nmore than a few hundred rows. Bypassed in jsdom (zero layout metrics)\n- test against Playwright for virtualization behaviour.\n\n**Visible rows.** Same as *Display rows*.\n\n## W\n\n**Watermark.** The \"Unlicensed @svgrid/enterprise\" badge that appears\nbottom-right when a Enterprise feature runs without a valid license. Removed\nby `setLicenseKey('YOUR-LICENSE-KEY')` or `dismissUnlicensedNudge()` (the\nnudge only).\n\n## See also\n\n- [Architecture overview](./architecture.md) - where each piece\n above sits.\n- [API reference](https://svgrid.com/api/) - every export with its tier\n badge.\n"
|
|
4591
4591
|
},
|
|
4592
4592
|
{
|
|
4593
4593
|
"slug": "help/grouping-aggregation",
|
|
@@ -4699,140 +4699,140 @@ export const docs = [
|
|
|
4699
4699
|
"path": "docs/help/mcp-server.md",
|
|
4700
4700
|
"title": "MCP server",
|
|
4701
4701
|
"section": "Help",
|
|
4702
|
-
"markdown": "# MCP server\n\nThe SvGrid MCP server does two things for an AI client (Claude Code,\nClaude Desktop, Cursor, Zed, Codex, custom agents): it answers questions\nabout SvGrid from the files this repository ships, and it **checks the\ncode the model writes** against the real exported surface of the version\nyou have installed. No API key either way.\n\n\n\n> **What is MCP?** Model Context Protocol is the open standard\n> ([modelcontextprotocol.io](https://modelcontextprotocol.io)) for\n> exposing tools to LLM clients. SvGrid ships an MCP server so the\n> model your team already uses can \"see\" the grid without you having\n> to copy-paste docs into prompts.\n\nIt runs either way you like: as a local process\n([`@svgrid/mcp`](https://www.npmjs.com/package/@svgrid/mcp) on npm), or as\na hosted endpoint at `https://mcp.svgrid.com/mcp` that needs no install at\nall. Both are listed in the official MCP registry as `com.svgrid/svgrid`.\n\n## Two ways to connect\n\n**Hosted (nothing to install).** Point any MCP client at the URL:\n\n```\nhttps://mcp.svgrid.com/mcp\n```\n\n```bash\nclaude mcp add --transport http svgrid https://mcp.svgrid.com/mcp\n```\n\nOne click:\n[Add to Cursor](https://cursor.com/en/install-mcp?name=svgrid&config=eyJ1cmwiOiJodHRwczovL21jcC5zdmdyaWQuY29tL21jcCJ9)\n· [Add to VS Code](https://insiders.vscode.dev/redirect/mcp/install?name=svgrid&config=%7B%22name%22%3A%22svgrid%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fmcp.svgrid.com%2Fmcp%22%7D)\n\nIt carries six tools - `search`, `fetch`, `list_examples`,\n`get_example_source`, `get_api_reference` and `check_svgrid_code` - and\nneeds no Node, no config file, and no key.\n\n**Local (`npx @svgrid/mcp`).** Everything the hosted server has, plus\nthe Studio tools, the docs and demos as MCP resources, ready-made\nprompts, and a `svgrid_check_code` that additionally *compiles* the file\nwith the Svelte compiler rather than checking it statically. Use it when\nyou want the compile pass, the Studio tools, or no third-party endpoint\nin the loop.\n\n| | Hosted | Local |\n| --- | --- | --- |\n| Setup | a URL | `npx @svgrid/mcp` |\n| Needs Node | no | yes |\n| Code check compiles | no, static checks only | yes |\n| Resources and prompts | yes | yes |\n| Visual preview | yes | yes |\n| `studio_*` tools | no | yes, opt-in |\n| Works offline | no | yes |\n\n## Install\n\nNo install step is required - `npx` fetches it on demand:\n\n```bash\n# One-shot, from any project\nnpx -y @svgrid/mcp\n```\n\nTo pin it as a dev dependency instead:\n\n```bash\npnpm add -D @svgrid/mcp\n```\n\nThe local server is a Node binary (`svgrid-mcp`) that speaks MCP over\nstdio. There is no daemon to maintain. The hosted server needs no install\nstep at all - skip to [Wire it into your AI client](#wire-it-into-your-ai-client)\nand use the URL.\n\n## Wire it into your AI client\n\nEvery snippet below shows the local (stdio) form and the hosted (HTTP)\nform. Pick one - running both connects the same tools twice.\n\n### Claude Code\n\nThe plugin is the shortest path: it installs the\n[Agent Skill](./skill.md) and the hosted server together, so the model\ngets the house style *and* the checker in one step.\n\n```\n/plugin marketplace add sv-grid/sv-grid\n/plugin install svgrid@svgrid\n```\n\nOr add the server on its own:\n\n```bash\n# hosted, nothing to install\nclaude mcp add --transport http svgrid https://mcp.svgrid.com/mcp\n\n# or local\nclaude mcp add svgrid -- npx -y @svgrid/mcp\n```\n\nThen run `/mcp` in a session and you will see `svgrid` listed.\n\nTo share the server with your team, add `--scope project`. That writes\na `.mcp.json` at the repository root which you can commit, so everyone\nwho clones the repo gets the same tooling with no per-machine setup:\n\n```bash\nclaude mcp add svgrid --scope project -- npx -y @svgrid/mcp\n```\n\n### Claude Desktop\n\nEdit `~/Library/Application Support/Claude/claude_desktop_config.json`\n(macOS) or `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows):\n\n```json\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@svgrid/mcp\"]\n }\n }\n}\n```\n\nOr the hosted server, with nothing to install:\n\n```json\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"type\": \"http\",\n \"url\": \"https://mcp.svgrid.com/mcp\"\n }\n }\n}\n```\n\nRestart Claude Desktop, then ask *\"using svgrid, build me a grid that\ngroups by department\"* to confirm the tools are exposed.\n\n### Cursor\n\nOne click:\n[Add to Cursor](https://cursor.com/en/install-mcp?name=svgrid&config=eyJ1cmwiOiJodHRwczovL21jcC5zdmdyaWQuY29tL21jcCJ9)\n\nOr by hand, in `Settings -> MCP -> Add new MCP server`:\n\n```json\n{ \"url\": \"https://mcp.svgrid.com/mcp\" }\n```\n\n```json\n{ \"command\": \"npx\", \"args\": [\"-y\", \"@svgrid/mcp\"] }\n```\n\n### Zed\n\n`~/.config/zed/settings.json`:\n\n```json\n{\n \"context_servers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@svgrid/mcp\"],\n \"env\": {}\n }\n }\n}\n```\n\n### VS Code\n\nOne click:\n[Add to VS Code](https://insiders.vscode.dev/redirect/mcp/install?name=svgrid&config=%7B%22name%22%3A%22svgrid%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fmcp.svgrid.com%2Fmcp%22%7D)\n\nOr create `.vscode/mcp.json` in the workspace. Note that VS Code uses\n`servers` rather than the `mcpServers` wrapper:\n\n```json\n{\n \"servers\": {\n \"svgrid\": {\n \"type\": \"http\",\n \"url\": \"https://mcp.svgrid.com/mcp\"\n }\n }\n}\n```\n\n```json\n{\n \"servers\": {\n \"svgrid\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@svgrid/mcp\"]\n }\n }\n}\n```\n\n### Custom agents (OpenAI Agents SDK, Anthropic SDK, LangChain)\n\nPoint your client's MCP stdio transport at `npx -y @svgrid/mcp`, or its\nstreamable-HTTP transport at `https://mcp.svgrid.com/mcp`. Any client that\nspeaks either transport works.\n\nThe hosted server names its two retrieval tools `search` and `fetch`\nexactly, which is what a connector needs to index it.\n\n## Tools exposed\n\nFour, by default. `tools/list` is sent on **every** request, so the tool\nsurface is pure overhead on every turn - and this server used to spend\n~4,710 tokens of it on 36 tools, 79% of them Studio tools that most\nsessions never call once.\n\n| Tool | What it does |\n| ---- | ------------ |\n| `svgrid_search` | Search the docs, the 375 demos and the API surface **in one call**. No arguments returns an index. |\n| `svgrid_get` | Read one thing in full: a doc slug, a demo id, or `api`. |\n| `svgrid_check_code` | Verify code against the real exported surface before the user sees it. |\n| `svgrid_preview` | Render a **live, interactive grid** in the conversation from columns + rows. |\n| `svgrid_scaffold` | Turn a Drizzle schema, sample rows or an EntitySchema into runnable SvelteKit files. |\n\nStudio adds four more, and only when you ask for them - set\n`SVGRID_MCP_STUDIO=1` or a licence key in the server's env. They need a\nlicence to be useful, so they are not charged to everyone else's context\nwindow.\n\nThe **hosted** server carries `search`, `fetch`, `list_examples`,\n`get_example_source`, `get_api_reference`, `check_svgrid_code` and\n`svgrid_preview`, plus the same resources and prompts. The first two are named\nthat way deliberately: those exact names are what a one-click connector needs to\nindex a remote server. It also answers to `svgrid_search`, `svgrid_get` and\n`svgrid_check_code`, so a model that learned the npm package's names is never\ntold \"unknown tool\".\n\nWhat it does **not** have is the compile pass (the Svelte compiler cannot run in\na Worker), the Studio tools (they need a filesystem), and the offline guarantee\n- it is a remote server, so by definition your query reaches it. Use the local\none when any of those matter.\n\n### Verification\n\n#### `svgrid_check_code`\n\nChecks a file **against the version you have installed** and returns\nline-numbered diagnostics with the exact replacement for each: unknown\n`<SvGrid>` props, wrong `ColumnDef` keys, api methods that do not\nexist, imports that will not resolve, and Svelte 5 runes mistakes. It\nalso compiles the component, so a syntax error surfaces here rather\nthan in the user's terminal.\n\nThis is the tool that makes the rest worth having. Retrieval alone\nstill lets a model write a confident, wrong grid; nothing else in the\nserver stops it. Run it on every file you write, fix what it reports,\nand run it again.\n\n### Finding and reading\n\n#### `svgrid_search`\n\nOne call across all three corpora, because \"how do I pin a column\" does\nnot announce whether it is answered by a doc page, a demo, or an API\nname:\n\n```json\n{ \"query\": \"pin a column\" }\n```\n\nReturns ranked doc hits with excerpts, matching demos, and matching API\nnames - each with the reference you pass to `svgrid_get`. Narrow with\n`kind` (`docs` | `examples` | `api`), trade tokens for completeness\nwith `detail` (`concise` | `full`), and cap with `limit` (max 50).\n\nCall it with **no arguments** for an index of doc sections, demo\ncategories and API groups - the cheapest way to orient before searching.\n\n#### `svgrid_get`\n\n```json\n{ \"ref\": \"help/columns/column-definitions\" }\n{ \"ref\": \"11-stock-market\" }\n{ \"ref\": \"api\" }\n```\n\nThe kind is inferred from the reference; pass `kind` to force it. A\nreference that does not resolve comes back with near matches rather\nthan a bare \"not found\".\n\n### It fixes what it finds\n\n`svgrid_check_code` does not stop at telling you what is wrong. Where the\ncorrection is exact it returns the corrected file too:\n\n```json\n{\n \"diagnostics\": [ ... ],\n \"applied\": [\"rowData -> data (line 7)\", \"accessorKey -> field (line 3)\"],\n \"fixed\": \"<the corrected source>\"\n}\n```\n\nBoth fields are omitted when there is nothing mechanically fixable, so a clean\ncheck stays small.\n\nThe rules are deliberately narrow, because this tool's whole worth is that it\nnever cries wolf - and rewriting raises the stakes from wasting a turn to\ncorrupting working code. Only exact renames are applied (a known rename, or a\nclose-enough spelling), only on word boundaries, and only on the line the\ndiagnostic reported. Advice that is ambiguous - \"this has no equivalent, remove\nit\" - stays advice. A test asserts that running auto-fix across all 367 demos\nin this repository changes nothing at all.\n\n### It knows which version you have\n\nThe result carries the version it checked against:\n\n```json\n{ \"version\": { \"corpus\": \"3.0.0\", \"installed\": \"2.6.8\", \"warning\": \"...\" } }\n```\n\nThe server reads the `@svgrid/grid` in your project and says plainly when it\ndisagrees with the corpus it ships, so a model is told to hedge instead of\nconfidently citing an API you do not have. A server that answers from a remote\nbackend cannot do this - it has no idea what is in your `node_modules`.\n\n### Nothing leaves your machine\n\nThis server makes **no network calls**. Not for docs, not for the API surface,\nnot for verification - the whole corpus (375 demos, 408 doc pages, the full\nexported API) ships inside the package, which is why it is 8 MB rather than\n90 KB. There is no API key, no licence check on the wire, and no telemetry.\n\nIt works on a plane, behind a corporate proxy, and inside an air-gapped\nnetwork. `tools/mcp-offline.test.ts` enforces it: the server is driven through\na full session with every network primitive booby-trapped, and the test fails if\nanything is even attempted.\n\nThe one honest exception: the **preview** loads the grid from a CDN to draw it.\nThat happens in your client's sandboxed iframe, never in this server, and only\nwhen you actually render a preview.\n\n### Seeing the grid, not just reading about it\n\n`svgrid_preview` renders a **real, interactive SvGrid inside the\nconversation** - sortable, filterable, scrollable. Not a screenshot and not a\nmock table: the same `<sv-grid>` custom element a page would use, loaded from\nthe CDN, with the columns and rows you passed.\n\n```json\n{\n \"title\": \"Team roster\",\n \"columns\": [{ \"field\": \"name\", \"header\": \"Name\" }, { \"field\": \"amount\", \"header\": \"Amount\" }],\n \"data\": [{ \"name\": \"Ada\", \"amount\": 20000 }],\n \"sortable\": true\n}\n```\n\nIt uses [MCP Apps](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/),\nthe official UI extension: the tool points at a `ui://` resource through\n`_meta`, the client loads that HTML in a sandboxed iframe, and the tool's\n`structuredContent` arrives over a postMessage bridge. Supported in Claude\n(web and desktop), VS Code and ChatGPT.\n\nClients without UI support are not left out - they ignore the `_meta` and get\na text summary of the same grid, so it is always safe to call. That is the\nextension's own rule, and it is why the text half describes the grid rather\nthan pointing at a picture the reader cannot see.\n\nPass `demo` instead of `columns` / `data` and you get the demo's source: a\ndemo is a Svelte component, not data, so there is nothing to hand the element\nand rendering an empty grid would just look broken.\n\n### Resources and prompts\n\nThe docs and demos are also exposed as **MCP resources**, so a user can\nattach a page or a demo directly instead of hoping the model thinks to\nsearch for it:\n\n```\nsvgrid://doc/help/columns/column-definitions\nsvgrid://example/11-stock-market\n```\n\nAnd three **prompts** ship ready to run: `build_grid`, `explain_api`\nand `review_grid_code`. Each is written to make the model use this\nserver rather than recall SvGrid from training data, and each ends at\n`svgrid_check_code`.\n\n### SvGrid Studio (commercial)\n\nOff unless enabled. Set `SVGRID_MCP_STUDIO=1`, or a valid\n`SVGRID_LICENSE_KEY`, in the server's env.\n\n#### `svgrid_scaffold`\n\nPoint it at a Drizzle schema, sample JSON rows, or an `EntitySchema`\nyou already have, and it infers the schema and generates the `$lib`\nschema module, a `+server.ts` API route and a `+page.svelte` with\n`SvGrid` + `SvGridEditPanel` - in one call. Pass `schemaOnly: true` to\nstop after inference. Generated bodies carry `svgrid:managed` markers,\nso regenerating preserves your edits outside them.\n\n#### The `studio_*` tools\n\nFour tools drive the same validated project model the visual designer\nuses:\n\n| Tool | What it does |\n| ---- | ------------ |\n| `studio_project` | `new`, `load`, `describe`, `config`, `capabilities` |\n| `studio_apply` | A **batch** of model changes - entities, screens, blocks, components - applied in order |\n| `studio_configure` | Theme, auth, access, tenancy, data layer, jobs, deploy target, layouts, in one call |\n| `studio_build` | `validate`, then `generate` the full runnable SvelteKit app |\n\nCall `studio_project` with `action: \"capabilities\"` first: it reports\nexactly what the installed version supports, so the agent does not have\nto guess block kinds or component keys.\n\n`studio_apply` takes a batch on purpose. Building a five-screen app was\ntwenty-odd round trips when every block was its own tool; now a whole\nscreen is one call, and a failure reports which op failed and what\nalready applied.\n\n### The pre-3.0 names\n\nEvery tool name from before 3.0 still answers - `search_docs`,\n`get_doc`, `list_examples`, `get_example_source`, `list_docs`,\n`get_api_reference`, `check_svgrid_code`, `introspect_source`,\n`scaffold_entity` and all 27 individual `studio_*` tools. They are not\n**listed**, because listing is what costs context and answering a name\nyou did not advertise costs nothing. Saved prompts and scripts keep\nworking; nobody pays for the compatibility.\n\nTheir JSON response shape follows 3.0, not 2.x. A model reads either\nwithout trouble; a script that parsed the old shape by hand needs a look.\n\n## Licensing\n\nThe documentation and example tools are free. The Studio code\ngenerators are part of the commercial offering. You can evaluate them\nwithout a key: they run, but prepend a notice comment\nto generated files. To license them, set\nthe key in your MCP client's server config:\n\n```json\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@svgrid/mcp\"],\n \"env\": { \"SVGRID_LICENSE_KEY\": \"SVENTERPRISE-...\" }\n }\n }\n}\n```\n\n## Verifying it works\n\nAsk your model: *\"What MCP tools do you have from svgrid?\"* The local\nserver answers with 36, including `check_svgrid_code` and the `studio_*`\nset; the hosted server answers with 6.\n\nThen give it something to catch:\n\n> Check this with svgrid: `<SvGrid rowData={rows} {columns} />`\n\nIt should come back with `rowData` is not a SvGrid prop, use `data`. If\nit explains the code instead of calling a tool, the server is not\nconnected.\n\nIf nothing is listed at all, check your client's MCP log. For the local\nserver the usual cause is `npx` not being on PATH - use the absolute path\nto the binary. For the hosted one, confirm the endpoint answers:\n\n```bash\ncurl https://mcp.svgrid.com/health\n```\n\n## Security model\n\nThe two ways of running it differ here, so pick deliberately.\n\n**Local (`npx @svgrid/mcp`)**\n\n- Runs on your machine over stdio. No telemetry, no outbound network\n calls, no API key.\n- Serves a documentation and example corpus bundled into the package at\n build time, so answers are pinned to the version you installed.\n- `check_svgrid_code` reads the source you pass it in-process and never\n sends it anywhere.\n\n**Hosted (`https://mcp.svgrid.com/mcp`)**\n\n- Your client sends tool arguments to a Cloudflare Worker we operate.\n Anything you pass to a tool leaves your machine, and for\n `check_svgrid_code` that means **the source you ask it to check**.\n- Each call is logged: tool name, duration, whether it succeeded, and the\n query or id it was given. For `check_svgrid_code` only the **byte\n length** of the submitted source is recorded, never the source itself.\n- No account, no key, no cookies. Requests are not tied to a user.\n- If your code cannot leave the building, use the local server. That is\n what it is for.\n\n**Both**\n\n- The Studio tools return generated files as data. Writing them to disk\n is your client's decision, not the server's.\n- See [security](./security.md) for the general supply-chain posture.\n\n## Building your own MCP integrations\n\nThe same docs manifest, JSON Schemas (column definitions, the grid's\noptions, export options, and the chart spec at `schemas/chart-spec.json`,\nwhich `svgrid_get` also serves for \"chart spec schema\"), and `llms.txt`\nfiles are also served directly from the docs site:\n\n```ts\nconst docs = await fetch('https://svgrid.com/docs.json').then((r) => r.json())\nconst schemas = await fetch('https://svgrid.com/schemas/index.json').then((r) => r.json())\nconst llms = await fetch('https://svgrid.com/llms-full.txt').then((r) => r.text())\n```\n\nIf you do not want to run the MCP server, building these into your\nagent's system prompt gives most of the same grounding.\n\n## Frequently asked questions\n\n### What is the SvGrid MCP server?\n\nA Model Context Protocol server that lets AI clients (Claude Code, Claude\nDesktop, Cursor, Zed, custom agents) query SvGrid's documentation, read real\ndemo source, scaffold SvelteKit CRUD apps, and check the code they write\nagainst the real API - grounded in the files the package ships, so the model\nanswers from current facts instead of guessing.\n\n### Do I need an API key to run it?\n\nNo, on either transport. A `SVGRID_LICENSE_KEY` is optional and only affects\nthe commercial Studio code generators.\n\n### Local or hosted - which should I use?\n\nHosted (`https://mcp.svgrid.com/mcp`) if you want it working in one paste,\nwith no Node and no config file. Local (`npx @svgrid/mcp`) if you want the\nSvelte compiler pass in `check_svgrid_code`, the 27 Studio tools, offline\nuse, or your source never leaving the machine. See\n[Security model](#security-model) for what each one sends.\n\n### How does it help AI assistants write better SvGrid code?\n\nTwo ways. It exposes the docs, example sources, and API reference as tools,\nso the assistant retrieves version-pinned answers instead of hallucinating an\nAPI from training data. And `check_svgrid_code` closes the loop: the model\nruns what it wrote past the real exported surface and gets told exactly what\nis wrong before you see it. That matters most for Svelte 5, where models\nroutinely mix in outdated Svelte 4 syntax.\n\n### Does it work with a version of SvGrid I have not upgraded to?\n\nThe local server answers for the version bundled in the `@svgrid/mcp` release\nyou install, so pin it alongside `@svgrid/grid` if you are behind. The hosted\nserver always tracks the current release. Either way, every\n`check_svgrid_code` result names the version it checked against in its\n`checkedAgainst` field.\n\n## See also\n\n- [Agent Skill](./skill.md) - the always-on house-style layer; the Claude Code plugin installs it together with this server\n- [LLM grounding](./llm-grounding.md) - the same files used by the MCP server, but documented for direct LLM consumption\n- [Agents](./agents.md) - how to build an AI agent that drives the live grid\n- [AI assistant](./ai.md) - the in-grid AI features (filter / smart-fill / classify / summarise), free in @svgrid/grid\n"
|
|
4702
|
+
"markdown": "# MCP server\n\nThe SvGrid MCP server does two things for an AI client (Claude Code,\nClaude Desktop, Cursor, Zed, Codex, custom agents): it answers questions\nabout SvGrid from the files this repository ships, and it **checks the\ncode the model writes** against the real exported surface of the version\nyou have installed. No API key either way.\n\n\n\n> **What is MCP?** Model Context Protocol is the open standard\n> ([modelcontextprotocol.io](https://modelcontextprotocol.io)) for\n> exposing tools to LLM clients. SvGrid ships an MCP server so the\n> model your team already uses can \"see\" the grid without you having\n> to copy-paste docs into prompts.\n\nIt runs either way you like: as a local process\n([`@svgrid/mcp`](https://www.npmjs.com/package/@svgrid/mcp) on npm), or as\na hosted endpoint at `https://mcp.svgrid.com/mcp` that needs no install at\nall. Both are listed in the official MCP registry as `com.svgrid/svgrid`.\n\n## Two ways to connect\n\n**Hosted (nothing to install).** Point any MCP client at the URL:\n\n```\nhttps://mcp.svgrid.com/mcp\n```\n\n```bash\nclaude mcp add --transport http svgrid https://mcp.svgrid.com/mcp\n```\n\nOne click:\n[Add to Cursor](https://cursor.com/en/install-mcp?name=svgrid&config=eyJ1cmwiOiJodHRwczovL21jcC5zdmdyaWQuY29tL21jcCJ9)\n· [Add to VS Code](https://insiders.vscode.dev/redirect/mcp/install?name=svgrid&config=%7B%22name%22%3A%22svgrid%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fmcp.svgrid.com%2Fmcp%22%7D)\n\nIt carries six tools - `search`, `fetch`, `list_examples`,\n`get_example_source`, `get_api_reference` and `check_svgrid_code` - and\nneeds no Node, no config file, and no key.\n\n**Local (`npx @svgrid/mcp`).** Everything the hosted server has, plus\nthe Studio tools, the docs and demos as MCP resources, ready-made\nprompts, and a `svgrid_check_code` that additionally *compiles* the file\nwith the Svelte compiler rather than checking it statically. Use it when\nyou want the compile pass, the Studio tools, or no third-party endpoint\nin the loop.\n\n| | Hosted | Local |\n| --- | --- | --- |\n| Setup | a URL | `npx @svgrid/mcp` |\n| Needs Node | no | yes |\n| Code check compiles | no, static checks only | yes |\n| Resources and prompts | yes | yes |\n| Visual preview | yes | yes |\n| `studio_*` tools | no | yes, opt-in |\n| Works offline | no | yes |\n\n## Install\n\nNo install step is required - `npx` fetches it on demand:\n\n```bash\n# One-shot, from any project\nnpx -y @svgrid/mcp\n```\n\nTo pin it as a dev dependency instead:\n\n```bash\npnpm add -D @svgrid/mcp\n```\n\nThe local server is a Node binary (`svgrid-mcp`) that speaks MCP over\nstdio. There is no daemon to maintain. The hosted server needs no install\nstep at all - skip to [Wire it into your AI client](#wire-it-into-your-ai-client)\nand use the URL.\n\n## Wire it into your AI client\n\nEvery snippet below shows the local (stdio) form and the hosted (HTTP)\nform. Pick one - running both connects the same tools twice.\n\n### Claude Code\n\nThe plugin is the shortest path: it installs the\n[Agent Skill](./skill.md) and the hosted server together, so the model\ngets the house style *and* the checker in one step.\n\n```\n/plugin marketplace add sv-grid/sv-grid\n/plugin install svgrid@svgrid\n```\n\nOr add the server on its own:\n\n```bash\n# hosted, nothing to install\nclaude mcp add --transport http svgrid https://mcp.svgrid.com/mcp\n\n# or local\nclaude mcp add svgrid -- npx -y @svgrid/mcp\n```\n\nThen run `/mcp` in a session and you will see `svgrid` listed.\n\nTo share the server with your team, add `--scope project`. That writes\na `.mcp.json` at the repository root which you can commit, so everyone\nwho clones the repo gets the same tooling with no per-machine setup:\n\n```bash\nclaude mcp add svgrid --scope project -- npx -y @svgrid/mcp\n```\n\n### Claude Desktop\n\nEdit `~/Library/Application Support/Claude/claude_desktop_config.json`\n(macOS) or `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows):\n\n```json\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@svgrid/mcp\"]\n }\n }\n}\n```\n\nOr the hosted server, with nothing to install:\n\n```json\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"type\": \"http\",\n \"url\": \"https://mcp.svgrid.com/mcp\"\n }\n }\n}\n```\n\nRestart Claude Desktop, then ask *\"using svgrid, build me a grid that\ngroups by department\"* to confirm the tools are exposed.\n\n### Cursor\n\nOne click:\n[Add to Cursor](https://cursor.com/en/install-mcp?name=svgrid&config=eyJ1cmwiOiJodHRwczovL21jcC5zdmdyaWQuY29tL21jcCJ9)\n\nOr by hand, in `Settings -> MCP -> Add new MCP server`:\n\n```json\n{ \"url\": \"https://mcp.svgrid.com/mcp\" }\n```\n\n```json\n{ \"command\": \"npx\", \"args\": [\"-y\", \"@svgrid/mcp\"] }\n```\n\n### Zed\n\n`~/.config/zed/settings.json`:\n\n```json\n{\n \"context_servers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@svgrid/mcp\"],\n \"env\": {}\n }\n }\n}\n```\n\n### VS Code\n\nOne click:\n[Add to VS Code](https://insiders.vscode.dev/redirect/mcp/install?name=svgrid&config=%7B%22name%22%3A%22svgrid%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fmcp.svgrid.com%2Fmcp%22%7D)\n\nOr create `.vscode/mcp.json` in the workspace. Note that VS Code uses\n`servers` rather than the `mcpServers` wrapper:\n\n```json\n{\n \"servers\": {\n \"svgrid\": {\n \"type\": \"http\",\n \"url\": \"https://mcp.svgrid.com/mcp\"\n }\n }\n}\n```\n\n```json\n{\n \"servers\": {\n \"svgrid\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@svgrid/mcp\"]\n }\n }\n}\n```\n\n### Custom agents (OpenAI Agents SDK, Anthropic SDK, LangChain)\n\nPoint your client's MCP stdio transport at `npx -y @svgrid/mcp`, or its\nstreamable-HTTP transport at `https://mcp.svgrid.com/mcp`. Any client that\nspeaks either transport works.\n\nThe hosted server names its two retrieval tools `search` and `fetch`\nexactly, which is what a connector needs to index it.\n\n## Tools exposed\n\nFour, by default. `tools/list` is sent on **every** request, so the tool\nsurface is pure overhead on every turn - and this server used to spend\n~4,710 tokens of it on 36 tools, 79% of them Studio tools that most\nsessions never call once.\n\n| Tool | What it does |\n| ---- | ------------ |\n| `svgrid_search` | Search the docs, the 375 demos and the API surface **in one call**. No arguments returns an index. |\n| `svgrid_get` | Read one thing in full: a doc slug, a demo id, or `api`. |\n| `svgrid_check_code` | Verify code against the real exported surface before the user sees it. |\n| `svgrid_preview` | Render a **live, interactive grid** in the conversation from columns + rows. |\n| `svgrid_scaffold` | Turn a Drizzle schema, sample rows or an EntitySchema into runnable SvelteKit files. |\n\nStudio adds four more, and only when you ask for them - set\n`SVGRID_MCP_STUDIO=1` or a licence key in the server's env. They need a\nlicence to be useful, so they are not charged to everyone else's context\nwindow.\n\nThe **hosted** server carries `search`, `fetch`, `list_examples`,\n`get_example_source`, `get_api_reference`, `check_svgrid_code` and\n`svgrid_preview`, plus the same resources and prompts. The first two are named\nthat way deliberately: those exact names are what a one-click connector needs to\nindex a remote server. It also answers to `svgrid_search`, `svgrid_get` and\n`svgrid_check_code`, so a model that learned the npm package's names is never\ntold \"unknown tool\".\n\nWhat it does **not** have is the compile pass (the Svelte compiler cannot run in\na Worker), the Studio tools (they need a filesystem), and the offline guarantee\n- it is a remote server, so by definition your query reaches it. Use the local\none when any of those matter.\n\n### Verification\n\n#### `svgrid_check_code`\n\nChecks a file **against the version you have installed** and returns\nline-numbered diagnostics with the exact replacement for each: unknown\n`<SvGrid>` props, wrong `ColumnDef` keys, api methods that do not\nexist, imports that will not resolve, and Svelte 5 runes mistakes. It\nalso compiles the component, so a syntax error surfaces here rather\nthan in the user's terminal.\n\nThis is the tool that makes the rest worth having. Retrieval alone\nstill lets a model write a confident, wrong grid; nothing else in the\nserver stops it. Run it on every file you write, fix what it reports,\nand run it again.\n\n### Finding and reading\n\n#### `svgrid_search`\n\nOne call across all three corpora, because \"how do I pin a column\" does\nnot announce whether it is answered by a doc page, a demo, or an API\nname:\n\n```json\n{ \"query\": \"pin a column\" }\n```\n\nReturns ranked doc hits with excerpts, matching demos, and matching API\nnames - each with the reference you pass to `svgrid_get`. Narrow with\n`kind` (`docs` | `examples` | `api`), trade tokens for completeness\nwith `detail` (`concise` | `full`), and cap with `limit` (max 50).\n\nCall it with **no arguments** for an index of doc sections, demo\ncategories and API groups - the cheapest way to orient before searching.\n\n#### `svgrid_get`\n\n```json\n{ \"ref\": \"help/columns/column-definitions\" }\n{ \"ref\": \"11-stock-market\" }\n{ \"ref\": \"api\" }\n```\n\nThe kind is inferred from the reference; pass `kind` to force it. A\nreference that does not resolve comes back with near matches rather\nthan a bare \"not found\".\n\n### It fixes what it finds\n\n`svgrid_check_code` does not stop at telling you what is wrong. Where the\ncorrection is exact it returns the corrected file too:\n\n```json\n{\n \"diagnostics\": [ ... ],\n \"applied\": [\"rowData -> data (line 7)\", \"accessorKey -> field (line 3)\"],\n \"fixed\": \"<the corrected source>\"\n}\n```\n\nBoth fields are omitted when there is nothing mechanically fixable, so a clean\ncheck stays small.\n\nThe rules are deliberately narrow, because this tool's whole worth is that it\nnever cries wolf - and rewriting raises the stakes from wasting a turn to\ncorrupting working code. Only exact renames are applied (a known rename, or a\nclose-enough spelling), only on word boundaries, and only on the line the\ndiagnostic reported. Advice that is ambiguous - \"this has no equivalent, remove\nit\" - stays advice. A test asserts that running auto-fix across all 367 demos\nin this repository changes nothing at all.\n\n### It knows which version you have\n\nThe result carries the version it checked against:\n\n```json\n{ \"version\": { \"corpus\": \"3.0.0\", \"installed\": \"2.6.8\", \"warning\": \"...\" } }\n```\n\nThe server reads the `@svgrid/grid` in your project and says plainly when it\ndisagrees with the corpus it ships, so a model is told to hedge instead of\nconfidently citing an API you do not have. A server that answers from a remote\nbackend cannot do this - it has no idea what is in your `node_modules`.\n\n### Nothing leaves your machine\n\nThis server makes **no network calls**. Not for docs, not for the API surface,\nnot for verification - the whole corpus (375 demos, 408 doc pages, the full\nexported API) ships inside the package, which is why it is 8 MB rather than\n90 KB. There is no API key, no licence check on the wire, and no telemetry.\n\nIt works on a plane, behind a corporate proxy, and inside an air-gapped\nnetwork. `tools/mcp-offline.test.ts` enforces it: the server is driven through\na full session with every network primitive booby-trapped, and the test fails if\nanything is even attempted.\n\nThe one honest exception: the **preview** loads the grid from a CDN to draw it.\nThat happens in your client's sandboxed iframe, never in this server, and only\nwhen you actually render a preview.\n\n### Seeing the grid, not just reading about it\n\n`svgrid_preview` renders a **real, interactive SvGrid inside the\nconversation** - sortable, filterable, scrollable. Not a screenshot and not a\nmock table: the same `<sv-grid>` custom element a page would use, loaded from\nthe CDN, with the columns and rows you passed.\n\n```json\n{\n \"title\": \"Team roster\",\n \"columns\": [{ \"field\": \"name\", \"header\": \"Name\" }, { \"field\": \"amount\", \"header\": \"Amount\" }],\n \"data\": [{ \"name\": \"Ada\", \"amount\": 20000 }],\n \"sortable\": true\n}\n```\n\nIt uses [MCP Apps](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/),\nthe official UI extension: the tool points at a `ui://` resource through\n`_meta`, the client loads that HTML in a sandboxed iframe, and the tool's\n`structuredContent` arrives over a postMessage bridge. Supported in Claude\n(web and desktop), VS Code and ChatGPT.\n\nClients without UI support are not left out - they ignore the `_meta` and get\na text summary of the same grid, so it is always safe to call. That is the\nextension's own rule, and it is why the text half describes the grid rather\nthan pointing at a picture the reader cannot see.\n\nPass `demo` instead of `columns` / `data` and you get the demo's source: a\ndemo is a Svelte component, not data, so there is nothing to hand the element\nand rendering an empty grid would just look broken.\n\n### Resources and prompts\n\nThe docs and demos are also exposed as **MCP resources**, so a user can\nattach a page or a demo directly instead of hoping the model thinks to\nsearch for it:\n\n```\nsvgrid://doc/help/columns/column-definitions\nsvgrid://example/11-stock-market\n```\n\nAnd three **prompts** ship ready to run: `build_grid`, `explain_api`\nand `review_grid_code`. Each is written to make the model use this\nserver rather than recall SvGrid from training data, and each ends at\n`svgrid_check_code`.\n\n### SvGrid Studio (commercial)\n\nOff unless enabled. Set `SVGRID_MCP_STUDIO=1`, or a valid\n`SVGRID_LICENSE_KEY`, in the server's env.\n\n#### `svgrid_scaffold`\n\nPoint it at a Drizzle schema, sample JSON rows, or an `EntitySchema`\nyou already have, and it infers the schema and generates the `$lib`\nschema module, a `+server.ts` API route and a `+page.svelte` with\n`SvGrid` + `SvGridEditPanel` - in one call. Pass `schemaOnly: true` to\nstop after inference. Generated bodies carry `svgrid:managed` markers,\nso regenerating preserves your edits outside them.\n\n#### The `studio_*` tools\n\nFour tools drive the same validated project model the visual designer\nuses:\n\n| Tool | What it does |\n| ---- | ------------ |\n| `studio_project` | `new`, `load`, `describe`, `config`, `capabilities` |\n| `studio_apply` | A **batch** of model changes - entities, screens, blocks, components - applied in order |\n| `studio_configure` | Theme, auth, access, tenancy, data layer, jobs, deploy target, layouts, in one call |\n| `studio_build` | `validate`, then `generate` the full runnable SvelteKit app |\n\nCall `studio_project` with `action: \"capabilities\"` first: it reports\nexactly what the installed version supports, so the agent does not have\nto guess block kinds or component keys.\n\n`studio_apply` takes a batch on purpose. Building a five-screen app was\ntwenty-odd round trips when every block was its own tool; now a whole\nscreen is one call, and a failure reports which op failed and what\nalready applied.\n\n### The pre-3.0 names\n\nEvery tool name from before 3.0 still answers - `search_docs`,\n`get_doc`, `list_examples`, `get_example_source`, `list_docs`,\n`get_api_reference`, `check_svgrid_code`, `introspect_source`,\n`scaffold_entity` and all 27 individual `studio_*` tools. They are not\n**listed**, because listing is what costs context and answering a name\nyou did not advertise costs nothing. Saved prompts and scripts keep\nworking; nobody pays for the compatibility.\n\nTheir JSON response shape follows 3.0, not 2.x. A model reads either\nwithout trouble; a script that parsed the old shape by hand needs a look.\n\n## Licensing\n\nThe documentation and example tools are free. The Studio code\ngenerators are part of the commercial offering. You can evaluate them\nwithout a key: they run, but prepend a notice comment\nto generated files. To license them, set\nthe key in your MCP client's server config:\n\n```json\n{\n \"mcpServers\": {\n \"svgrid\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@svgrid/mcp\"],\n \"env\": { \"SVGRID_LICENSE_KEY\": \"YOUR-LICENSE-KEY\" }\n }\n }\n}\n```\n\n## Verifying it works\n\nAsk your model: *\"What MCP tools do you have from svgrid?\"* The local\nserver answers with 36, including `check_svgrid_code` and the `studio_*`\nset; the hosted server answers with 6.\n\nThen give it something to catch:\n\n> Check this with svgrid: `<SvGrid rowData={rows} {columns} />`\n\nIt should come back with `rowData` is not a SvGrid prop, use `data`. If\nit explains the code instead of calling a tool, the server is not\nconnected.\n\nIf nothing is listed at all, check your client's MCP log. For the local\nserver the usual cause is `npx` not being on PATH - use the absolute path\nto the binary. For the hosted one, confirm the endpoint answers:\n\n```bash\ncurl https://mcp.svgrid.com/health\n```\n\n## Security model\n\nThe two ways of running it differ here, so pick deliberately.\n\n**Local (`npx @svgrid/mcp`)**\n\n- Runs on your machine over stdio. No telemetry, no outbound network\n calls, no API key.\n- Serves a documentation and example corpus bundled into the package at\n build time, so answers are pinned to the version you installed.\n- `check_svgrid_code` reads the source you pass it in-process and never\n sends it anywhere.\n\n**Hosted (`https://mcp.svgrid.com/mcp`)**\n\n- Your client sends tool arguments to a Cloudflare Worker we operate.\n Anything you pass to a tool leaves your machine, and for\n `check_svgrid_code` that means **the source you ask it to check**.\n- Each call is logged: tool name, duration, whether it succeeded, and the\n query or id it was given. For `check_svgrid_code` only the **byte\n length** of the submitted source is recorded, never the source itself.\n- No account, no key, no cookies. Requests are not tied to a user.\n- If your code cannot leave the building, use the local server. That is\n what it is for.\n\n**Both**\n\n- The Studio tools return generated files as data. Writing them to disk\n is your client's decision, not the server's.\n- See [security](./security.md) for the general supply-chain posture.\n\n## Building your own MCP integrations\n\nThe same docs manifest, JSON Schemas (column definitions, the grid's\noptions, export options, and the chart spec at `schemas/chart-spec.json`,\nwhich `svgrid_get` also serves for \"chart spec schema\"), and `llms.txt`\nfiles are also served directly from the docs site:\n\n```ts\nconst docs = await fetch('https://svgrid.com/docs.json').then((r) => r.json())\nconst schemas = await fetch('https://svgrid.com/schemas/index.json').then((r) => r.json())\nconst llms = await fetch('https://svgrid.com/llms-full.txt').then((r) => r.text())\n```\n\nIf you do not want to run the MCP server, building these into your\nagent's system prompt gives most of the same grounding.\n\n## Frequently asked questions\n\n### What is the SvGrid MCP server?\n\nA Model Context Protocol server that lets AI clients (Claude Code, Claude\nDesktop, Cursor, Zed, custom agents) query SvGrid's documentation, read real\ndemo source, scaffold SvelteKit CRUD apps, and check the code they write\nagainst the real API - grounded in the files the package ships, so the model\nanswers from current facts instead of guessing.\n\n### Do I need an API key to run it?\n\nNo, on either transport. A `SVGRID_LICENSE_KEY` is optional and only affects\nthe commercial Studio code generators.\n\n### Local or hosted - which should I use?\n\nHosted (`https://mcp.svgrid.com/mcp`) if you want it working in one paste,\nwith no Node and no config file. Local (`npx @svgrid/mcp`) if you want the\nSvelte compiler pass in `check_svgrid_code`, the 27 Studio tools, offline\nuse, or your source never leaving the machine. See\n[Security model](#security-model) for what each one sends.\n\n### How does it help AI assistants write better SvGrid code?\n\nTwo ways. It exposes the docs, example sources, and API reference as tools,\nso the assistant retrieves version-pinned answers instead of hallucinating an\nAPI from training data. And `check_svgrid_code` closes the loop: the model\nruns what it wrote past the real exported surface and gets told exactly what\nis wrong before you see it. That matters most for Svelte 5, where models\nroutinely mix in outdated Svelte 4 syntax.\n\n### Does it work with a version of SvGrid I have not upgraded to?\n\nThe local server answers for the version bundled in the `@svgrid/mcp` release\nyou install, so pin it alongside `@svgrid/grid` if you are behind. The hosted\nserver always tracks the current release. Either way, every\n`check_svgrid_code` result names the version it checked against in its\n`checkedAgainst` field.\n\n## See also\n\n- [Agent Skill](./skill.md) - the always-on house-style layer; the Claude Code plugin installs it together with this server\n- [LLM grounding](./llm-grounding.md) - the same files used by the MCP server, but documented for direct LLM consumption\n- [Agents](./agents.md) - how to build an AI agent that drives the live grid\n- [AI assistant](./ai.md) - the in-grid AI features (filter / smart-fill / classify / summarise), free in @svgrid/grid\n"
|
|
4703
4703
|
},
|
|
4704
4704
|
{
|
|
4705
4705
|
"slug": "help/migrating-from-ag-grid",
|
|
4706
4706
|
"path": "docs/help/migrating-from-ag-grid.md",
|
|
4707
4707
|
"title": "Migrating from AG Grid to SvGrid",
|
|
4708
4708
|
"section": "Help",
|
|
4709
|
-
"markdown": "# Migrating from AG Grid to SvGrid\n\nIf you tried AG Grid on a Svelte 5 project - via `ag-grid-svelte`, the\nold `ag-grid-community/svelte`, or a hand-rolled wrapper - you probably\nhit the same friction everyone hits: the bridge between AG Grid's\nReact/Angular-first API and Svelte 5 runes is brittle, the bundle is\nheavy, and the Enterprise pricing only makes sense at scale.\n\n<!-- facts:start ag-grid -->\n> **Facts, checked 12 Sep 2026.** `ag-grid-community` 36.1.0, MIT, last published 5 Aug 2026, 12,400,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `ag-grid-community` 36.1.0 317.5 KB JS, no separate stylesheet (measured 12 Sep 2026). AG Grid pricing, as its site states it: AG Grid Community is free under MIT. AG Grid Enterprise is listed at $999 USD per developer with one year of updates and Zendesk support; the Enterprise Bundle with AG Charts Enterprise is $1,498 USD per developer (https://www.ag-grid.com/license-pricing/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/).\n<!-- facts:end -->\n\nThis page is a 30-minute migration recipe from AG Grid to SvGrid. It\ncovers what maps 1:1, what's different by design, and what you'll lose.\nWe tell you when **not** to switch at the bottom.\n\n## TL;DR\n\n| | AG Grid Community | AG Grid Enterprise | SvGrid Community | @svgrid/enterprise |\n| --- | --- | --- | --- | --- |\n| **Licence** | MIT | Commercial, per developer (the price is in the facts box above) | **MIT** | $599/dev/yr (grid) or $999/dev/yr (grid + spreadsheet + Studio) |\n| **Svelte 5 native** | No (community-built integration) | No (community-built integration) | Yes | Yes |\n| **Bundle (gzipped)** | measured, in the facts box above | not measured (licence) | measured, in the facts box above | lazy-loaded subpaths |\n| **Sorting / filtering** | Yes | Yes | Yes | (in Community) |\n| **Row grouping + aggregation** | No (Enterprise) | Yes | Yes (free) | (in Community) |\n| **Master/detail, tree, range select** | No (Enterprise) | Yes | Yes (free) | (in Community) |\n| **Set filter / Excel-style filter menu** | No (Enterprise) | Yes | Yes (free) | (in Community) |\n| **Server-side data, flat (infinite row model)** | Yes | Yes | Yes (free) | (in Community) |\n| **Server-side row model (grouping, tree, pivot, transactions, selection)** | No (Enterprise) | Yes | No | Yes |\n| **Integrated charts** | No (Enterprise) | Yes, AG Charts | Yes (free) | (in Community) |\n| **CSV export** | Yes (API) | Yes | Yes, with TSV and JSON | (in Community) |\n| **Excel export** | No | Yes | No | Yes |\n| **PDF / styled-HTML export, print** | No | No | No | Yes |\n| **Pivot tables** | No | Yes | No | Yes |\n| **MCP server for AI assistants** | Yes, `ag-mcp` | Yes | Yes, `@svgrid/mcp` | (in Community) |\n| **In-grid AI helpers** | No | No | Yes (bring your own model) | (in Community) |\n\n**SvGrid Community gives you most of what AG Grid sells as Enterprise for\nfree**, and `@svgrid/enterprise` adds Excel, PDF and print output, import,\npivot tables and the server-side row model per developer per year. Compare what each paid tier adds\nbefore comparing prices; both are in the facts box. The trade-offs are\nSvelte-only and a much smaller ecosystem. Every AG Grid cell above follows\nag-grid.com's own pages; the dated list is on the\n[SvGrid vs AG Grid](https://svgrid.com/compare/ag-grid/) page.\n\n## Mental model - what changes\n\nAG Grid is one big object you configure declaratively. SvGrid is a\n**headless engine** (`createSvGrid`) with an optional **render\ncomponent** (`<SvGrid>`) on top - the same split TanStack Table made\npopular. You can use either layer; most projects use the render\ncomponent.\n\nEvery example below runs against this setup:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature, type ColumnDef } from '@svgrid/grid'\n\n type Row = { id: number; make: string; model: string; price: number }\n\n const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n\n let rows = $state<Row[]>([\n { id: 1, make: 'Toyota', model: 'Celica', price: 35000 },\n { id: 2, make: 'Ford', model: 'Mondeo', price: 32000 },\n { id: 3, make: 'Porsche', model: 'Boxster', price: 72000 },\n ])\n const data = rows\n\n const columns: ColumnDef<typeof features, Row>[] = [\n { field: 'make', header: 'Make' },\n { field: 'model', header: 'Model' },\n { field: 'price', header: 'Price', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```svelte\n<!-- AG Grid (via a Svelte wrapper) -->\n<AgGridSvelte\n gridOptions={{\n rowData: rows,\n columnDefs: columns,\n onGridReady: (params) => (gridApi = params.api),\n }}\n/>\n\n<!-- SvGrid -->\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n onApiReady={(api) => (gridApi = api)}\n/>\n```\n\nThree things to note:\n\n1. **No giant `gridOptions` blob.** Each capability is a top-level prop.\n2. **Features are opt-in.** You pass a `features` object built with\n `tableFeatures({...})` - only the features you list ship JS.\n3. **`onApiReady`** gives you a typed `SvGridApi` that is roughly the\n AG Grid `gridApi` equivalent (see the API-mapping table below).\n\n## Column definitions - direct translation\n\nThe shapes are similar enough that you can usually translate by hand\nwithout thinking too hard.\n\n```ts\n// AG Grid\nconst columnDefs: ColDef[] = [\n { field: 'name', headerName: 'Name', sortable: true, filter: true, width: 200 },\n { field: 'price', headerName: 'Price', type: 'numericColumn',\n valueFormatter: ({ value }) => `$${value.toFixed(2)}` },\n { field: 'date', headerName: 'Date',\n valueGetter: ({ data }) => new Date(data.date).toISOString().slice(0, 10) },\n { field: 'status', headerName: 'Status',\n cellRenderer: StatusCellRenderer,\n cellRendererParams: { onChange: handleStatusChange } },\n]\n```\n\n```ts\n// SvGrid\nimport { renderComponent, type ColumnDef } from '@svgrid/grid'\nimport StatusCell from './StatusCell.svelte'\n\nconst columns: ColumnDef<typeof features, Row>[] = [\n { field: 'name', header: 'Name', width: 200 }, // sortable + filterable by default\n { field: 'price', header: 'Price',\n format: { type: 'currency', currency: 'USD' } },\n { field: 'date', header: 'Date',\n format: { type: 'date', pattern: 'y-m-d' } },\n { field: 'status', header: 'Status',\n cell: renderComponent(StatusCell, (ctx) => ({\n value: ctx.getValue(),\n onChange: handleStatusChange,\n })),\n },\n]\n```\n\n### Property mapping\n\n| AG Grid | SvGrid | Notes |\n| --- | --- | --- |\n| `field` | `field` | Same. |\n| `headerName` | `header` | Accepts a string or a snippet/component. |\n| `width` | `width` | Same. |\n| `minWidth` / `maxWidth` | `minWidth` / `maxWidth` | Same. |\n| `sortable: true` | (default) | Sorting is on when `rowSortingFeature` is registered. |\n| `filter: true` | (default) | Filtering is on when `columnFilteringFeature` is registered. |\n| `valueFormatter` | `format: { ... }` | Built-in types: `number`, `currency`, `percent`, `date`. For custom, use `cell`. |\n| `valueGetter` | `fieldFn` | Returns the value for sorting/filtering. |\n| `cellRenderer` + `cellRendererParams` | `cell: renderComponent(C, ctx => props)` | One call, type-checked. |\n| `cellEditor: 'agTextCellEditor'` | `editorType: 'text'` | Built-in: `text`, `number`, `checkbox`, `date`. |\n| `editable: true` | `enableInlineEditing` prop on `<SvGrid>` | Per-grid, not per-column. (Per-column control on the roadmap.) |\n| `pinned: 'left'` / `'right'` | Right-click column menu → Pin | Set programmatically via the api. |\n| `rowGroup: true` | Via `setGroupBy([colId])` | See Grouping below. |\n| `aggFunc: 'sum'` | `aggregate: 'sum'` | Built-in: `sum`, `avg`, `min`, `max`, `count`. |\n\n## Feature registration - the one new thing\n\nAG Grid auto-enables most features; you turn them off. SvGrid is the\nopposite - features are opt-in. The result is a smaller bundle.\n\n```ts\nimport {\n tableFeatures,\n rowSortingFeature,\n columnFilteringFeature,\n columnGroupingFeature,\n rowExpandingFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n} from '@svgrid/grid'\n\nconst features = tableFeatures({\n rowSortingFeature,\n columnFilteringFeature,\n rowSelectionFeature,\n // omit any you don't need - their code won't ship\n})\n```\n\nPass `features` to `<SvGrid>` once. From then on the grid behaves like\nAG Grid's `enableSorting`, `enableFilter`, `rowSelection`, etc. are all\non for the registered features.\n\n## API mapping (`gridApi` → `SvGridApi`)\n\nYou get the SvGrid API from `onApiReady` (equivalent to AG Grid's\n`onGridReady`).\n\n| AG Grid `gridApi.X()` | SvGrid `api.X()` |\n| --- | --- |\n| `setRowData(rows)` | (declarative - just update `data` prop) |\n| `addRow(row)` / `applyTransaction({ add: [row] })` | `api.addRow(row)` / `api.addRows(rows)` |\n| `applyTransaction({ remove: [row] })` | `api.removeRow(rowIndex)` |\n| `getValue(colId, rowNode)` | `api.getCellValue(rowIndex, columnId)` |\n| `setValue(...)` | `api.setCellValue(rowIndex, columnId, value)` |\n| `setColumnVisible(colId, visible)` | `api.setColumnVisible(columnId, visible)` |\n| `getSortModel()` / `setSortModel()` | `api.setSort(columnId, 'asc'\\|'desc'\\|null)` |\n| `setFilterModel({...})` | `api.setFilter(columnId, { operator, value })` |\n| `getDisplayedRowAtIndex(i)` / `forEachNodeAfterFilterAndSort(...)` | `api.getDisplayedRows()` |\n| `getModel()` (raw rows) | `api.getData()` |\n\n## Common patterns\n\n### Sorting + filtering + pagination (the 80% case)\n\n```svelte\n<script lang=\"ts\">\n import {\n SvGrid,\n tableFeatures,\n rowSortingFeature,\n columnFilteringFeature,\n rowPaginationFeature,\n } from '@svgrid/grid'\n\n const features = tableFeatures({\n rowSortingFeature,\n columnFilteringFeature,\n rowPaginationFeature,\n })\n</script>\n\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n showPagination\n showColumnFilters\n/>\n```\n\nAG Grid equivalent: `gridOptions: { defaultColDef: { sortable: true, filter: true }, pagination: true }`.\n\n### Cell editing with persistence\n\n```svelte\n<script lang=\"ts\">\n function onCellValueChange(e: { rowIndex: number; columnId: string; value: unknown }) {\n // Persist however you like (fetch to backend, optimistic local update, etc.)\n console.log('cell changed', e)\n }\n</script>\n\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n enableInlineEditing\n onCellValueChange={onCellValueChange}\n/>\n```\n\nAG Grid equivalent: `onCellValueChanged: ({ data, colDef, newValue, oldValue }) => ...`.\nSvGrid's event payload is column-id + row-index based rather than node-based; the row data is yours\nto mutate (or not) on the `rows` array you passed in.\n\n### Grouping + aggregation\n\n```svelte\n<script lang=\"ts\">\n import {\n SvGrid,\n tableFeatures,\n columnGroupingFeature,\n rowSortingFeature,\n rowExpandingFeature,\n } from '@svgrid/grid'\n\n const features = tableFeatures({\n rowSortingFeature,\n columnGroupingFeature,\n rowExpandingFeature,\n })\n\n const columns = [\n { field: 'department', header: 'Department' },\n { field: 'team', header: 'Team' },\n { field: 'salary', header: 'Salary', aggregate: 'sum',\n format: { type: 'currency', currency: 'USD' } },\n ]\n\n function setGroup(api) {\n api.setGroupBy(['department', 'team'])\n }\n</script>\n\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n showGroupingControls\n onApiReady={setGroup}\n/>\n```\n\nAG Grid Enterprise's `rowGroupPanelShow: 'always'` + `aggFunc: 'sum'` translates 1:1.\n\n### Master / detail\n\nAG Grid Enterprise feature; **free in SvGrid Community**. See\n[demo 08](https://svgrid.com/demos/08-tree-and-master-detail/) for the exact pattern.\n\n### Server-side data\n\nAG Grid's Infinite Row Model (Community) and Server-Side Row Model\n(Enterprise) both take an `IServerSideDatasource` with a `getRows(params)`\nthat answers through `params.success({ rowData, rowCount })`. SvGrid has one\n`ServerDataSource` whose `getRows(request)` returns `{ rows, rowCount }`,\nand two controllers over it: `createServerDataSource` (free: paging or\ninfinite block scroll, sort, filter, CRUD) and `createServerRowModel`\n(Enterprise: lazy grouping, tree, pivot, transactions, selection). Both\nmount through one prop, `<SvGrid rowModel={ctl} />`.\n\nAn existing datasource written for AG Grid keeps working behind one call:\n\n```ts\nimport { adaptCallbackDatasource, createServerRowModel } from '@svgrid/enterprise'\n\nconst ctl = createServerRowModel(adaptCallbackDatasource(myServerSideDatasource), {\n groupBy: ['country'],\n aggregations: [{ col: 'amount', fn: 'sum' }],\n})\n```\n\n`adaptCallbackDatasource` maps the request both ways (`rowGroupCols` ->\n`groupBy`, `valueCols` -> `aggregations`, `pivotCols` -> `pivotBy`, the\nsort and filter models, `context`, `parentNode`) and turns `success` /\n`fail` into a resolved or rejected promise.\n\nMore often the datasource is a thin `fetch` and the real investment is the\nendpoint behind it - a Java or Node service that parses AG Grid's\n`IServerSideGetRowsRequest` JSON. That endpoint stays as it is: post\n`toCallbackRequest(request)` and read the answer back.\n\n```ts\nimport { toCallbackRequest } from '@svgrid/enterprise'\n\nconst source = {\n async getRows(request) {\n const res = await fetch('/api/sales', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(toCallbackRequest(request)),\n })\n const { rowData, rowCount, pivotResultFields } = await res.json()\n return { rows: rowData, rowCount: rowCount ?? -1, pivotResultFields }\n },\n}\n```\n\n`fromCallbackRequest` is the other direction, for a SvelteKit endpoint that\nhas to keep serving an AG Grid client during the switch. A saved selection\nor a bulk endpoint written against `getServerSideSelectionState()` keeps\nits shape the same way: `toCallbackSelectionState(ctl.getSelectionState())`\nproduces `{ selectAll, toggledNodes }` (or the `nodeId` /\n`selectAllChildren` / `toggledNodes` tree), `ctl.setSelectionState` takes\nthat shape as it is when your group node ids are the group keys, and\n`fromCallbackSelectionState(state, { groupKey, isGroup })` maps them when\na `getRowId` gave group rows ids of their own. Option by option:\n\n| AG Grid | SvGrid |\n| --- | --- |\n| `rowModelType: 'infinite'` + `datasource` | `createServerDataSource(source, { mode: 'infinite' })` + `rowModel={ctl}` |\n| `rowModelType: 'serverSide'` + `serverSideDatasource` | `createServerRowModel(source, options)` + `rowModel={ctl}` |\n| `getRows(params)` + `params.success({ rowData, rowCount })` / `params.fail()` | `getRows(request)` returning `{ rows, rowCount }` / throwing |\n| `cacheBlockSize`, `maxBlocksInCache`, `maxConcurrentDatasourceRequests`, `blockLoadDebounceMillis` | `blockSize`, `maxBlocksInCache`, `maxConcurrentRequests`, `blockLoadDebounceMs` |\n| `infiniteInitialRowCount` / `serverSideInitialRowCount` | `initialRowCount` |\n| `rowCount: -1` (unknown) | `rowCount: -1` |\n| `refreshInfiniteCache()` / `purgeInfiniteCache()` | `ctl.refresh()` / `ctl.purge()` |\n| `request.rowGroupCols`, `groupKeys`, `valueCols`, `pivotCols`, `pivotMode` | `request.groupBy`, `groupKeys`, `aggregations`, `pivotBy`, `pivotMode` |\n| `getChildCount(data)` | `childCount: (row) => row.childCount` |\n| `isServerSideGroupOpenByDefault` | `isGroupOpenByDefault(route, row)` |\n| `getServerSideGroupLevelParams` | `levelParams(level, route)` |\n| `isServerSideGroup` / `getServerSideGroupKey` (tree) | `treeData: true` + `hasChildren` / `getRowId` |\n| `grandTotalRow` / `groupTotalRow` | `grandTotalRow` / `groupFooters` |\n| `refreshServerSide({ route, purge })` / `retryServerSideLoads()` | `ctl.refresh({ route, purge })` / `ctl.retryLoads()` |\n| `applyServerSideTransaction` / `applyServerSideTransactionAsync` / `flushServerSideAsyncTransactions` | `ctl.applyTransaction` / `applyTransactionAsync` / `flushAsyncTransactions` |\n| `applyServerSideRowData` | `ctl.applyRowData` |\n| `serverSideSortAllLevels`, `serverSideEnableClientSideSort`, `serverSideOnlyRefreshFilteredGroups` | `sortAllLevels`, `clientSideSort`, `onlyRefreshFilteredGroups` |\n| `getServerSideSelectionState` / `setServerSideSelectionState` | `ctl.getSelectionState()` / `setSelectionState()` (the `toggledNodes` shape is accepted; `toCallbackSelectionState` / `fromCallbackSelectionState` convert) |\n| `ServerSideTransactionResult.status`: `Applied`, `StoreNotFound`, `StoreLoading`, `StoreWaitingToLoad`, `StoreLoadingFailed`, `Cancelled` | `ServerTransactionResult.status`: the same six, lower camel case (`applied`, `storeNotFound`, ...) - a `switch` on the old spelling falls through silently |\n| `groupSelects: 'descendants'` | `selection: { groupSelects: 'descendants' }` |\n| `pivotResultFields` in `success`, `setPivotResultColumns`, `processPivotResultColDef` | `pivotResultFields` / `pivotResultColumns` in the result, `pivotResultColumn(field, def)` |\n| `pagination` + `paginateChildRows` | `pagination: { pageSize, paginateChildRows }` |\n| `getCacheBlockState()` / `getServerSideGroupLevelState()` | `ctl.getCacheState()` / `ctl.levelStates()` |\n| `serverSideDatasource.destroy()` | `source.destroy()` |\n\nTwo differences worth knowing before you start: SvGrid sends the global\nsearch box to the server as `filterModel.global` (AG Grid's quick filter is\nclient-side only and unsupported under its infinite and server-side models),\nand SvGrid has no viewport row model. See\n[Server grouping](./server/server-grouping.md) and\n[demo 467](https://svgrid.com/demos/467-server-row-model-1m/).\n\n### Excel / PDF export\n\nAG Grid: `gridApi.exportDataAsExcel({...})` (Enterprise-only).\nSvGrid: install `@svgrid/enterprise`, call `api.exportData({ format: 'xlsx', ... })`. See [Data export and printing](./export.md).\n\n```ts\nimport { installEnterprise, setLicenseKey } from '@svgrid/enterprise'\nsetLicenseKey('SVENTERPRISE-...') // your Enterprise key\n\n// inside onApiReady:\nconst pro = installEnterprise(api)\nawait pro.exportData({ format: 'xlsx', filename: 'orders' })\n```\n\n## Gotchas - things that don't translate directly\n\n### 1. Per-column `editable: true`\nEditing is switched on at the grid level (`enableInlineEditing`) and\nnarrowed per column with `editable: boolean | (ctx) => boolean` on the\ncolumn definition, so AG Grid's per-column flag and its callback form both\nmap directly. What does not map is AG Grid's `editable` on a column\ngroup: set it on each child column.\n\n### 2. Column drag-to-reorder\nHeader drag is `enableColumnReorder` on `<SvGrid>`; `setColumnOrder`\non the API does the same from code. See\n[column moving](./columns/column-moving.md) for the events.\n\n### 3. AG Grid `valueGetter` chains\nAG Grid's `valueGetter` can read other column values via the API. In\nSvGrid, `fieldFn` only receives the row; if you need cross-column\ncomputed values, do it in the cell renderer with `ctx.row.original` or\ncompute the derived value upstream and store it in the row.\n\n### 4. `cellClass` / `rowClass` callbacks\nOn the roadmap. For now, render a wrapper element in your `cell` snippet\nwith the conditional class.\n\n### 5. The Status Bar / Side Bar / Tool Panels\nAG Grid's chrome (status bar with row count, side bar with filters and\ncolumns panels) doesn't exist in SvGrid - build it as plain Svelte\nmarkup around the grid. Most teams build their own anyway because\nAG Grid's defaults rarely match a polished design system.\n\n### 6. Set filter (the Excel-style funnel popup)\nSvGrid ships an Excel-style filter menu (free in Community). API surface\nis similar but not identical - see [Set filter](./filtering/set-filter.md).\n\n## When NOT to migrate\n\nBe honest. Stay on AG Grid if you:\n\n- **Use multiple frameworks** - AG Grid has React, Angular, Vue, Solid, Qwik, vanilla adapters. SvGrid is Svelte-only.\n- **Need a push-based viewport row model** - SvGrid's server-side row model covers grouping, tree, pivot, transactions and select-all across unloaded rows, and its real-time page merges deltas into loaded rows, but the server cannot push the visible window over a socket the way the viewport model does.\n- **Need pluggable custom filter components or custom tool panels** - SvGrid's tool panel is a fixed Columns + Filters pair.\n- **Are mid-project and shipping in <2 weeks** - the migration is a few hours per grid, but only do it when you have buffer.\n- **Have a Svelte 4 codebase you can't upgrade** - SvGrid requires Svelte 5 runes. (Consider [htmlelements.com](https://www.htmlelements.com) for vanilla / multi-framework.)\n\nIf none of those apply: switching drops a per-developer Enterprise licence\nfor features that are in SvGrid's MIT core, cuts the bundle by the\ndifference in the facts box above, and gives you a Svelte-native API that\nplays well with runes.\n\n## Step-by-step migration\n\nA typical migration of a single grid takes 1-3 hours:\n\n1. **Install** - `pnpm add @svgrid/grid` (and `@svgrid/enterprise` if you need export).\n2. **Translate columnDefs** - use the mapping table above. Most columns are 1:1.\n3. **Wrap features** - figure out which AG Grid features you actually use; register only those in `tableFeatures({...})`.\n4. **Swap the component** - `<AgGridSvelte gridOptions={...}>` → `<SvGrid data={rows} columns={columns} features={features}>`.\n5. **Move event handlers** - AG Grid `onCellValueChanged` → SvGrid `onCellValueChange` (signature differs slightly, see above).\n6. **Move API calls** - AG Grid `gridApi.X()` → SvGrid `api.X()` per the API table.\n7. **Test interactions** - sort, filter, edit, select. Most \"just works.\"\n8. **Remove `ag-grid-*` packages** - `pnpm remove ag-grid-community ag-grid-svelte` etc. Inspect your bundle to confirm the drop; the facts box above has both measured sizes.\n\n## Need help migrating?\n\nEnterprise customers get **migration help included** with the support plan\n(architecture review, port one grid for you as a reference). Email\n`support@jqwidgets.com` after purchase, or `sales@jqwidgets.com` for\npre-sales questions.\n\n## Frequently asked questions\n\n### Is SvGrid a drop-in replacement for AG Grid in Svelte?\n\nNot a literal drop-in - there is no `ag-grid-svelte` shim to swap. But the\nconcepts map closely: column definitions, row models, sorting, filtering,\ngrouping, and an imperative API all have direct SvGrid equivalents, so most\nteams port a grid in 30 minutes to a day. It is a configuration translation,\nnot a rewrite.\n\n### What is the SvGrid equivalent of AG Grid Enterprise?\n\n`@svgrid/enterprise`. It adds Excel/PDF/styled-HTML export (CSV, TSV and JSON export are already free in the grid), a printable view, pivot\ntables and data import. The in-grid AI helpers are free in `@svgrid/grid`.\nIt is licensed per developer ($599 for the grid, $999 with the spreadsheet\nand Studio, both covering unlimited apps), and the\nCommunity package is MIT-licensed and free for commercial use.\n\n### Does SvGrid use Svelte 5 runes, or is it a wrapper?\n\nIt is Svelte-5-native. State is `$state` / `$derived` / `$effect` and cells\nrender through Svelte snippets - there is no React or Angular core underneath\nand no framework bridge to keep in sync.\n\n### Will my AG Grid bundle size shrink?\n\nAlmost always. The facts box at the top of this page has both packages\nmeasured the same way on the same date: the full SvGrid render component\nwith its stylesheet against `createGrid` with every AG Grid Community\nmodule registered. You add `@svgrid/enterprise` features only where you\nimport them, and the headless core on its own is a small fraction of the\nrender component.\n\n## More examples\n\n### AG Grid ↔ sv-grid side-by-side\n\nTwo real grids over the same dataset: the installed AG Grid Community on the left, sv-grid on the right. Same global filter drives both. Source code panels for either side.\n\n<div data-docs-demo=\"139-migration-from-ag-grid\" data-height=\"460\"></div>\n\n## See also\n\n- [Getting started](../getting-started.md) - full SvGrid walkthrough\n- [Why headless?](../why-headless.md) - the headless / render-component split\n- [Data export and printing](./export.md) - the `@svgrid/enterprise` feature pack\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](./comparison.md) - the\n measured benchmark and the feature matrix\n- [SvGrid vs AG Grid comparison page](https://svgrid.com/compare/ag-grid/) -\n every claim with its source and date\n"
|
|
4709
|
+
"markdown": "# Migrating from AG Grid to SvGrid\n\nIf you tried AG Grid on a Svelte 5 project - via `ag-grid-svelte`, the\nold `ag-grid-community/svelte`, or a hand-rolled wrapper - you probably\nhit the same friction everyone hits: the bridge between AG Grid's\nReact/Angular-first API and Svelte 5 runes is brittle, the bundle is\nheavy, and the Enterprise pricing only makes sense at scale.\n\n<!-- facts:start ag-grid -->\n> **Facts, checked 12 Sep 2026.** `ag-grid-community` 36.1.0, MIT, last published 5 Aug 2026, 12,400,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `ag-grid-community` 36.1.0 317.5 KB JS, no separate stylesheet (measured 12 Sep 2026). AG Grid pricing, as its site states it: AG Grid Community is free under MIT. AG Grid Enterprise is listed at $999 USD per developer with one year of updates and Zendesk support; the Enterprise Bundle with AG Charts Enterprise is $1,498 USD per developer (https://www.ag-grid.com/license-pricing/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/).\n<!-- facts:end -->\n\nThis page is a 30-minute migration recipe from AG Grid to SvGrid. It\ncovers what maps 1:1, what's different by design, and what you'll lose.\nWe tell you when **not** to switch at the bottom.\n\n## TL;DR\n\n| | AG Grid Community | AG Grid Enterprise | SvGrid Community | @svgrid/enterprise |\n| --- | --- | --- | --- | --- |\n| **Licence** | MIT | Commercial, per developer (the price is in the facts box above) | **MIT** | $599/dev/yr (grid) or $999/dev/yr (grid + spreadsheet + Studio) |\n| **Svelte 5 native** | No (community-built integration) | No (community-built integration) | Yes | Yes |\n| **Bundle (gzipped)** | measured, in the facts box above | not measured (licence) | measured, in the facts box above | lazy-loaded subpaths |\n| **Sorting / filtering** | Yes | Yes | Yes | (in Community) |\n| **Row grouping + aggregation** | No (Enterprise) | Yes | Yes (free) | (in Community) |\n| **Master/detail, tree, range select** | No (Enterprise) | Yes | Yes (free) | (in Community) |\n| **Set filter / Excel-style filter menu** | No (Enterprise) | Yes | Yes (free) | (in Community) |\n| **Server-side data, flat (infinite row model)** | Yes | Yes | Yes (free) | (in Community) |\n| **Server-side row model (grouping, tree, pivot, transactions, selection)** | No (Enterprise) | Yes | No | Yes |\n| **Integrated charts** | No (Enterprise) | Yes, AG Charts | Yes (free) | (in Community) |\n| **CSV export** | Yes (API) | Yes | Yes, with TSV and JSON | (in Community) |\n| **Excel export** | No | Yes | No | Yes |\n| **PDF / styled-HTML export, print** | No | No | No | Yes |\n| **Pivot tables** | No | Yes | No | Yes |\n| **MCP server for AI assistants** | Yes, `ag-mcp` | Yes | Yes, `@svgrid/mcp` | (in Community) |\n| **In-grid AI helpers** | No | No | Yes (bring your own model) | (in Community) |\n\n**SvGrid Community gives you most of what AG Grid sells as Enterprise for\nfree**, and `@svgrid/enterprise` adds Excel, PDF and print output, import,\npivot tables and the server-side row model per developer per year. Compare what each paid tier adds\nbefore comparing prices; both are in the facts box. The trade-offs are\nSvelte-only and a much smaller ecosystem. Every AG Grid cell above follows\nag-grid.com's own pages; the dated list is on the\n[SvGrid vs AG Grid](https://svgrid.com/compare/ag-grid/) page.\n\n## Mental model - what changes\n\nAG Grid is one big object you configure declaratively. SvGrid is a\n**headless engine** (`createSvGrid`) with an optional **render\ncomponent** (`<SvGrid>`) on top - the same split TanStack Table made\npopular. You can use either layer; most projects use the render\ncomponent.\n\nEvery example below runs against this setup:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature, type ColumnDef } from '@svgrid/grid'\n\n type Row = { id: number; make: string; model: string; price: number }\n\n const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n\n let rows = $state<Row[]>([\n { id: 1, make: 'Toyota', model: 'Celica', price: 35000 },\n { id: 2, make: 'Ford', model: 'Mondeo', price: 32000 },\n { id: 3, make: 'Porsche', model: 'Boxster', price: 72000 },\n ])\n const data = rows\n\n const columns: ColumnDef<typeof features, Row>[] = [\n { field: 'make', header: 'Make' },\n { field: 'model', header: 'Model' },\n { field: 'price', header: 'Price', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```svelte\n<!-- AG Grid (via a Svelte wrapper) -->\n<AgGridSvelte\n gridOptions={{\n rowData: rows,\n columnDefs: columns,\n onGridReady: (params) => (gridApi = params.api),\n }}\n/>\n\n<!-- SvGrid -->\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n onApiReady={(api) => (gridApi = api)}\n/>\n```\n\nThree things to note:\n\n1. **No giant `gridOptions` blob.** Each capability is a top-level prop.\n2. **Features are opt-in.** You pass a `features` object built with\n `tableFeatures({...})` - only the features you list ship JS.\n3. **`onApiReady`** gives you a typed `SvGridApi` that is roughly the\n AG Grid `gridApi` equivalent (see the API-mapping table below).\n\n## Column definitions - direct translation\n\nThe shapes are similar enough that you can usually translate by hand\nwithout thinking too hard.\n\n```ts\n// AG Grid\nconst columnDefs: ColDef[] = [\n { field: 'name', headerName: 'Name', sortable: true, filter: true, width: 200 },\n { field: 'price', headerName: 'Price', type: 'numericColumn',\n valueFormatter: ({ value }) => `$${value.toFixed(2)}` },\n { field: 'date', headerName: 'Date',\n valueGetter: ({ data }) => new Date(data.date).toISOString().slice(0, 10) },\n { field: 'status', headerName: 'Status',\n cellRenderer: StatusCellRenderer,\n cellRendererParams: { onChange: handleStatusChange } },\n]\n```\n\n```ts\n// SvGrid\nimport { renderComponent, type ColumnDef } from '@svgrid/grid'\nimport StatusCell from './StatusCell.svelte'\n\nconst columns: ColumnDef<typeof features, Row>[] = [\n { field: 'name', header: 'Name', width: 200 }, // sortable + filterable by default\n { field: 'price', header: 'Price',\n format: { type: 'currency', currency: 'USD' } },\n { field: 'date', header: 'Date',\n format: { type: 'date', pattern: 'y-m-d' } },\n { field: 'status', header: 'Status',\n cell: renderComponent(StatusCell, (ctx) => ({\n value: ctx.getValue(),\n onChange: handleStatusChange,\n })),\n },\n]\n```\n\n### Property mapping\n\n| AG Grid | SvGrid | Notes |\n| --- | --- | --- |\n| `field` | `field` | Same. |\n| `headerName` | `header` | Accepts a string or a snippet/component. |\n| `width` | `width` | Same. |\n| `minWidth` / `maxWidth` | `minWidth` / `maxWidth` | Same. |\n| `sortable: true` | (default) | Sorting is on when `rowSortingFeature` is registered. |\n| `filter: true` | (default) | Filtering is on when `columnFilteringFeature` is registered. |\n| `valueFormatter` | `format: { ... }` | Built-in types: `number`, `currency`, `percent`, `date`. For custom, use `cell`. |\n| `valueGetter` | `fieldFn` | Returns the value for sorting/filtering. |\n| `cellRenderer` + `cellRendererParams` | `cell: renderComponent(C, ctx => props)` | One call, type-checked. |\n| `cellEditor: 'agTextCellEditor'` | `editorType: 'text'` | Built-in: `text`, `number`, `checkbox`, `date`. |\n| `editable: true` | `enableInlineEditing` prop on `<SvGrid>` | Per-grid, not per-column. (Per-column control on the roadmap.) |\n| `pinned: 'left'` / `'right'` | Right-click column menu → Pin | Set programmatically via the api. |\n| `rowGroup: true` | Via `setGroupBy([colId])` | See Grouping below. |\n| `aggFunc: 'sum'` | `aggregate: 'sum'` | Built-in: `sum`, `avg`, `min`, `max`, `count`. |\n\n## Feature registration - the one new thing\n\nAG Grid auto-enables most features; you turn them off. SvGrid is the\nopposite - features are opt-in. The result is a smaller bundle.\n\n```ts\nimport {\n tableFeatures,\n rowSortingFeature,\n columnFilteringFeature,\n columnGroupingFeature,\n rowExpandingFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n} from '@svgrid/grid'\n\nconst features = tableFeatures({\n rowSortingFeature,\n columnFilteringFeature,\n rowSelectionFeature,\n // omit any you don't need - their code won't ship\n})\n```\n\nPass `features` to `<SvGrid>` once. From then on the grid behaves like\nAG Grid's `enableSorting`, `enableFilter`, `rowSelection`, etc. are all\non for the registered features.\n\n## API mapping (`gridApi` → `SvGridApi`)\n\nYou get the SvGrid API from `onApiReady` (equivalent to AG Grid's\n`onGridReady`).\n\n| AG Grid `gridApi.X()` | SvGrid `api.X()` |\n| --- | --- |\n| `setRowData(rows)` | (declarative - just update `data` prop) |\n| `addRow(row)` / `applyTransaction({ add: [row] })` | `api.addRow(row)` / `api.addRows(rows)` |\n| `applyTransaction({ remove: [row] })` | `api.removeRow(rowIndex)` |\n| `getValue(colId, rowNode)` | `api.getCellValue(rowIndex, columnId)` |\n| `setValue(...)` | `api.setCellValue(rowIndex, columnId, value)` |\n| `setColumnVisible(colId, visible)` | `api.setColumnVisible(columnId, visible)` |\n| `getSortModel()` / `setSortModel()` | `api.setSort(columnId, 'asc'\\|'desc'\\|null)` |\n| `setFilterModel({...})` | `api.setFilter(columnId, { operator, value })` |\n| `getDisplayedRowAtIndex(i)` / `forEachNodeAfterFilterAndSort(...)` | `api.getDisplayedRows()` |\n| `getModel()` (raw rows) | `api.getData()` |\n\n## Common patterns\n\n### Sorting + filtering + pagination (the 80% case)\n\n```svelte\n<script lang=\"ts\">\n import {\n SvGrid,\n tableFeatures,\n rowSortingFeature,\n columnFilteringFeature,\n rowPaginationFeature,\n } from '@svgrid/grid'\n\n const features = tableFeatures({\n rowSortingFeature,\n columnFilteringFeature,\n rowPaginationFeature,\n })\n</script>\n\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n showPagination\n showColumnFilters\n/>\n```\n\nAG Grid equivalent: `gridOptions: { defaultColDef: { sortable: true, filter: true }, pagination: true }`.\n\n### Cell editing with persistence\n\n```svelte\n<script lang=\"ts\">\n function onCellValueChange(e: { rowIndex: number; columnId: string; value: unknown }) {\n // Persist however you like (fetch to backend, optimistic local update, etc.)\n console.log('cell changed', e)\n }\n</script>\n\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n enableInlineEditing\n onCellValueChange={onCellValueChange}\n/>\n```\n\nAG Grid equivalent: `onCellValueChanged: ({ data, colDef, newValue, oldValue }) => ...`.\nSvGrid's event payload is column-id + row-index based rather than node-based; the row data is yours\nto mutate (or not) on the `rows` array you passed in.\n\n### Grouping + aggregation\n\n```svelte\n<script lang=\"ts\">\n import {\n SvGrid,\n tableFeatures,\n columnGroupingFeature,\n rowSortingFeature,\n rowExpandingFeature,\n } from '@svgrid/grid'\n\n const features = tableFeatures({\n rowSortingFeature,\n columnGroupingFeature,\n rowExpandingFeature,\n })\n\n const columns = [\n { field: 'department', header: 'Department' },\n { field: 'team', header: 'Team' },\n { field: 'salary', header: 'Salary', aggregate: 'sum',\n format: { type: 'currency', currency: 'USD' } },\n ]\n\n function setGroup(api) {\n api.setGroupBy(['department', 'team'])\n }\n</script>\n\n<SvGrid\n data={rows}\n columns={columns}\n features={features}\n showGroupingControls\n onApiReady={setGroup}\n/>\n```\n\nAG Grid Enterprise's `rowGroupPanelShow: 'always'` + `aggFunc: 'sum'` translates 1:1.\n\n### Master / detail\n\nAG Grid Enterprise feature; **free in SvGrid Community**. See\n[demo 08](https://svgrid.com/demos/08-tree-and-master-detail/) for the exact pattern.\n\n### Server-side data\n\nAG Grid's Infinite Row Model (Community) and Server-Side Row Model\n(Enterprise) both take an `IServerSideDatasource` with a `getRows(params)`\nthat answers through `params.success({ rowData, rowCount })`. SvGrid has one\n`ServerDataSource` whose `getRows(request)` returns `{ rows, rowCount }`,\nand two controllers over it: `createServerDataSource` (free: paging or\ninfinite block scroll, sort, filter, CRUD) and `createServerRowModel`\n(Enterprise: lazy grouping, tree, pivot, transactions, selection). Both\nmount through one prop, `<SvGrid rowModel={ctl} />`.\n\nAn existing datasource written for AG Grid keeps working behind one call:\n\n```ts\nimport { adaptCallbackDatasource, createServerRowModel } from '@svgrid/enterprise'\n\nconst ctl = createServerRowModel(adaptCallbackDatasource(myServerSideDatasource), {\n groupBy: ['country'],\n aggregations: [{ col: 'amount', fn: 'sum' }],\n})\n```\n\n`adaptCallbackDatasource` maps the request both ways (`rowGroupCols` ->\n`groupBy`, `valueCols` -> `aggregations`, `pivotCols` -> `pivotBy`, the\nsort and filter models, `context`, `parentNode`) and turns `success` /\n`fail` into a resolved or rejected promise.\n\nMore often the datasource is a thin `fetch` and the real investment is the\nendpoint behind it - a Java or Node service that parses AG Grid's\n`IServerSideGetRowsRequest` JSON. That endpoint stays as it is: post\n`toCallbackRequest(request)` and read the answer back.\n\n```ts\nimport { toCallbackRequest } from '@svgrid/enterprise'\n\nconst source = {\n async getRows(request) {\n const res = await fetch('/api/sales', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(toCallbackRequest(request)),\n })\n const { rowData, rowCount, pivotResultFields } = await res.json()\n return { rows: rowData, rowCount: rowCount ?? -1, pivotResultFields }\n },\n}\n```\n\n`fromCallbackRequest` is the other direction, for a SvelteKit endpoint that\nhas to keep serving an AG Grid client during the switch. A saved selection\nor a bulk endpoint written against `getServerSideSelectionState()` keeps\nits shape the same way: `toCallbackSelectionState(ctl.getSelectionState())`\nproduces `{ selectAll, toggledNodes }` (or the `nodeId` /\n`selectAllChildren` / `toggledNodes` tree), `ctl.setSelectionState` takes\nthat shape as it is when your group node ids are the group keys, and\n`fromCallbackSelectionState(state, { groupKey, isGroup })` maps them when\na `getRowId` gave group rows ids of their own. Option by option:\n\n| AG Grid | SvGrid |\n| --- | --- |\n| `rowModelType: 'infinite'` + `datasource` | `createServerDataSource(source, { mode: 'infinite' })` + `rowModel={ctl}` |\n| `rowModelType: 'serverSide'` + `serverSideDatasource` | `createServerRowModel(source, options)` + `rowModel={ctl}` |\n| `getRows(params)` + `params.success({ rowData, rowCount })` / `params.fail()` | `getRows(request)` returning `{ rows, rowCount }` / throwing |\n| `cacheBlockSize`, `maxBlocksInCache`, `maxConcurrentDatasourceRequests`, `blockLoadDebounceMillis` | `blockSize`, `maxBlocksInCache`, `maxConcurrentRequests`, `blockLoadDebounceMs` |\n| `infiniteInitialRowCount` / `serverSideInitialRowCount` | `initialRowCount` |\n| `rowCount: -1` (unknown) | `rowCount: -1` |\n| `refreshInfiniteCache()` / `purgeInfiniteCache()` | `ctl.refresh()` / `ctl.purge()` |\n| `request.rowGroupCols`, `groupKeys`, `valueCols`, `pivotCols`, `pivotMode` | `request.groupBy`, `groupKeys`, `aggregations`, `pivotBy`, `pivotMode` |\n| `getChildCount(data)` | `childCount: (row) => row.childCount` |\n| `isServerSideGroupOpenByDefault` | `isGroupOpenByDefault(route, row)` |\n| `getServerSideGroupLevelParams` | `levelParams(level, route)` |\n| `isServerSideGroup` / `getServerSideGroupKey` (tree) | `treeData: true` + `hasChildren` / `getRowId` |\n| `grandTotalRow` / `groupTotalRow` | `grandTotalRow` / `groupFooters` |\n| `refreshServerSide({ route, purge })` / `retryServerSideLoads()` | `ctl.refresh({ route, purge })` / `ctl.retryLoads()` |\n| `applyServerSideTransaction` / `applyServerSideTransactionAsync` / `flushServerSideAsyncTransactions` | `ctl.applyTransaction` / `applyTransactionAsync` / `flushAsyncTransactions` |\n| `applyServerSideRowData` | `ctl.applyRowData` |\n| `serverSideSortAllLevels`, `serverSideEnableClientSideSort`, `serverSideOnlyRefreshFilteredGroups` | `sortAllLevels`, `clientSideSort`, `onlyRefreshFilteredGroups` |\n| `getServerSideSelectionState` / `setServerSideSelectionState` | `ctl.getSelectionState()` / `setSelectionState()` (the `toggledNodes` shape is accepted; `toCallbackSelectionState` / `fromCallbackSelectionState` convert) |\n| `ServerSideTransactionResult.status`: `Applied`, `StoreNotFound`, `StoreLoading`, `StoreWaitingToLoad`, `StoreLoadingFailed`, `Cancelled` | `ServerTransactionResult.status`: the same six, lower camel case (`applied`, `storeNotFound`, ...) - a `switch` on the old spelling falls through silently |\n| `groupSelects: 'descendants'` | `selection: { groupSelects: 'descendants' }` |\n| `pivotResultFields` in `success`, `setPivotResultColumns`, `processPivotResultColDef` | `pivotResultFields` / `pivotResultColumns` in the result, `pivotResultColumn(field, def)` |\n| `pagination` + `paginateChildRows` | `pagination: { pageSize, paginateChildRows }` |\n| `getCacheBlockState()` / `getServerSideGroupLevelState()` | `ctl.getCacheState()` / `ctl.levelStates()` |\n| `serverSideDatasource.destroy()` | `source.destroy()` |\n\nTwo differences worth knowing before you start: SvGrid sends the global\nsearch box to the server as `filterModel.global` (AG Grid's quick filter is\nclient-side only and unsupported under its infinite and server-side models),\nand SvGrid has no viewport row model. See\n[Server grouping](./server/server-grouping.md) and\n[demo 467](https://svgrid.com/demos/467-server-row-model-1m/).\n\n### Excel / PDF export\n\nAG Grid: `gridApi.exportDataAsExcel({...})` (Enterprise-only).\nSvGrid: install `@svgrid/enterprise`, call `api.exportData({ format: 'xlsx', ... })`. See [Data export and printing](./export.md).\n\n```ts\nimport { installEnterprise, setLicenseKey } from '@svgrid/enterprise'\nsetLicenseKey('YOUR-LICENSE-KEY') // your Enterprise key\n\n// inside onApiReady:\nconst pro = installEnterprise(api)\nawait pro.exportData({ format: 'xlsx', filename: 'orders' })\n```\n\n## Gotchas - things that don't translate directly\n\n### 1. Per-column `editable: true`\nEditing is switched on at the grid level (`enableInlineEditing`) and\nnarrowed per column with `editable: boolean | (ctx) => boolean` on the\ncolumn definition, so AG Grid's per-column flag and its callback form both\nmap directly. What does not map is AG Grid's `editable` on a column\ngroup: set it on each child column.\n\n### 2. Column drag-to-reorder\nHeader drag is `enableColumnReorder` on `<SvGrid>`; `setColumnOrder`\non the API does the same from code. See\n[column moving](./columns/column-moving.md) for the events.\n\n### 3. AG Grid `valueGetter` chains\nAG Grid's `valueGetter` can read other column values via the API. In\nSvGrid, `fieldFn` only receives the row; if you need cross-column\ncomputed values, do it in the cell renderer with `ctx.row.original` or\ncompute the derived value upstream and store it in the row.\n\n### 4. `cellClass` / `rowClass` callbacks\nOn the roadmap. For now, render a wrapper element in your `cell` snippet\nwith the conditional class.\n\n### 5. The Status Bar / Side Bar / Tool Panels\nAG Grid's chrome (status bar with row count, side bar with filters and\ncolumns panels) doesn't exist in SvGrid - build it as plain Svelte\nmarkup around the grid. Most teams build their own anyway because\nAG Grid's defaults rarely match a polished design system.\n\n### 6. Set filter (the Excel-style funnel popup)\nSvGrid ships an Excel-style filter menu (free in Community). API surface\nis similar but not identical - see [Set filter](./filtering/set-filter.md).\n\n## When NOT to migrate\n\nBe honest. Stay on AG Grid if you:\n\n- **Use multiple frameworks** - AG Grid has React, Angular, Vue, Solid, Qwik, vanilla adapters. SvGrid is Svelte-only.\n- **Need a push-based viewport row model** - SvGrid's server-side row model covers grouping, tree, pivot, transactions and select-all across unloaded rows, and its real-time page merges deltas into loaded rows, but the server cannot push the visible window over a socket the way the viewport model does.\n- **Need pluggable custom filter components or custom tool panels** - SvGrid's tool panel is a fixed Columns + Filters pair.\n- **Are mid-project and shipping in <2 weeks** - the migration is a few hours per grid, but only do it when you have buffer.\n- **Have a Svelte 4 codebase you can't upgrade** - SvGrid requires Svelte 5 runes. (Consider [htmlelements.com](https://www.htmlelements.com) for vanilla / multi-framework.)\n\nIf none of those apply: switching drops a per-developer Enterprise licence\nfor features that are in SvGrid's MIT core, cuts the bundle by the\ndifference in the facts box above, and gives you a Svelte-native API that\nplays well with runes.\n\n## Step-by-step migration\n\nA typical migration of a single grid takes 1-3 hours:\n\n1. **Install** - `pnpm add @svgrid/grid` (and `@svgrid/enterprise` if you need export).\n2. **Translate columnDefs** - use the mapping table above. Most columns are 1:1.\n3. **Wrap features** - figure out which AG Grid features you actually use; register only those in `tableFeatures({...})`.\n4. **Swap the component** - `<AgGridSvelte gridOptions={...}>` → `<SvGrid data={rows} columns={columns} features={features}>`.\n5. **Move event handlers** - AG Grid `onCellValueChanged` → SvGrid `onCellValueChange` (signature differs slightly, see above).\n6. **Move API calls** - AG Grid `gridApi.X()` → SvGrid `api.X()` per the API table.\n7. **Test interactions** - sort, filter, edit, select. Most \"just works.\"\n8. **Remove `ag-grid-*` packages** - `pnpm remove ag-grid-community ag-grid-svelte` etc. Inspect your bundle to confirm the drop; the facts box above has both measured sizes.\n\n## Need help migrating?\n\nEnterprise customers get **migration help included** with the support plan\n(architecture review, port one grid for you as a reference). Email\n`support@jqwidgets.com` after purchase, or `sales@jqwidgets.com` for\npre-sales questions.\n\n## Frequently asked questions\n\n### Is SvGrid a drop-in replacement for AG Grid in Svelte?\n\nNot a literal drop-in - there is no `ag-grid-svelte` shim to swap. But the\nconcepts map closely: column definitions, row models, sorting, filtering,\ngrouping, and an imperative API all have direct SvGrid equivalents, so most\nteams port a grid in 30 minutes to a day. It is a configuration translation,\nnot a rewrite.\n\n### What is the SvGrid equivalent of AG Grid Enterprise?\n\n`@svgrid/enterprise`. It adds Excel/PDF/styled-HTML export (CSV, TSV and JSON export are already free in the grid), a printable view, pivot\ntables and data import. The in-grid AI helpers are free in `@svgrid/grid`.\nIt is licensed per developer ($599 for the grid, $999 with the spreadsheet\nand Studio, both covering unlimited apps), and the\nCommunity package is MIT-licensed and free for commercial use.\n\n### Does SvGrid use Svelte 5 runes, or is it a wrapper?\n\nIt is Svelte-5-native. State is `$state` / `$derived` / `$effect` and cells\nrender through Svelte snippets - there is no React or Angular core underneath\nand no framework bridge to keep in sync.\n\n### Will my AG Grid bundle size shrink?\n\nAlmost always. The facts box at the top of this page has both packages\nmeasured the same way on the same date: the full SvGrid render component\nwith its stylesheet against `createGrid` with every AG Grid Community\nmodule registered. You add `@svgrid/enterprise` features only where you\nimport them, and the headless core on its own is a small fraction of the\nrender component.\n\n## More examples\n\n### AG Grid ↔ sv-grid side-by-side\n\nTwo real grids over the same dataset: the installed AG Grid Community on the left, sv-grid on the right. Same global filter drives both. Source code panels for either side.\n\n<div data-docs-demo=\"139-migration-from-ag-grid\" data-height=\"460\"></div>\n\n## See also\n\n- [Getting started](../getting-started.md) - full SvGrid walkthrough\n- [Why headless?](../why-headless.md) - the headless / render-component split\n- [Data export and printing](./export.md) - the `@svgrid/enterprise` feature pack\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](./comparison.md) - the\n measured benchmark and the feature matrix\n- [SvGrid vs AG Grid comparison page](https://svgrid.com/compare/ag-grid/) -\n every claim with its source and date\n"
|
|
4710
4710
|
},
|
|
4711
4711
|
{
|
|
4712
4712
|
"slug": "help/migrating-from-devextreme",
|
|
4713
4713
|
"path": "docs/help/migrating-from-devextreme.md",
|
|
4714
4714
|
"title": "Migrating from DevExtreme DataGrid (DevExpress)",
|
|
4715
4715
|
"section": "Help",
|
|
4716
|
-
"markdown": "# Migrating from DevExtreme DataGrid (DevExpress)\n\nDevExtreme DataGrid is a deep, commercial multi-framework grid from\nDevExpress (jQuery, React, Vue, Angular). Moving to SvGrid trades the\ncommercial suite for a Svelte-5-native grid with an MIT core and a far\nlower-cost paid tier.\n\n> Estimated effort: **3-6 hours** per grid.\n>\n> DevExtreme's option names vary by framework flavour; map your version's\n> columns and events onto the SvGrid equivalents below.\n\n<!-- facts:start devextreme-datagrid -->\n> **Facts, checked 12 Sep 2026.** `devextreme` 26.1.4, Commercial (see licence file), last published 7 Aug 2026, 1,180,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). DevExtreme DataGrid pricing, as its site states it: js.devexpress.com lists DevExtreme Complete at $899.99 per developer for a 12-month subscription with updates and support, renewing at $449.99; no free or non-commercial tier is shown (https://js.devexpress.com/Buy/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4716
|
+
"markdown": "# Migrating from DevExtreme DataGrid (DevExpress)\n\nDevExtreme DataGrid is a deep, commercial multi-framework grid from\nDevExpress (jQuery, React, Vue, Angular). Moving to SvGrid trades the\ncommercial suite for a Svelte-5-native grid with an MIT core and a far\nlower-cost paid tier.\n\n> Estimated effort: **3-6 hours** per grid.\n>\n> DevExtreme's option names vary by framework flavour; map your version's\n> columns and events onto the SvGrid equivalents below.\n\n<!-- facts:start devextreme-datagrid -->\n> **Facts, checked 12 Sep 2026.** `devextreme` 26.1.4, Commercial (see licence file), last published 7 Aug 2026, 1,180,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). DevExtreme DataGrid pricing, as its site states it: js.devexpress.com lists DevExtreme Complete at $899.99 per developer for a 12-month subscription with updates and support, renewing at $449.99; no free or non-commercial tier is shown (https://js.devexpress.com/Buy/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs DevExtreme DataGrid (DevExpress)](https://svgrid.com/compare/devextreme-datagrid/).\n<!-- facts:end -->\n\n## Concept map\n\n| DevExtreme DataGrid | sv-grid |\n| ---------------------------------------- | ----------------------------------------- |\n| `columns: [{ dataField, caption }]` | `columns: [{ field, header }]` |\n| `cellTemplate` | `cell: (c) => renderSnippet(...)` |\n| `editing: { mode, allowUpdating }` | `enableInlineEditing` + `editorType` |\n| `sorting` / `filterRow` / `headerFilter` | `rowSortingFeature` / `columnFilteringFeature` |\n| `grouping` + `summary` | `columnGroupingFeature` + aggregates |\n| `masterDetail` | `rowExpandingFeature` / master-detail rows |\n| `dataSource` (store / remote) | `data` array or `externalSort/Filter` |\n| `paging` + `pager` | `showPagination` |\n| `export` | `@svgrid/enterprise` export pack |\n| `stateStoring` | persist column state yourself (saved views) |\n\n## Shape of the change\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- $('#grid').dxDataGrid({\n- dataSource: rows,\n- paging: { pageSize: 25 },\n- sorting: { mode: 'multiple' }, filterRow: { visible: true },\n- editing: { mode: 'cell', allowUpdating: true },\n- columns: [\n- { dataField: 'name', caption: 'Name' },\n- { dataField: 'amount', caption: 'Amount', format: 'currency' },\n- ],\n- })\n\n+ <SvGrid\n+ data={rows}\n+ columns={[\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]}\n+ features={tableFeatures({ rowSortingFeature, columnFilteringFeature })}\n+ showPagination enableInlineEditing />\n```\n\n## Why teams switch\n\n- **Svelte 5 native** instead of a multi-framework commercial library.\n- **MIT community core** plus an optional Enterprise pack for export / import /\n pivot / AI.\n- **Much lower-cost paid tier.**\n\n## What to weigh\n\n- DevExtreme has a **larger built-in feature surface** (state storing,\n broad export, a full suite). If you depend on those, factor them in -\n `stateStoring` in particular becomes a saved-views pattern you wire up.\n\n## Frequently asked questions\n\n### How do DevExtreme columns map to SvGrid?\n\n`dataField` becomes `field`, `caption` becomes `header`, and `cellTemplate`\nbecomes a `renderSnippet` cell. Sorting / filtering / grouping move from grid\noptions to registered features.\n\n### Is SvGrid cheaper than DevExtreme?\n\nFor a Svelte stack, yes - the core is MIT and the paid tier is far below\ncommercial-suite pricing. You give up DevExtreme's multi-framework reach and\nsome built-in features like `stateStoring`.\n\n### Does SvGrid export like DevExtreme?\n\nYes, via the `@svgrid/enterprise` pack: Excel, PDF, CSV, TSV, and HTML export plus a\nprintable view.\n\n## What you end up with\n\nGrouping with totals plus the filter row, the DevExtreme default layout.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} groupBy={['department']} summary groupable sortable filterMode=\"row\" />\n```\n\n## See also\n\n- [SvGrid vs DevExtreme DataGrid](https://svgrid.com/compare/devextreme-datagrid/) - the side-by-side comparison\n- [Saved views](./saved-views.md) - the state-persistence pattern\n- [Data export and printing - Enterprise](./export.md) - the Enterprise export pack\n"
|
|
4717
4717
|
},
|
|
4718
4718
|
{
|
|
4719
4719
|
"slug": "help/migrating-from-glide",
|
|
4720
4720
|
"path": "docs/help/migrating-from-glide.md",
|
|
4721
4721
|
"title": "Migrating from Glide Data Grid",
|
|
4722
4722
|
"section": "Help",
|
|
4723
|
-
"markdown": "# Migrating from Glide Data Grid\n\nGlide Data Grid is the canvas-rendered, ultra-high-performance choice\nfor very wide datasets (100k+ rows, 100+ columns). Sv-grid renders to\nDOM with virtualization, which trades peak FPS for\naccessibility + standards-compliant HTML.\n\n> Estimated effort: **3-6 hours** per grid. Glide's getCellContent /\n> onCellEdited cell-data model is the opposite of sv-grid's\n> data-array model; the mental flip takes the most time.\n\n<!-- facts:start glide-data-grid -->\n> **Facts, checked 12 Sep 2026.** `@glideapps/glide-data-grid` 6.0.3, MIT, last published 3 Feb 2024, 1,180,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@glideapps/glide-data-grid` 6.0.3 71.1 KB JS + 0.2 KB CSS, lodash + marked + react + react-dom + react-responsive-carousel external (measured 12 Sep 2026). Glide Data Grid pricing, as its site states it: Glide Data Grid is MIT and, in its own words, fully free and open source; no licence is sold for the grid (https://grid.glideapps.com/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4723
|
+
"markdown": "# Migrating from Glide Data Grid\n\nGlide Data Grid is the canvas-rendered, ultra-high-performance choice\nfor very wide datasets (100k+ rows, 100+ columns). Sv-grid renders to\nDOM with virtualization, which trades peak FPS for\naccessibility + standards-compliant HTML.\n\n> Estimated effort: **3-6 hours** per grid. Glide's getCellContent /\n> onCellEdited cell-data model is the opposite of sv-grid's\n> data-array model; the mental flip takes the most time.\n\n<!-- facts:start glide-data-grid -->\n> **Facts, checked 12 Sep 2026.** `@glideapps/glide-data-grid` 6.0.3, MIT, last published 3 Feb 2024, 1,180,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@glideapps/glide-data-grid` 6.0.3 71.1 KB JS + 0.2 KB CSS, lodash + marked + react + react-dom + react-responsive-carousel external (measured 12 Sep 2026). Glide Data Grid pricing, as its site states it: Glide Data Grid is MIT and, in its own words, fully free and open source; no licence is sold for the grid (https://grid.glideapps.com/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs Glide Data Grid](https://svgrid.com/compare/glide-data-grid/).\n<!-- facts:end -->\n\n## Mental-model flip\n\nGlide gives you a **canvas + a `getCellContent` callback**: the grid\nasks you for each visible cell on demand. Sv-grid wants the\n**whole data array up front** (`<SvGrid data={rows}>`); the engine\nslices for virtualization.\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- function getCellContent([col, row]) {\n- const r = rows[row]\n- if (col === 0) return { kind: 'text', data: r.name, displayData: r.name, allowOverlay: true }\n- if (col === 1) return { kind: 'number', data: r.amount, displayData: fmt(r.amount), allowOverlay: true }\n- }\n- <DataEditor columns={[...]} getCellContent={getCellContent} rows={rows.length} />\n\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name', editorType: 'text' },\n+ { field: 'amount', header: 'Amount', editorType: 'number',\n+ format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ <SvGrid data={rows} columns={columns} features={features} />\n```\n\nThis change is **good** for 99% of apps: it's less code, less risk\nof typos in cell coordinates, full TypeScript type checking on the\nrow shape. For the 1% of apps with rows that don't fit in memory,\nsee \"Out-of-memory data\" below.\n\n## Cell editing\n\n```diff\n- function onCellEdited([col, row], newValue) {\n- rows[row] = { ...rows[row], [colToField(col)]: newValue.data }\n- }\n- <DataEditor onCellEdited={onCellEdited} />\n\n+ <SvGrid\n+ data={rows} columns={columns} features={features}\n+ onCellValueChange={(e) => {\n+ rows[e.rowIndex] = { ...rows[e.rowIndex], [e.columnId]: e.newValue }\n+ }}\n+ />\n```\n\nYou can also rely on sv-grid's built-in write-back if `data` is a\nSvelte 5 `$state` array - mutations propagate automatically.\n\n## Sorting + filtering\n\nGlide doesn't ship sort / filter UI; you wrap your own. Sv-grid\nships them:\n\n```diff\n- // Build your own sort buttons in the toolbar; sort rows yourself.\n\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ <SvGrid data={rows} columns={columns} features={features} filterMode=\"menu\" />\n```\n\n## Frozen columns / row markers\n\n| Glide | sv-grid |\n| -------------------------------------- | --------------------------------------------- |\n| `freezeColumns={1}` | `api.setColumnPinning({ left: ['firstColId'] })` |\n| `rowMarkers=\"number\"` | `showRowNumbers={true}` prop |\n| `rowMarkers=\"checkbox\"` | `selectionMode=\"row\"` prop |\n\n## Custom drawing → custom snippets\n\nGlide's `drawCustomCell` lets you render anything via canvas. The\nsv-grid equivalent is a Svelte snippet (DOM):\n\n```diff\n- drawCustomCell(args) {\n- const ctx = args.ctx\n- ctx.fillStyle = args.cell.data.color\n- ctx.fillRect(args.rect.x, args.rect.y, args.rect.width, args.rect.height)\n- return true\n- }\n\n+ {\n+ field: 'color',\n+ cell: (ctx) => renderSnippet(ColorChip, { color: ctx.row.original.color }),\n+ }\n```\n\n```svelte\n{#snippet ColorChip(props)}\n <span style=\"display: inline-block; width: 18px; height: 18px; background: {props.color};\"></span>\n{/snippet}\n```\n\n## Out-of-memory data\n\nFor \"10M rows, fetched on scroll\" workloads (the only case Glide\ngenuinely beats sv-grid on), use sv-grid's\n[server-side / infinite-scroll pattern](./server-side-data.md):\n\n```svelte\n<SvGrid\n data={loadedSlice}\n columns={columns} features={features}\n externalSort={true}\n externalFilter={true}\n onSortingChange={async (s) => { loadedSlice = await fetchPage({ sort: s, offset: 0, limit: 200 }) }}\n/>\n```\n\nYou'll cap practical perf at ~100k rendered rows; for true 10M+\ndatasets Glide's canvas approach has a perf edge sv-grid won't\nmatch. Most apps don't need 10M rows on screen at once - they need\nfast server-side filtering, which both libraries support equally.\n\n## Theming\n\nGlide: huge `theme` prop object. Sv-grid: CSS custom properties (`--sg-*`).\n\n```diff\n- <DataEditor theme={{\n- accentColor: '#4F5DFF',\n- accentLight: 'rgba(62, 116, 253, 0.2)',\n- bgCell: '#1c1c20',\n- /* …40 more properties… */\n- }} />\n\n+ <div style=\"--sg-accent: #4F5DFF; --sg-bg: #1c1c20;\">\n+ <SvGrid {data} {columns} features={features} />\n+ </div>\n```\n\nSee [design tokens](./tokens.md) for the full list (≤ 30 tokens\ncovers everything; Glide's theme has ~40).\n\n## What you get for free vs Glide\n\n- **Accessibility.** Glide's canvas is invisible to screen readers\n unless you build an off-screen ARIA buffer. Sv-grid is WAI-ARIA\n 1.2 grid pattern out of the box; demo 17 covers axe-core CI.\n- **Standard HTML.** SEO crawlers, browser Find-in-Page, browser\n zoom, OS-level text scaling - all work because the grid emits\n actual `<table><tr><td>`.\n- **Familiar editing.** Browser-native `<input>` / `<select>` for\n cells, with autofill / clipboard / autocorrect intact.\n- **Built-in sort / filter / pagination UI.**\n\n## What you give up\n\n- **Peak FPS on >200k visible rows.** Canvas wins here. For most\n apps the gap is invisible; if you've actually measured it on real\n hardware and need the FPS, Glide remains the right call.\n- **Per-pixel cell drawing.** DOM cells are sub-pixel-uniform but\n not arbitrarily drawn.\n\n## Frequently asked questions\n\n### Should I move from Glide Data Grid to SvGrid?\n\nMove if you need accessibility, standards-compliant HTML, SEO-friendly markup,\nor DOM-based custom cells. Stay on Glide only if you have measured a need for\npeak canvas FPS on 200k+ simultaneously visible rows. For most apps the\nperformance gap is invisible, and SvGrid virtualizes comfortably to 100k+ rows.\n\n### How long does a Glide migration take?\n\nAbout 3-6 hours per grid. The biggest shift is conceptual: Glide's\n`getCellContent` / `onCellEdited` cell-data model is the inverse of SvGrid's\nplain data-array model, so the mental flip takes the most time, not the code.\n\n### Does SvGrid render to canvas or DOM?\n\nDOM, with row and column virtualization. That is what gives you WAI-ARIA roles,\nkeyboard navigation, screen-reader support, and selectable/indexable text -\nthings a canvas grid like Glide cannot offer.\n\n## What you end up with\n\nInline editing over a virtualized body, without a canvas to draw into.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} editable enableCellSelection sortable />\n```\n\n## See also\n\n- [SvGrid vs Glide Data Grid](https://svgrid.com/compare/glide-data-grid/) - the side-by-side comparison\n- [Performance benchmarks](./benchmarks.md) - measured numbers\n- [Server-side data](./server-side-data.md) - the >100k-row pattern\n- [Accessibility](./accessibility.md) - the standards compliance Glide doesn't ship\n"
|
|
4724
4724
|
},
|
|
4725
4725
|
{
|
|
4726
4726
|
"slug": "help/migrating-from-gridjs",
|
|
4727
4727
|
"path": "docs/help/migrating-from-gridjs.md",
|
|
4728
4728
|
"title": "Migrating from Grid.js",
|
|
4729
4729
|
"section": "Help",
|
|
4730
|
-
"markdown": "# Migrating from Grid.js\n\nGrid.js is a small vanilla-JS table for search, sort, and pagination\nthat you render into a DOM element. SvGrid does the same in a\nSvelte-5-native component and keeps going - virtualization, Excel-style\nfilters, editing, grouping - when you outgrow the basics.\n\n> Estimated effort: **30 min - 1 hour** per table.\n\n<!-- facts:start gridjs -->\n> **Facts, checked 12 Sep 2026.** `gridjs` 6.2.0, MIT, last published 3 Mar 2024, 161,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `gridjs` 6.2.0 17.8 KB JS + 2.4 KB CSS (measured 12 Sep 2026). Grid.js pricing, as its site states it: Grid.js is MIT, free and open source; no licence is sold (https://gridjs.io/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4730
|
+
"markdown": "# Migrating from Grid.js\n\nGrid.js is a small vanilla-JS table for search, sort, and pagination\nthat you render into a DOM element. SvGrid does the same in a\nSvelte-5-native component and keeps going - virtualization, Excel-style\nfilters, editing, grouping - when you outgrow the basics.\n\n> Estimated effort: **30 min - 1 hour** per table.\n\n<!-- facts:start gridjs -->\n> **Facts, checked 12 Sep 2026.** `gridjs` 6.2.0, MIT, last published 3 Mar 2024, 161,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `gridjs` 6.2.0 17.8 KB JS + 2.4 KB CSS (measured 12 Sep 2026). Grid.js pricing, as its site states it: Grid.js is MIT, free and open source; no licence is sold (https://gridjs.io/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs Grid.js](https://svgrid.com/compare/gridjs/).\n<!-- facts:end -->\n\n## Vocabulary cheat sheet\n\n| Grid.js | sv-grid |\n| ----------------------------------------- | ----------------------------------------- |\n| `new Grid({ ... }).render(el)` | `<SvGrid ... />` |\n| `columns: ['Name', 'Amount']` | `columns: [{ field, header }]` |\n| `columns: [{ name, formatter }]` | `{ header, cell: (c) => renderSnippet(...) }` |\n| `sort: true` | `rowSortingFeature` |\n| `search: true` | `api.setState({ globalFilter: query })` / filter feature |\n| `pagination: { limit: 25 }` | `showPagination` (+ page size) |\n| `server: { url, then }` | `externalSort` / `externalFilter` + refetch |\n\n## Before / after\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import { Grid } from 'gridjs'\n- import 'gridjs/dist/theme/mermaid.css'\n-\n- new Grid({\n- data: rows,\n- columns: ['Name', 'Amount'],\n- sort: true, search: true,\n- pagination: { limit: 25 },\n- }).render(document.getElementById('grid'))\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} showPagination />\n```\n\n## What you gain\n\n- **Virtualization** for large datasets (Grid.js renders the page).\n- **Excel-style filter menu**, **inline editing**, **grouping**, and\n **tree / master-detail** when you need them.\n- **Reactive data** - no `.render(el)` re-instantiation.\n- A **headless engine** and an **imperative API** plus `@svgrid/mcp`.\n\n## Frequently asked questions\n\n### When should I move from Grid.js to SvGrid?\n\nWhen you need more than search / sort / paginate - virtualization for big\ndatasets, inline editing, Excel-style filters, grouping, or tree data. For a\nsmall table, Grid.js stays lighter.\n\n### Is SvGrid MIT-licensed like Grid.js?\n\nYes. `@svgrid/grid` is MIT. Only the optional `@svgrid/enterprise` add-on is paid.\n\n### Does SvGrid support server-side data like Grid.js?\n\nYes. Set `externalSort` / `externalFilter` and refetch on the\n`onSortingChange` / `onFiltersChange` events.\n\n## What you end up with\n\nSearch, sort and pagination - the whole Grid.js surface, plus editing.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable pageable pageSize={3} editable />\n```\n\n## See also\n\n- [SvGrid vs Grid.js](https://svgrid.com/compare/gridjs/) - the side-by-side comparison\n- [Getting started](../getting-started.md) - a working grid in ~15 lines\n- [Server-side data](./server-side-data.md) - the external-data pattern\n"
|
|
4731
4731
|
},
|
|
4732
4732
|
{
|
|
4733
4733
|
"slug": "help/migrating-from-handsontable",
|
|
4734
4734
|
"path": "docs/help/migrating-from-handsontable.md",
|
|
4735
4735
|
"title": "Migrating from Handsontable",
|
|
4736
4736
|
"section": "Help",
|
|
4737
|
-
"markdown": "# Migrating from Handsontable\n\nHandsontable's mental model is \"spreadsheet-in-a-page\": every cell\neditable, formulas, copy/paste with the OS clipboard, frozen rows\nand columns. Sv-grid covers ~90% of the same surface; the port is\nmostly a configuration translation, except for HyperFormula (see\nthe Formulas section below).\n\n> Estimated effort: **2-4 hours** per grid for typical spreadsheet\n> workflows. **Add 1-2 days** if you depend heavily on\n> HyperFormula features sv-grid doesn't ship.\n\n<!-- facts:start handsontable -->\n> **Facts, checked 12 Sep 2026.** `handsontable` 18.1.0, Commercial (see licence file), last published 1 Sep 2026, 1,190,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Handsontable pricing, as its site states it: Handsontable's Hobby licence is free for personal, exploratory projects and cannot be used in commercial settings; handsontable.com lists Standard from $999 per developer and Priority from $1,299 per developer, with Enterprise on custom terms (https://handsontable.com/pricing, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs Handsontable](https://svgrid.com/compare/handsontable/).\n<!-- facts:end -->\n\n## Imports\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import Handsontable from 'handsontable'\n- import 'handsontable/dist/handsontable.full.min.css'\n\n+ import {\n+ SvGrid, tableFeatures,\n+ rowSortingFeature, columnFilteringFeature, rowSelectionFeature,\n+ + } from '@svgrid/grid'\n```\n\n## Schema → columns\n\nHandsontable accepts a 2D array OR an array of objects. Sv-grid\nexpects the array-of-objects form:\n\n```diff\n- const hot = new Handsontable(container, {\n- data: [\n- ['Tesla', 2017, 'black', false],\n- ['Nissan', 2018, 'blue', true ],\n- ],\n- colHeaders: ['Make', 'Year', 'Color', 'In stock'],\n- columns: [\n- {},\n- { type: 'numeric' },\n- {},\n- { type: 'checkbox' },\n- ],\n- })\n\n+ type Car = { make: string; year: number; color: string; inStock: boolean }\n+ const rows: Car[] = [\n+ { make: 'Tesla', year: 2017, color: 'black', inStock: false },\n+ { make: 'Nissan', year: 2018, color: 'blue', inStock: true },\n+ ]\n+ const columns: ColumnDef<typeof features, Car>[] = [\n+ { field: 'make', header: 'Make' },\n+ { field: 'year', header: 'Year', editorType: 'number' },\n+ { field: 'color', header: 'Color' },\n+ { field: 'inStock', header: 'In stock', editorType: 'checkbox' },\n+ ]\n+ <SvGrid data={rows} columns={columns} features={features} />\n```\n\nIf your existing data is a 2D array, transform once at boot:\n\n```ts\nconst headerRow = raw[0]\nconst rows = raw.slice(1).map((cells) =>\n Object.fromEntries(cells.map((v, i) => [headerRow[i], v])),\n)\n```\n\n## Editor types\n\n| Handsontable | sv-grid |\n| ---------------------------------------------- | ------------------------------------------------ |\n| `type: 'text'` | `editorType: 'text'` |\n| `type: 'numeric'` | `editorType: 'number'` |\n| `type: 'date'` | `editorType: 'date'` |\n| `type: 'checkbox'` | `editorType: 'checkbox'` |\n| `type: 'dropdown', source: [...]` | `editorType: 'list', editorOptions: [...]` |\n| `type: 'autocomplete'` | `editorType: 'list'` (combobox UI ships) |\n| `type: 'time'` | `editorType: 'time'` |\n| `type: 'password'` | Use `editorType: 'text'` + a custom snippet |\n\n## Selection + clipboard\n\n| Handsontable | sv-grid |\n| --------------------------------------- | ------------------------------------------------------- |\n| `selectCells([[0,0,2,5]])` | `api.selectCells(ranges)`, with `selectionMode='cell'` |\n| `getSelected()` | `api.getSelected()`: the same `[[startRow, startCol, endRow, endCol], ...]`, normalised to top-left / bottom-right and `[]` rather than `undefined` when nothing is selected |\n| `getSelectedLast()` | `api.getSelectedLast()`: `[startRow, startCol, endRow, endCol]` with the orientation kept (a range dragged upwards has `startRow > endRow`), or `undefined` |\n| `getSelectedRange()` / `getSelectedRangeLast()` | `api.getSelectedRange()` / `api.getSelectedRangeLast()`: `{ from, to, highlight }` per rectangle, the same three fields as `CellRange`; plain data rather than a class, so use `Math.min` / `Math.max` for the corners |\n| `copyPaste: true` (default) | Ships built-in; `enableCellSelection={true}`. The spreadsheet shell also exchanges formats, number formats and formulas with Excel and Google Sheets through the HTML clipboard |\n| `fillHandle: true` | Ships built-in (drag-to-fill on selected range) |\n| `moveCells: true` | `moveCells` - drag the range border to move it, Ctrl / Cmd to copy. On by default; see [move or copy a range](./editing/move-cells.md) |\n\n## Frozen rows / columns\n\n| Handsontable | sv-grid |\n| ---------------------------------- | ------------------------------------------------------ |\n| `fixedColumnsStart: 2` | `api.setColumnPinning({ left: ['firstColId', 'secondColId'] })` |\n| `fixedRowsTop: 1` | `pinnedTopRows` (and `pinnedBottomRows`) |\n| `manualColumnFreeze: true` | Ships via the column-header right-click menu |\n| `mergeCells: [{ row, col, rowspan, colspan }]` | `mergedCells={[{ rowIndex, colIndex, rowSpan, colSpan }]}` on `<SvGrid>`; the spreadsheet shell adds Merge & Center, Merge Across, Merge Cells and Unmerge on the ribbon and the cell menu |\n\nFreeze panes on a plain `<SvGrid>`: two pinned columns and the sticky\nletter and number headers, with formulas underneath.\n\n<div data-docs-demo=\"208-freeze-panes\" data-height=\"520\"></div>\n\n## Hooks → callbacks\n\n| Handsontable hook | sv-grid |\n| -------------------------------------- | ------------------------------------------------------- |\n| `afterChange((changes, src) => {})` | `onCellValueChange((e) => {...})` |\n| `afterSelection(...)` | `onActiveCellChange((cell) => {...})` |\n| `afterFilter(...)` | `onFiltersChange((f) => {...})` |\n| `afterColumnSort(...)` | `onSortingChange((s) => {...})` |\n| `beforeChange((changes) => false)` | Throw / return `false` from your inline validator; see [validation](./editing/validation.md) |\n| `afterCreateRow / afterRemoveRow` | Wrap `api.addRow / removeRow` in your own emitter; on the spreadsheet shell, `onChange` reports a `structure` reason with the edit |\n| `afterMergeCells / afterUnmergeCells` | On the spreadsheet shell, `onChange` reports `merges`; `api.getMergedCells()` reads the grid's list |\n| `afterSetCellMeta` (comments, validation) | `onChange` reports `comments`, `validation`, `conditional-formats` and `protection` on the shell |\n| `afterFilter` (the Filters plugin) | `onChange` reports `filter` on the shell; `getState().sheets[name].autoFilter` is the state |\n\nOn the spreadsheet shell (`<SvSheet>` in `@svgrid/enterprise`) one callback\ncovers the lot: `onChange(reasons)` fires once per tick with every kind of\nchange since the last call (`cells`, `formats`, `sizes`, `hidden`,\n`freeze`, `sheets`, `comments`, `protection`, `validation`,\n`conditional-formats`, `merges`, `filter`, `structure` with the insert or\ndelete, `restore`), which is where Handsontable's `afterChange` autosave\ngoes. `getState()` gives the document to save and `setState()` puts it back.\n\n## Cell meta → the sheet document\n\nHandsontable keeps comments, validators, read-only flags and merges as cell\nmeta on the instance. On the spreadsheet shell they are parts of the\ndocument, per sheet, saved with it and moved by inserts and deletes:\n\n| Handsontable | sv-grid spreadsheet shell |\n| --------------------------------------------------- | --------------------------------------------------------------- |\n| `comments: true`, `cell: [{ row, col, comment }]` | Review > New Comment, Shift+F2, the cell menu; `getState().sheets[name].comments` |\n| `validator: 'numeric'`, `allowInvalid: false` | Data > Data Validation (Whole number, Decimal, List, Date, Text length, Custom), Stop or Warning; `validation` in the state |\n| `readOnly: true` on a cell | Format Cells > Protection unlocks the cells that may change, Review > Protect Sheet locks the rest; `locked: false` in the format entry, `protected` per sheet |\n| `mergeCells` | Merge & Center on the ribbon and the cell menu; `merges` in the state |\n| `filters: true` + `dropdownMenu` | Ctrl+Shift+L or Data > Filter: Excel's AutoFilter arrows and menus; `autoFilter` in the state |\n| conditional formatting (a custom renderer) | Home > Styles > Conditional Formatting: Highlight Cells, Top/Bottom, Data Bars, Color Scales, Icon Sets, Manage Rules; `conditionalFormats` in the state |\n| `autofill` rules | The fill handle's own series: numbers, dates by day or by the set gap, `Item 1`, weekdays and months |\n\nOn a plain `<SvGrid>` the free grid has the primitives instead: `notes`\nand `editableComments` for comments, `editable` and `valueParser` on a\ncolumn for read-only cells and validation, `mergedCells` for merges, the\nfilter row and its Excel-style menu for filtering, and value-driven\n`conditionalFormats` by column.\n\n## Formulas (HyperFormula)\n\nSv-grid ships a focused subset under\n[`spreadsheet-formulas`](./spreadsheet-formulas.md) (SUM, IF, COUNTIF\n+ cell refs + ranges + cycle detection). It does NOT ship the full\nHyperFormula library.\n\nIf you need HyperFormula's full surface (~400 functions, complex\ndate math, R1C1 refs), the integration pattern is:\n\n```ts\nimport { HyperFormula } from 'hyperformula'\n\nconst hf = HyperFormula.buildFromArray(rowsAsMatrix, { licenseKey: 'gpl-v3' })\n\n// On every cell edit, push to HF + read back the computed value:\nfunction onCellValueChange(e) {\n hf.setCellContents({ sheet: 0, row: e.rowIndex, col: columnIndex }, e.newValue)\n // ...read computed cells you depend on + push back via api.setCellValue\n}\n```\n\nThis is the only piece where the swap isn't 1:1. Most teams find\nsv-grid's shipped subset covers 80% of real-world formula usage; if\nyours is in the 20%, HyperFormula plugs in with the pattern above.\n\n## Licence\n\nHandsontable's grid needs a commercial licence for commercial use; its free\nHobby licence is for personal, exploratory projects, as its pricing page\nstates (the wording and the date are in the facts box at the top of this\npage). Sv-grid's `@svgrid/grid` is MIT with no licence key, and the\n[Enterprise tier](../enterprise/licensing.md) needs no key to evaluate:\nit works without one and displays a watermark and a console\nmessage until you add one, so there is no cutoff to plan around.\n\n## What you get for free vs Handsontable\n\n- **No commercial licence for the grid.** @svgrid/grid is MIT.\n- **Modern Svelte 5 ergonomics.** `$state` arrays beat\n `loadData(...)`.\n- **Grid features a spreadsheet does not have.** Row grouping with\n aggregation, master/detail, server-side data (grouping, tree, pivot and transactions on the server are Enterprise) and integrated\n charts in the same package.\n- **CSP-clean.** Handsontable's HyperFormula path needs CSP `eval`\n exceptions in some configurations.\n\n## What you give up\n\n- **Full HyperFormula surface as a supported feature.** Sv-grid ships a\n subset and lets you wire HyperFormula yourself; see above.\n- **Nested headers.** Handsontable's `nestedHeaders` have no\n counterpart beyond column groups.\n- **Threaded comments and a validation Input Message.** Comments on the\n shell are Excel's notes, one text per cell; validation shows its message\n on a refusal, not on arrival.\n- **Excel export without a paid pack.** Handsontable's export plugin writes\n XLSX through its asynchronous method; on sv-grid, CSV, TSV and JSON export\n are free and Excel, PDF and print output are in `@svgrid/enterprise`.\n\n## Frequently asked questions\n\n### Can SvGrid replace Handsontable's spreadsheet features?\n\nIt covers roughly 90% of the surface - inline editing on every cell, copy/paste\nas TSV, range selection, column groups, and a built-in formula engine. Budget\n2-4 hours per grid for typical spreadsheet workflows, plus 1-2 days if you lean\nheavily on the full HyperFormula function set.\n\n### Does SvGrid support formulas like Handsontable?\n\nYes, a built-in formula engine with cell references, ranges, and common\nfunctions (see the spreadsheet-formulas guide and demo 27). It is a practical\nsubset rather than the complete HyperFormula library, so verify your specific\nfunctions before porting.\n\n### Is SvGrid licensed like Handsontable?\n\nNo. The `@svgrid/grid` core is MIT and free for commercial use - no per-seat\nlicence key - whereas Handsontable's free licence excludes commercial use and\nits commercial plans are per developer; the facts box has the statement as\nread from handsontable.com. The optional `@svgrid/enterprise` pack (Excel and\nPDF export, print, pivot, import) is priced per developer.\n\n### Does SvGrid have a blank spreadsheet like Handsontable?\n\nYes, on the plain grid: column-letter headers, a row gutter, a name box\nand formula bar, gridlines, range selection and a fill handle, with\nHyperFormula underneath when you want its function library.\n\n<div data-docs-demo=\"207-blank-sheet\" data-height=\"560\"></div>\n\n## What you end up with\n\nSpreadsheet behaviour: inline edit, drag a cell range, copy it out as TSV.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} editable enableCellSelection statusBar />\n```\n\n## See also\n\n- [SvGrid vs Handsontable](https://svgrid.com/compare/handsontable/) - the side-by-side comparison, with a source and date for every claim\n- [Spreadsheet formulas](./spreadsheet-formulas.md) - sv-grid's\n built-in formula engine, and the rest of the spreadsheet demos\n- [Demo 27 (Spreadsheet + Ribbon)](https://svgrid.com/demos/27-spreadsheet-ribbon/) - live\n- [Migrating from AG Grid](./migrating-from-ag-grid.md)\n"
|
|
4737
|
+
"markdown": "# Migrating from Handsontable\n\nHandsontable's mental model is \"spreadsheet-in-a-page\": every cell\neditable, formulas, copy/paste with the OS clipboard, frozen rows\nand columns. Sv-grid covers ~90% of the same surface; the port is\nmostly a configuration translation, except for HyperFormula (see\nthe Formulas section below).\n\n> Estimated effort: **2-4 hours** per grid for typical spreadsheet\n> workflows. **Add 1-2 days** if you depend heavily on\n> HyperFormula features sv-grid doesn't ship.\n\n<!-- facts:start handsontable -->\n> **Facts, checked 12 Sep 2026.** `handsontable` 18.1.0, Commercial (see licence file), last published 1 Sep 2026, 1,190,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Handsontable pricing, as its site states it: Handsontable's Hobby licence is free for personal, exploratory projects and cannot be used in commercial settings; handsontable.com lists Standard from $999 per developer and Priority from $1,299 per developer, with Enterprise on custom terms (https://handsontable.com/pricing, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs Handsontable](https://svgrid.com/compare/handsontable/).\n<!-- facts:end -->\n\n## Imports\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import Handsontable from 'handsontable'\n- import 'handsontable/dist/handsontable.full.min.css'\n\n+ import {\n+ SvGrid, tableFeatures,\n+ rowSortingFeature, columnFilteringFeature, rowSelectionFeature,\n+ + } from '@svgrid/grid'\n```\n\n## Schema → columns\n\nHandsontable accepts a 2D array OR an array of objects. Sv-grid\nexpects the array-of-objects form:\n\n```diff\n- const hot = new Handsontable(container, {\n- data: [\n- ['Tesla', 2017, 'black', false],\n- ['Nissan', 2018, 'blue', true ],\n- ],\n- colHeaders: ['Make', 'Year', 'Color', 'In stock'],\n- columns: [\n- {},\n- { type: 'numeric' },\n- {},\n- { type: 'checkbox' },\n- ],\n- })\n\n+ type Car = { make: string; year: number; color: string; inStock: boolean }\n+ const rows: Car[] = [\n+ { make: 'Tesla', year: 2017, color: 'black', inStock: false },\n+ { make: 'Nissan', year: 2018, color: 'blue', inStock: true },\n+ ]\n+ const columns: ColumnDef<typeof features, Car>[] = [\n+ { field: 'make', header: 'Make' },\n+ { field: 'year', header: 'Year', editorType: 'number' },\n+ { field: 'color', header: 'Color' },\n+ { field: 'inStock', header: 'In stock', editorType: 'checkbox' },\n+ ]\n+ <SvGrid data={rows} columns={columns} features={features} />\n```\n\nIf your existing data is a 2D array, transform once at boot:\n\n```ts\nconst headerRow = raw[0]\nconst rows = raw.slice(1).map((cells) =>\n Object.fromEntries(cells.map((v, i) => [headerRow[i], v])),\n)\n```\n\n## Editor types\n\n| Handsontable | sv-grid |\n| ---------------------------------------------- | ------------------------------------------------ |\n| `type: 'text'` | `editorType: 'text'` |\n| `type: 'numeric'` | `editorType: 'number'` |\n| `type: 'date'` | `editorType: 'date'` |\n| `type: 'checkbox'` | `editorType: 'checkbox'` |\n| `type: 'dropdown', source: [...]` | `editorType: 'list', editorOptions: [...]` |\n| `type: 'autocomplete'` | `editorType: 'list'` (combobox UI ships) |\n| `type: 'time'` | `editorType: 'time'` |\n| `type: 'password'` | Use `editorType: 'text'` + a custom snippet |\n\n## Selection + clipboard\n\n| Handsontable | sv-grid |\n| --------------------------------------- | ------------------------------------------------------- |\n| `selectCells([[0,0,2,5]])` | `api.selectCells(ranges)`, with `selectionMode='cell'` |\n| `getSelected()` | `api.getSelected()`: the same `[[startRow, startCol, endRow, endCol], ...]`, normalised to top-left / bottom-right and `[]` rather than `undefined` when nothing is selected |\n| `getSelectedLast()` | `api.getSelectedLast()`: `[startRow, startCol, endRow, endCol]` with the orientation kept (a range dragged upwards has `startRow > endRow`), or `undefined` |\n| `getSelectedRange()` / `getSelectedRangeLast()` | `api.getSelectedRange()` / `api.getSelectedRangeLast()`: `{ from, to, highlight }` per rectangle, the same three fields as `CellRange`; plain data rather than a class, so use `Math.min` / `Math.max` for the corners |\n| `copyPaste: true` (default) | Ships built-in; `enableCellSelection={true}`. The spreadsheet shell also exchanges formats, number formats and formulas with Excel and Google Sheets through the HTML clipboard |\n| `fillHandle: true` | Ships built-in (drag-to-fill on selected range) |\n| `moveCells: true` | `moveCells` - drag the range border to move it, Ctrl / Cmd to copy. On by default; see [move or copy a range](./editing/move-cells.md) |\n\n## Frozen rows / columns\n\n| Handsontable | sv-grid |\n| ---------------------------------- | ------------------------------------------------------ |\n| `fixedColumnsStart: 2` | `api.setColumnPinning({ left: ['firstColId', 'secondColId'] })` |\n| `fixedRowsTop: 1` | `pinnedTopRows` (and `pinnedBottomRows`) |\n| `manualColumnFreeze: true` | Ships via the column-header right-click menu |\n| `mergeCells: [{ row, col, rowspan, colspan }]` | `mergedCells={[{ rowIndex, colIndex, rowSpan, colSpan }]}` on `<SvGrid>`; the spreadsheet shell adds Merge & Center, Merge Across, Merge Cells and Unmerge on the ribbon and the cell menu |\n\nFreeze panes on a plain `<SvGrid>`: two pinned columns and the sticky\nletter and number headers, with formulas underneath.\n\n<div data-docs-demo=\"208-freeze-panes\" data-height=\"520\"></div>\n\n## Hooks → callbacks\n\n| Handsontable hook | sv-grid |\n| -------------------------------------- | ------------------------------------------------------- |\n| `afterChange((changes, src) => {})` | `onCellValueChange((e) => {...})` |\n| `afterSelection(...)` | `onActiveCellChange((cell) => {...})` |\n| `afterFilter(...)` | `onFiltersChange((f) => {...})` |\n| `afterColumnSort(...)` | `onSortingChange((s) => {...})` |\n| `beforeChange((changes) => false)` | Throw / return `false` from your inline validator; see [validation](./editing/validation.md) |\n| `afterCreateRow / afterRemoveRow` | Wrap `api.addRow / removeRow` in your own emitter; on the spreadsheet shell, `onChange` reports a `structure` reason with the edit |\n| `afterMergeCells / afterUnmergeCells` | On the spreadsheet shell, `onChange` reports `merges`; `api.getMergedCells()` reads the grid's list |\n| `afterSetCellMeta` (comments, validation) | `onChange` reports `comments`, `validation`, `conditional-formats` and `protection` on the shell |\n| `afterFilter` (the Filters plugin) | `onChange` reports `filter` on the shell; `getState().sheets[name].autoFilter` is the state |\n\nOn the spreadsheet shell (`<SvSheet>` in `@svgrid/enterprise`) one callback\ncovers the lot: `onChange(reasons)` fires once per tick with every kind of\nchange since the last call (`cells`, `formats`, `sizes`, `hidden`,\n`freeze`, `sheets`, `comments`, `protection`, `validation`,\n`conditional-formats`, `merges`, `filter`, `structure` with the insert or\ndelete, `restore`), which is where Handsontable's `afterChange` autosave\ngoes. `getState()` gives the document to save and `setState()` puts it back.\n\n## Cell meta → the sheet document\n\nHandsontable keeps comments, validators, read-only flags and merges as cell\nmeta on the instance. On the spreadsheet shell they are parts of the\ndocument, per sheet, saved with it and moved by inserts and deletes:\n\n| Handsontable | sv-grid spreadsheet shell |\n| --------------------------------------------------- | --------------------------------------------------------------- |\n| `comments: true`, `cell: [{ row, col, comment }]` | Review > New Comment, Shift+F2, the cell menu; `getState().sheets[name].comments` |\n| `validator: 'numeric'`, `allowInvalid: false` | Data > Data Validation (Whole number, Decimal, List, Date, Text length, Custom), Stop or Warning; `validation` in the state |\n| `readOnly: true` on a cell | Format Cells > Protection unlocks the cells that may change, Review > Protect Sheet locks the rest; `locked: false` in the format entry, `protected` per sheet |\n| `mergeCells` | Merge & Center on the ribbon and the cell menu; `merges` in the state |\n| `filters: true` + `dropdownMenu` | Ctrl+Shift+L or Data > Filter: Excel's AutoFilter arrows and menus; `autoFilter` in the state |\n| conditional formatting (a custom renderer) | Home > Styles > Conditional Formatting: Highlight Cells, Top/Bottom, Data Bars, Color Scales, Icon Sets, Manage Rules; `conditionalFormats` in the state |\n| `autofill` rules | The fill handle's own series: numbers, dates by day or by the set gap, `Item 1`, weekdays and months |\n\nOn a plain `<SvGrid>` the free grid has the primitives instead: `notes`\nand `editableComments` for comments, `editable` and `valueParser` on a\ncolumn for read-only cells and validation, `mergedCells` for merges, the\nfilter row and its Excel-style menu for filtering, and value-driven\n`conditionalFormats` by column.\n\n## Formulas (HyperFormula)\n\nSv-grid ships a focused subset under\n[`spreadsheet-formulas`](./spreadsheet-formulas.md) (SUM, IF, COUNTIF\n+ cell refs + ranges + cycle detection). It does NOT ship the full\nHyperFormula library.\n\nIf you need HyperFormula's full surface (~400 functions, complex\ndate math, R1C1 refs), the integration pattern is:\n\n```ts\nimport { HyperFormula } from 'hyperformula'\n\nconst hf = HyperFormula.buildFromArray(rowsAsMatrix, { licenseKey: 'gpl-v3' })\n\n// On every cell edit, push to HF + read back the computed value:\nfunction onCellValueChange(e) {\n hf.setCellContents({ sheet: 0, row: e.rowIndex, col: columnIndex }, e.newValue)\n // ...read computed cells you depend on + push back via api.setCellValue\n}\n```\n\nThis is the only piece where the swap isn't 1:1. Most teams find\nsv-grid's shipped subset covers 80% of real-world formula usage; if\nyours is in the 20%, HyperFormula plugs in with the pattern above.\n\n## Licence\n\nHandsontable's grid needs a commercial licence for commercial use; its free\nHobby licence is for personal, exploratory projects, as its pricing page\nstates (the wording and the date are in the facts box at the top of this\npage). Sv-grid's `@svgrid/grid` is MIT with no licence key, and the\n[Enterprise tier](../enterprise/licensing.md) needs no key to evaluate:\nit works without one and displays a watermark and a console\nmessage until you add one, so there is no cutoff to plan around.\n\n## What you get for free vs Handsontable\n\n- **No commercial licence for the grid.** @svgrid/grid is MIT.\n- **Modern Svelte 5 ergonomics.** `$state` arrays beat\n `loadData(...)`.\n- **Grid features a spreadsheet does not have.** Row grouping with\n aggregation, master/detail, server-side data (grouping, tree, pivot and transactions on the server are Enterprise) and integrated\n charts in the same package.\n- **CSP-clean.** Handsontable's HyperFormula path needs CSP `eval`\n exceptions in some configurations.\n\n## What you give up\n\n- **Full HyperFormula surface as a supported feature.** Sv-grid ships a\n subset and lets you wire HyperFormula yourself; see above.\n- **Nested headers.** Handsontable's `nestedHeaders` have no\n counterpart beyond column groups.\n- **Threaded comments and a validation Input Message.** Comments on the\n shell are Excel's notes, one text per cell; validation shows its message\n on a refusal, not on arrival.\n- **Excel export without a paid pack.** Handsontable's export plugin writes\n XLSX through its asynchronous method; on sv-grid, CSV, TSV and JSON export\n are free and Excel, PDF and print output are in `@svgrid/enterprise`.\n\n## Frequently asked questions\n\n### Can SvGrid replace Handsontable's spreadsheet features?\n\nIt covers roughly 90% of the surface - inline editing on every cell, copy/paste\nas TSV, range selection, column groups, and a built-in formula engine. Budget\n2-4 hours per grid for typical spreadsheet workflows, plus 1-2 days if you lean\nheavily on the full HyperFormula function set.\n\n### Does SvGrid support formulas like Handsontable?\n\nYes, a built-in formula engine with cell references, ranges, and common\nfunctions (see the spreadsheet-formulas guide and demo 27). It is a practical\nsubset rather than the complete HyperFormula library, so verify your specific\nfunctions before porting.\n\n### Is SvGrid licensed like Handsontable?\n\nNo. The `@svgrid/grid` core is MIT and free for commercial use - no per-seat\nlicence key - whereas Handsontable's free licence excludes commercial use and\nits commercial plans are per developer; the facts box has the statement as\nread from handsontable.com. The optional `@svgrid/enterprise` pack (Excel and\nPDF export, print, pivot, import) is priced per developer.\n\n### Does SvGrid have a blank spreadsheet like Handsontable?\n\nYes, on the plain grid: column-letter headers, a row gutter, a name box\nand formula bar, gridlines, range selection and a fill handle, with\nHyperFormula underneath when you want its function library.\n\n<div data-docs-demo=\"207-blank-sheet\" data-height=\"560\"></div>\n\n## What you end up with\n\nSpreadsheet behaviour: inline edit, drag a cell range, copy it out as TSV.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} editable enableCellSelection statusBar />\n```\n\n## See also\n\n- [SvGrid vs Handsontable](https://svgrid.com/compare/handsontable/) - the side-by-side comparison, with a source and date for every claim\n- [Spreadsheet formulas](./spreadsheet-formulas.md) - sv-grid's\n built-in formula engine, and the rest of the spreadsheet demos\n- [Demo 27 (Spreadsheet + Ribbon)](https://svgrid.com/demos/27-spreadsheet-ribbon/) - live\n- [Migrating from AG Grid](./migrating-from-ag-grid.md)\n"
|
|
4738
4738
|
},
|
|
4739
4739
|
{
|
|
4740
4740
|
"slug": "help/migrating-from-jqxgrid",
|
|
4741
4741
|
"path": "docs/help/migrating-from-jqxgrid.md",
|
|
4742
4742
|
"title": "Migrating from jqxGrid (jQWidgets)",
|
|
4743
4743
|
"section": "Help",
|
|
4744
|
-
"markdown": "# Migrating from jqxGrid (jQWidgets)\n\njqxGrid and SvGrid come from the **same team**. jqxGrid is the mature,\nmulti-framework grid (jQuery core with Angular, React, and Vue\nintegrations); SvGrid is the Svelte-5-native member of the family. If\nyour team is consolidating on Svelte 5, this guide maps a jqxGrid setup\nonto SvGrid - and the concepts will feel familiar because the\nengineering lineage is shared.\n\n> Estimated effort: **2-4 hours** per grid. Most of the work is moving\n> from the imperative jQuery source / API to reactive `$state`.\n\n<!-- facts:start jqxgrid -->\n> **Facts, checked 12 Sep 2026.** `jqwidgets-scripts` 26.0.0, https://www.jqwidgets.com/license/, last published 9 Jul 2026, 41,900 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). jqxGrid pricing, as its site states it: jqwidgets.com lists the Developer License at $499 (on sale at $399) per developer, perpetual and royalty-free with one year of updates and support, and the Team License at $1,499 for five or more developers; the free Community License excludes the Grid (https://www.jqwidgets.com/license/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4744
|
+
"markdown": "# Migrating from jqxGrid (jQWidgets)\n\njqxGrid and SvGrid come from the **same team**. jqxGrid is the mature,\nmulti-framework grid (jQuery core with Angular, React, and Vue\nintegrations); SvGrid is the Svelte-5-native member of the family. If\nyour team is consolidating on Svelte 5, this guide maps a jqxGrid setup\nonto SvGrid - and the concepts will feel familiar because the\nengineering lineage is shared.\n\n> Estimated effort: **2-4 hours** per grid. Most of the work is moving\n> from the imperative jQuery source / API to reactive `$state`.\n\n<!-- facts:start jqxgrid -->\n> **Facts, checked 12 Sep 2026.** `jqwidgets-scripts` 26.0.0, https://www.jqwidgets.com/license/, last published 9 Jul 2026, 41,900 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). jqxGrid pricing, as its site states it: jqwidgets.com lists the Developer License at $499 (on sale at $399) per developer, perpetual and royalty-free with one year of updates and support, and the Team License at $1,499 for five or more developers; the free Community License excludes the Grid (https://www.jqwidgets.com/license/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs jqxGrid (jQWidgets)](https://svgrid.com/compare/jqxgrid/).\n<!-- facts:end -->\n\n## Vocabulary cheat sheet\n\n| jqxGrid | sv-grid |\n| ---------------------------------------- | ----------------------------------------- |\n| `$('#grid').jqxGrid({ ... })` | `<SvGrid ... />` |\n| `source` / `jqxDataAdapter` | `data` array (or `externalSort/Filter`) |\n| `{ text: 'Name', datafield: 'name' }` | `{ header: 'Name', field: 'name' }` |\n| `cellsrenderer` | `cell: (c) => renderSnippet(...)` |\n| `columntype` / cell editor | `editorType` |\n| `cellsformat: 'c2'` | `format: { type: 'currency', currency: 'USD' }` |\n| `sortable` / `filterable` | `rowSortingFeature` / `columnFilteringFeature` |\n| `groupable` + `groups` | `columnGroupingFeature` + `api.setGroupBy()` |\n| `pageable` | `showPagination` |\n| `jqxGrid('updatebounddata')` | reassign the `$state` data array |\n| `editable` + `cellendedit` event | `enableInlineEditing` + `onCellValueChange` |\n\n## Before / after\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- const source = { localdata: rows, datatype: 'array' }\n- const adapter = new $.jqx.dataAdapter(source)\n- $('#grid').jqxGrid({\n- source: adapter, sortable: true, filterable: true, pageable: true, editable: true,\n- columns: [\n- { text: 'Name', datafield: 'name' },\n- { text: 'Amount', datafield: 'amount', cellsformat: 'c2' },\n- ],\n- })\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} showPagination enableInlineEditing />\n```\n\n## What changes\n\n- **jQuery source / dataAdapter → reactive `$state`.** No\n `updatebounddata()`; reassign the array.\n- **`cellsrenderer` → snippet cells** via `renderSnippet`.\n- **jQWidgets theme → `--sg-*` tokens** (or your Tailwind theme).\n\n## A note on family\n\nMoving to SvGrid keeps you with the same team's Svelte-5 grid rather\nthan switching vendors. The Enterprise tier and support come from the same people behind jqxGrid.\nIf your app is still on jQuery / Angular / React / Vue, jqxGrid remains\nthe right tool; reach for SvGrid when the codebase is Svelte 5.\n\n## Frequently asked questions\n\n### Is SvGrid made by the same team as jqxGrid?\n\nYes. SvGrid is built by jQWidgets - the same team behind jqxGrid - specifically\nfor Svelte 5, rebuilt around runes and snippets with an MIT community core.\n\n### How do jqxGrid columns map to SvGrid?\n\n`text` becomes `header`, `datafield` becomes `field`, `cellsrenderer` becomes a\n`renderSnippet` cell, and `cellsformat` maps onto the `format` config. Sorting /\nfiltering / grouping move to registered features.\n\n### Should I migrate my jQuery jqxGrid app to SvGrid?\n\nOnly if you are moving that app to Svelte 5. If it stays on jQuery / Angular /\nReact / Vue, jqxGrid is the better fit. SvGrid is the native choice once the\nstack is Svelte.\n\n## What you end up with\n\nEditing plus range selection and a totals row - the jqxGrid working set.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} editable enableCellSelection summary sortable />\n```\n\n## See also\n\n- [SvGrid vs jqxGrid](https://svgrid.com/compare/jqxgrid/) - the side-by-side comparison\n- [About SvGrid](https://svgrid.com/about/) - built by jQWidgets\n- [Getting started](../getting-started.md) - a working grid in ~15 lines\n"
|
|
4745
4745
|
},
|
|
4746
4746
|
{
|
|
4747
4747
|
"slug": "help/migrating-from-kendo-grid",
|
|
4748
4748
|
"path": "docs/help/migrating-from-kendo-grid.md",
|
|
4749
4749
|
"title": "Migrating from Kendo UI Grid (Telerik)",
|
|
4750
4750
|
"section": "Help",
|
|
4751
|
-
"markdown": "# Migrating from Kendo UI Grid (Telerik)\n\nKendo UI Grid is the polished, commercial enterprise grid from Telerik /\nProgress, available for jQuery, React, Vue, and Angular. Moving to SvGrid\ntrades the multi-framework commercial suite for a Svelte-5-native grid\nwith an MIT core - and a much cheaper paid tier.\n\n> Estimated effort: **3-6 hours** per grid - column / event translation\n> plus re-theming.\n>\n> Kendo's exact API differs across its jQuery / React / Vue / Angular\n> flavours; map your version's column and event names onto the SvGrid\n> equivalents below.\n\n<!-- facts:start kendo-ui-grid -->\n> **Facts, checked 12 Sep 2026.** `@progress/kendo-react-grid` 16.1.0, Commercial (see licence file), last published 8 Sep 2026, 385,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Kendo UI Grid pricing, as its site states it: telerik.com lists the Kendo UI bundle at $799, $849 or $1,299 per developer per year depending on the support tier, and KendoReact alone from $649 per developer per year; no free tier for the grid (https://www.telerik.com/purchase.aspx, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4751
|
+
"markdown": "# Migrating from Kendo UI Grid (Telerik)\n\nKendo UI Grid is the polished, commercial enterprise grid from Telerik /\nProgress, available for jQuery, React, Vue, and Angular. Moving to SvGrid\ntrades the multi-framework commercial suite for a Svelte-5-native grid\nwith an MIT core - and a much cheaper paid tier.\n\n> Estimated effort: **3-6 hours** per grid - column / event translation\n> plus re-theming.\n>\n> Kendo's exact API differs across its jQuery / React / Vue / Angular\n> flavours; map your version's column and event names onto the SvGrid\n> equivalents below.\n\n<!-- facts:start kendo-ui-grid -->\n> **Facts, checked 12 Sep 2026.** `@progress/kendo-react-grid` 16.1.0, Commercial (see licence file), last published 8 Sep 2026, 385,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Kendo UI Grid pricing, as its site states it: telerik.com lists the Kendo UI bundle at $799, $849 or $1,299 per developer per year depending on the support tier, and KendoReact alone from $649 per developer per year; no free tier for the grid (https://www.telerik.com/purchase.aspx, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs Kendo UI Grid (Telerik)](https://svgrid.com/compare/kendo-ui-grid/).\n<!-- facts:end -->\n\n## Concept map\n\n| Kendo UI Grid | sv-grid |\n| ---------------------------------------- | ----------------------------------------- |\n| `columns: [{ field, title }]` | `columns: [{ field, header }]` |\n| `template` / cell render | `cell: (c) => renderSnippet(...)` |\n| `editable` + editor | `enableInlineEditing` + `editorType` |\n| `sortable` / `filterable` | `rowSortingFeature` / `columnFilteringFeature` |\n| `group` / aggregates | `columnGroupingFeature` + `api.setGroupBy()` |\n| `dataSource` (local / remote) | `data` array or `externalSort/Filter` |\n| `pageable` | `showPagination` |\n| Kendo themes (Default / Bootstrap) | `--sg-*` tokens / Tailwind |\n| Grid events (`change`, `dataBound`) | `onCellValueChange`, `onApiReady`, ... |\n\n## Shape of the change\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- $('#grid').kendoGrid({\n- dataSource: { data: rows, pageSize: 25 },\n- sortable: true, filterable: true, pageable: true, editable: true,\n- columns: [\n- { field: 'name', title: 'Name' },\n- { field: 'amount', title: 'Amount', format: '{0:c}' },\n- ],\n- })\n\n+ <SvGrid\n+ data={rows}\n+ columns={[\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]}\n+ features={tableFeatures({ rowSortingFeature, columnFilteringFeature })}\n+ showPagination enableInlineEditing />\n```\n\n## Why teams switch\n\n- **Svelte 5 native** instead of a jQuery / multi-framework suite.\n- **MIT community core** - no per-developer license for the grid itself.\n- **Paid support at a fraction of enterprise-suite pricing.**\n- **No design-system lock-in** - theme via `--sg-*` tokens.\n\n## What to weigh\n\n- Kendo bundles a **huge component suite** (charts, scheduler, editor)\n and decades of vendor support. If you need the whole suite across\n several frameworks, that has real value.\n\n## Frequently asked questions\n\n### Is SvGrid a cheaper alternative to Kendo UI Grid?\n\nFor a Svelte stack, yes: the `@svgrid/grid` core is MIT (free, including\ncommercial use), and the paid `@svgrid/enterprise` tier is a fraction of enterprise\ncomponent-suite pricing.\n\n### How long does a Kendo Grid migration take?\n\nAbout 3-6 hours per grid. It is a column / event rename pass plus re-theming;\nthe columns and editing concepts map closely.\n\n### Does SvGrid match Kendo's feature set?\n\nFor the grid itself it covers the common enterprise surface - sorting,\nExcel-style filters, grouping, virtualization, editing, master/detail, tree.\nKendo's value beyond that is the wider suite and multi-framework parity.\n\n## What you end up with\n\nSorting, filtering, grouping and editing, with the column menu Kendo users expect.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} groupBy={['department']} groupable sortable filterable editable />\n```\n\n## See also\n\n- [SvGrid vs Kendo UI Grid](https://svgrid.com/compare/kendo-ui-grid/) - the side-by-side comparison\n- [Pricing](https://svgrid.com/pricing/) - the SvGrid Enterprise tiers\n- [Architecture](./architecture.md) - engine + render-component split\n"
|
|
4752
4752
|
},
|
|
4753
4753
|
{
|
|
4754
4754
|
"slug": "help/migrating-from-mui-x",
|
|
4755
4755
|
"path": "docs/help/migrating-from-mui-x.md",
|
|
4756
4756
|
"title": "Migrating from MUI X DataGrid",
|
|
4757
4757
|
"section": "Help",
|
|
4758
|
-
"markdown": "# Migrating from MUI X DataGrid\n\nMUI X DataGrid is the most common starting point for teams already\non Material UI. Its MIT Community edition plus paid Pro and Premium\ntiers is a split similar to sv-grid's, except that column pinning,\nmaster/detail, tree data, row grouping, aggregation and cell selection\nare paid in MUI X and free here. The port is mostly mechanical.\n\n> Estimated effort: **1-3 hours** per grid, depending on how heavily\n> you've leant on `apiRef.current.*` calls.\n\n<!-- facts:start mui-x-datagrid -->\n> **Facts, checked 12 Sep 2026.** `@mui/x-data-grid` 9.13.0, MIT, last published 4 Sep 2026, 11,800,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@mui/x-data-grid` 9.13.0 155.0 KB JS, no separate stylesheet, @emotion/react + @emotion/styled + @mui/material + @mui/system + react + react-dom external (measured 12 Sep 2026). MUI X DataGrid pricing, as its site states it: MUI X Community is free under MIT. mui.com lists Pro at $299 per year per developer, Premium at $599 per year per developer and Enterprise at $1,399 per year per developer, with perpetual and annual licence models (https://mui.com/pricing/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/).\n<!-- facts:end -->\n\n## Package map\n\n| MUI X | sv-grid |\n| ------------------------------------ | ---------------------------------------- |\n| `@mui/x-data-grid` | `@svgrid/grid` |\n| `@mui/x-data-grid-pro` | `@svgrid/enterprise` (export, import, pivot, AI) |\n| `@mui/x-data-grid-premium` | All of `@svgrid/enterprise` ships in one tier |\n\n## Imports\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import { DataGrid, GridColDef, GridRowsProp } from '@mui/x-data-grid'\n\n+ import { SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef } from '@svgrid/grid'\n```\n\n## Column defs\n\n```diff\n- const columns: GridColDef[] = [\n- { field: 'id', headerName: 'ID', width: 90 },\n- { field: 'lastName', headerName: 'Last', width: 150, editable: true },\n- { field: 'age', headerName: 'Age', type: 'number', width: 110, editable: true },\n- ]\n\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'id', header: 'ID', width: 90 },\n+ { field: 'lastName', header: 'Last', width: 150 },\n+ { field: 'age', header: 'Age', width: 110, editorType: 'number' },\n+ ]\n```\n\n- `headerName` → `header`\n- `type: 'number'` → `editorType: 'number'`\n- `editable: true` → omit (every column is editable by default; set\n `editable: false` to OPT OUT)\n\n## Mounting\n\n```diff\n- <DataGrid rows={rows} columns={columns} pageSize={25} checkboxSelection />\n\n+ <SvGrid\n+ data={rows} columns={columns} features={features}\n+ showPagination={true} pageSize={25}\n+ selectionMode=\"row\" />\n```\n\n`tableFeatures({ rowSortingFeature, columnFilteringFeature,\nrowSelectionFeature })` registers what you'd implicitly get from\nMUI X.\n\n## `apiRef` translation\n\n| MUI X (`apiRef.current.*`) | sv-grid (`api.*`) |\n| -------------------------------------------- | ------------------------------------------ |\n| `setRows(rows)` | mutate the `$state` array you bound to `data` |\n| `updateRows([{id, ...patch}])` | `api.setCellValue(rowIndex, field, value)` |\n| `setSortModel([{field, sort}])` | `api.setSort(field, sort)` |\n| `setFilterModel({items: [...]})` | `api.setFilter(field, {operator, value})` |\n| `setPage(0)` / `setPageSize(50)` | Use the built-in pager; for headless control register `pageSize` prop |\n| `selectRow(id)` | Toggle the row checkbox via the wrapper's UI; programmatic select is `api.selectRows([id])` (`api.toggleRowSelected(id)` to flip one) |\n| `getSelectedRows()` | `api.getSelectedRows()` (ids via `api.getSelectedRowIds()`) |\n| `exportDataAsExcel()` | `api.exportData({ format: 'xlsx' })` (Enterprise) |\n| `setColumnVisibilityModel({field: false})` | `api.setColumnVisible('field', false)` |\n\n## Custom cells\n\n```diff\n- {\n- field: 'status',\n- renderCell: ({ row }) => <Chip label={row.status} color={row.status === 'active' ? 'success' : 'default'} />,\n- }\n\n+ {\n+ field: 'status',\n+ cell: (ctx) => renderSnippet(StatusChip, { status: ctx.row.original.status }),\n+ }\n```\n\n## Selection\n\n```diff\n- <DataGrid checkboxSelection\n- onRowSelectionModelChange={(ids) => setSelected(ids)} />\n\n+ <SvGrid\n+ {data} {columns} features={features}\n+ selectionMode=\"row\"\n+ onRowSelectionChange={(selection, rows) => setSelected(rows)} />\n```\n\n`selectionMode` values: `'row'` (the MUI X equivalent), `'cell'`\n(spreadsheet-style range), `'both'`, `'none'`.\n\n## Inline editing\n\nMUI X had `processRowUpdate(newRow, oldRow)` returning the new row.\nSv-grid's equivalent is `onCellValueChange`:\n\n```diff\n- <DataGrid processRowUpdate={async (newRow) => {\n- await api.savePatch(newRow)\n- return newRow\n- }} />\n\n+ <SvGrid\n+ onCellValueChange={async (e) => {\n+ await api.savePatch({ id: e.row.id, [e.columnId]: e.newValue })\n+ }}\n+ />\n```\n\nFor full-row editing (one Save button per row), see\n[Full-row editing](./editing/full-row.md).\n\n## Server-side data\n\nMUI X's `pagination + serverSideMode + filterMode='server'` maps to\nsv-grid's `externalSort + externalFilter`, or to `createServerDataSource` (free:\npaging or infinite scroll, sort, filter) when the server pages, and to the\nEnterprise `createServerRowModel` when it also groups; the demo below runs\nthe free controller against a fake API with sort, filter and infinite scroll:\n\n<div data-docs-demo=\"148-server-row-model\" data-height=\"520\"></div>\n\nMUI X's server-side row grouping and aggregation (Premium) map to the\nEnterprise row model, which loads each group level on expand and pages,\nedits and selects across rows the grid never fetched:\n\n<div data-docs-demo=\"467-server-row-model-1m\" data-height=\"600\"></div>\n\n```svelte\n<SvGrid\n data={rows} columns={columns} features={features}\n externalSort={true}\n externalFilter={true}\n onSortingChange={async (s) => { rows = await fetchPage({ sort: s }) }}\n onFiltersChange={async (f) => { rows = await fetchPage({ filters: f.columns }) }}\n/>\n```\n\n## Slots / customisation\n\nMUI X exposes a `slots` object. Sv-grid doesn't - instead, every\nvisual piece is a CSS custom property (`--sg-*`); see\n[design tokens](./tokens.md). Override at any DOM level:\n\n```css\n.grid-host { --sg-accent: #db2777; --sg-radius: 10px; }\n```\n\nRow height is the exception: it is the `rowHeight` prop rather than a\ntoken, because the virtualizer needs it as a number.\n\nFor full theme presets (Ant, MUI, Fluent, Base Web, shadcn) see\n[demo 74](https://svgrid.com/demos/74-theme-integrations/).\n\n## What you get for free vs MUI X\n\n- **No Emotion / no Material theme dependency.** The facts box at the\n top of the page has both packages measured the same way; the MUI X\n figure excludes React, Material UI, Emotion and the MUI system, which\n it needs and sv-grid does not.\n- **Pro and Premium features in the MIT core.** Column pinning, master/detail,\n tree data, row grouping, aggregation and cell selection carry Pro or\n Premium badges on mui.com; they are free here. Excel export and pivot\n are paid on both sides.\n- **In-grid AI helpers against your own model.** MUI X's AI assistant is a\n Premium feature that routes prompts through MUI's hosted service unless\n you build your own; sv-grid's natural-language filter, smart fill and\n summarise helpers are free and run against a provider you register.\n- **CSP-clean.** No `eval`.\n\n## What you give up\n\n- **The Material Design look out of the box.** Sv-grid ships\n unstyled-by-token; the [MUI preset in demo 74](https://svgrid.com/demos/74-theme-integrations/)\n is one drop-in.\n- **MUI form-field integration.** Bind directly to your own MUI\n inputs in custom cell components if you want them.\n- **The rest of MUI X in one design system.** Date pickers, charts and\n the tree view share MUI X's theme; sv-grid ships its own date and time\n editors and charts, themed through the same `--sg-*` tokens.\n- **A hosted AI assistant with starter credits.** Premium licence holders\n get MUI's service; sv-grid's helpers need a model provider you host or\n pay for yourself.\n\n## Frequently asked questions\n\n### How hard is it to migrate from MUI X DataGrid to SvGrid?\n\nMostly mechanical - typically 1-3 hours per grid, depending on how heavily you\nrelied on `apiRef.current.*`. The Community/Enterprise split mirrors MUI X's, so the\nlicensing mental model carries over directly.\n\n### Can SvGrid keep the Material Design look?\n\nYes. SvGrid ships unstyled-by-token and re-themes through `--sg-*` CSS\nvariables; the MUI preset in demo 74 is a drop-in starting point. You can also\nbind your own MUI inputs inside custom cell components.\n\n### Is SvGrid cheaper than MUI X Pro/Premium?\n\nSvGrid's Community tier is MIT and free for commercial use, and `@svgrid/enterprise`\nis priced per developer ($599 for the grid, $999 with the spreadsheet and\nStudio, both covering unlimited apps). MUI X Pro and\nPremium are also per developer per year; the prices mui.com listed on the\ndate we read it are in the facts box at the top of this page. The difference\nis what the free tier holds: most of what MUI X sells in Pro and Premium is\nin SvGrid's MIT core, so compare feature needs before prices on the\n[pricing page](https://svgrid.com/pricing/).\n\n## What you end up with\n\nSorting, filtering, pagination and inline editing - the MUI X DataGrid feature set.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable editable pageable pageSize={3} />\n```\n\n## See also\n\n- [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/) - the side-by-side comparison, with a source and date for every claim\n- [Server-side data](./server-side-data.md) - the row model the demo above uses\n- [AI assistant](./ai.md) - the free in-grid helpers\n- [Migrating from AG Grid](./migrating-from-ag-grid.md)\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md)\n- [Design tokens](./tokens.md)\n"
|
|
4758
|
+
"markdown": "# Migrating from MUI X DataGrid\n\nMUI X DataGrid is the most common starting point for teams already\non Material UI. Its MIT Community edition plus paid Pro and Premium\ntiers is a split similar to sv-grid's, except that column pinning,\nmaster/detail, tree data, row grouping, aggregation and cell selection\nare paid in MUI X and free here. The port is mostly mechanical.\n\n> Estimated effort: **1-3 hours** per grid, depending on how heavily\n> you've leant on `apiRef.current.*` calls.\n\n<!-- facts:start mui-x-datagrid -->\n> **Facts, checked 12 Sep 2026.** `@mui/x-data-grid` 9.13.0, MIT, last published 4 Sep 2026, 11,800,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@mui/x-data-grid` 9.13.0 155.0 KB JS, no separate stylesheet, @emotion/react + @emotion/styled + @mui/material + @mui/system + react + react-dom external (measured 12 Sep 2026). MUI X DataGrid pricing, as its site states it: MUI X Community is free under MIT. mui.com lists Pro at $299 per year per developer, Premium at $599 per year per developer and Enterprise at $1,399 per year per developer, with perpetual and annual licence models (https://mui.com/pricing/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/).\n<!-- facts:end -->\n\n## Package map\n\n| MUI X | sv-grid |\n| ------------------------------------ | ---------------------------------------- |\n| `@mui/x-data-grid` | `@svgrid/grid` |\n| `@mui/x-data-grid-pro` | `@svgrid/enterprise` (export, import, pivot, AI) |\n| `@mui/x-data-grid-premium` | All of `@svgrid/enterprise` ships in one tier |\n\n## Imports\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import { DataGrid, GridColDef, GridRowsProp } from '@mui/x-data-grid'\n\n+ import { SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef } from '@svgrid/grid'\n```\n\n## Column defs\n\n```diff\n- const columns: GridColDef[] = [\n- { field: 'id', headerName: 'ID', width: 90 },\n- { field: 'lastName', headerName: 'Last', width: 150, editable: true },\n- { field: 'age', headerName: 'Age', type: 'number', width: 110, editable: true },\n- ]\n\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'id', header: 'ID', width: 90 },\n+ { field: 'lastName', header: 'Last', width: 150 },\n+ { field: 'age', header: 'Age', width: 110, editorType: 'number' },\n+ ]\n```\n\n- `headerName` → `header`\n- `type: 'number'` → `editorType: 'number'`\n- `editable: true` → omit (every column is editable by default; set\n `editable: false` to OPT OUT)\n\n## Mounting\n\n```diff\n- <DataGrid rows={rows} columns={columns} pageSize={25} checkboxSelection />\n\n+ <SvGrid\n+ data={rows} columns={columns} features={features}\n+ showPagination={true} pageSize={25}\n+ selectionMode=\"row\" />\n```\n\n`tableFeatures({ rowSortingFeature, columnFilteringFeature,\nrowSelectionFeature })` registers what you'd implicitly get from\nMUI X.\n\n## `apiRef` translation\n\n| MUI X (`apiRef.current.*`) | sv-grid (`api.*`) |\n| -------------------------------------------- | ------------------------------------------ |\n| `setRows(rows)` | mutate the `$state` array you bound to `data` |\n| `updateRows([{id, ...patch}])` | `api.setCellValue(rowIndex, field, value)` |\n| `setSortModel([{field, sort}])` | `api.setSort(field, sort)` |\n| `setFilterModel({items: [...]})` | `api.setFilter(field, {operator, value})` |\n| `setPage(0)` / `setPageSize(50)` | Use the built-in pager; for headless control register `pageSize` prop |\n| `selectRow(id)` | Toggle the row checkbox via the wrapper's UI; programmatic select is `api.selectRows([id])` (`api.toggleRowSelected(id)` to flip one) |\n| `getSelectedRows()` | `api.getSelectedRows()` (ids via `api.getSelectedRowIds()`) |\n| `exportDataAsExcel()` | `api.exportData({ format: 'xlsx' })` (Enterprise) |\n| `setColumnVisibilityModel({field: false})` | `api.setColumnVisible('field', false)` |\n\n## Custom cells\n\n```diff\n- {\n- field: 'status',\n- renderCell: ({ row }) => <Chip label={row.status} color={row.status === 'active' ? 'success' : 'default'} />,\n- }\n\n+ {\n+ field: 'status',\n+ cell: (ctx) => renderSnippet(StatusChip, { status: ctx.row.original.status }),\n+ }\n```\n\n## Selection\n\n```diff\n- <DataGrid checkboxSelection\n- onRowSelectionModelChange={(ids) => setSelected(ids)} />\n\n+ <SvGrid\n+ {data} {columns} features={features}\n+ selectionMode=\"row\"\n+ onRowSelectionChange={(selection, rows) => setSelected(rows)} />\n```\n\n`selectionMode` values: `'row'` (the MUI X equivalent), `'cell'`\n(spreadsheet-style range), `'both'`, `'none'`.\n\n## Inline editing\n\nMUI X had `processRowUpdate(newRow, oldRow)` returning the new row.\nSv-grid's equivalent is `onCellValueChange`:\n\n```diff\n- <DataGrid processRowUpdate={async (newRow) => {\n- await api.savePatch(newRow)\n- return newRow\n- }} />\n\n+ <SvGrid\n+ onCellValueChange={async (e) => {\n+ await api.savePatch({ id: e.row.id, [e.columnId]: e.newValue })\n+ }}\n+ />\n```\n\nFor full-row editing (one Save button per row), see\n[Full-row editing](./editing/full-row.md).\n\n## Server-side data\n\nMUI X's `pagination + serverSideMode + filterMode='server'` maps to\nsv-grid's `externalSort + externalFilter`, or to `createServerDataSource` (free:\npaging or infinite scroll, sort, filter) when the server pages, and to the\nEnterprise `createServerRowModel` when it also groups; the demo below runs\nthe free controller against a fake API with sort, filter and infinite scroll:\n\n<div data-docs-demo=\"148-server-row-model\" data-height=\"520\"></div>\n\nMUI X's server-side row grouping and aggregation (Premium) map to the\nEnterprise row model, which loads each group level on expand and pages,\nedits and selects across rows the grid never fetched:\n\n<div data-docs-demo=\"467-server-row-model-1m\" data-height=\"600\"></div>\n\n```svelte\n<SvGrid\n data={rows} columns={columns} features={features}\n externalSort={true}\n externalFilter={true}\n onSortingChange={async (s) => { rows = await fetchPage({ sort: s }) }}\n onFiltersChange={async (f) => { rows = await fetchPage({ filters: f.columns }) }}\n/>\n```\n\n## Slots / customisation\n\nMUI X exposes a `slots` object. Sv-grid doesn't - instead, every\nvisual piece is a CSS custom property (`--sg-*`); see\n[design tokens](./tokens.md). Override at any DOM level:\n\n```css\n.grid-host { --sg-accent: #db2777; --sg-radius: 10px; }\n```\n\nRow height is the exception: it is the `rowHeight` prop rather than a\ntoken, because the virtualizer needs it as a number.\n\nFor full theme presets (Ant, MUI, Fluent, Base Web, shadcn) see\n[demo 74](https://svgrid.com/demos/74-theme-integrations/).\n\n## What you get for free vs MUI X\n\n- **No Emotion / no Material theme dependency.** The facts box at the\n top of the page has both packages measured the same way; the MUI X\n figure excludes React, Material UI, Emotion and the MUI system, which\n it needs and sv-grid does not.\n- **Pro and Premium features in the MIT core.** Column pinning, master/detail,\n tree data, row grouping, aggregation and cell selection carry Pro or\n Premium badges on mui.com; they are free here. Excel export and pivot\n are paid on both sides.\n- **In-grid AI helpers against your own model.** MUI X's AI assistant is a\n Premium feature that routes prompts through MUI's hosted service unless\n you build your own; sv-grid's natural-language filter, smart fill and\n summarise helpers are free and run against a provider you register.\n- **CSP-clean.** No `eval`.\n\n## What you give up\n\n- **The Material Design look out of the box.** Sv-grid ships\n unstyled-by-token; the [MUI preset in demo 74](https://svgrid.com/demos/74-theme-integrations/)\n is one drop-in.\n- **MUI form-field integration.** Bind directly to your own MUI\n inputs in custom cell components if you want them.\n- **The rest of MUI X in one design system.** Date pickers, charts and\n the tree view share MUI X's theme; sv-grid ships its own date and time\n editors and charts, themed through the same `--sg-*` tokens.\n- **A hosted AI assistant with starter credits.** Premium licence holders\n get MUI's service; sv-grid's helpers need a model provider you host or\n pay for yourself.\n\n## Frequently asked questions\n\n### How hard is it to migrate from MUI X DataGrid to SvGrid?\n\nMostly mechanical - typically 1-3 hours per grid, depending on how heavily you\nrelied on `apiRef.current.*`. The Community/Enterprise split mirrors MUI X's, so the\nlicensing mental model carries over directly.\n\n### Can SvGrid keep the Material Design look?\n\nYes. SvGrid ships unstyled-by-token and re-themes through `--sg-*` CSS\nvariables; the MUI preset in demo 74 is a drop-in starting point. You can also\nbind your own MUI inputs inside custom cell components.\n\n### Is SvGrid cheaper than MUI X Pro/Premium?\n\nSvGrid's Community tier is MIT and free for commercial use, and `@svgrid/enterprise`\nis priced per developer ($599 for the grid, $999 with the spreadsheet and\nStudio, both covering unlimited apps). MUI X Pro and\nPremium are also per developer per year; the prices mui.com listed on the\ndate we read it are in the facts box at the top of this page. The difference\nis what the free tier holds: most of what MUI X sells in Pro and Premium is\nin SvGrid's MIT core, so compare feature needs before prices on the\n[pricing page](https://svgrid.com/pricing/).\n\n## What you end up with\n\nSorting, filtering, pagination and inline editing - the MUI X DataGrid feature set.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable editable pageable pageSize={3} />\n```\n\n## See also\n\n- [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/) - the side-by-side comparison, with a source and date for every claim\n- [Server-side data](./server-side-data.md) - the row model the demo above uses\n- [AI assistant](./ai.md) - the free in-grid helpers\n- [Migrating from AG Grid](./migrating-from-ag-grid.md)\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md)\n- [Design tokens](./tokens.md)\n"
|
|
4759
4759
|
},
|
|
4760
4760
|
{
|
|
4761
4761
|
"slug": "help/migrating-from-primevue-datatable",
|
|
4762
4762
|
"path": "docs/help/migrating-from-primevue-datatable.md",
|
|
4763
4763
|
"title": "Migrating from PrimeVue / PrimeNG / PrimeReact DataTable",
|
|
4764
4764
|
"section": "Help",
|
|
4765
|
-
"markdown": "# Migrating from PrimeVue / PrimeNG / PrimeReact DataTable\n\nThe Prime DataTable is the grid in the Prime UI suites for Vue, Angular,\nand React. Its columns are declared as `<Column>` children with `field`\n/ `header` props - a shape that maps cleanly onto SvGrid's `ColumnDef`\narray. The port is mostly translating columns and events into a Svelte 5\ncomponent. Since PrimeVue 5 the package ships under the PrimeUI licence\nrather than MIT: free for individuals and small organisations under the\nlimits in its licence file, per developer with a licence key otherwise.\nThe facts box below quotes the terms as read on the date shown.\n\n> Estimated effort: **2-4 hours** per grid.\n\n<!-- facts:start primevue-datatable -->\n> **Facts, checked 12 Sep 2026.** `primevue` 5.0.1, Commercial (see licence file), last published 13 Aug 2026, 3,010,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). PrimeVue / PrimeNG / PrimeReact DataTable pricing, as its site states it: primeui.dev lists the Commercial Suite at a launch price of $599 per developer (standard $799) as a perpetual licence with one year of updates, renewable at $399 per developer per year; the Community License is free for individuals, non-profits and organisations under $1M revenue, fewer than five developers, fewer than ten employees and under $3M in venture funding (https://primeui.dev/pricing, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4765
|
+
"markdown": "# Migrating from PrimeVue / PrimeNG / PrimeReact DataTable\n\nThe Prime DataTable is the grid in the Prime UI suites for Vue, Angular,\nand React. Its columns are declared as `<Column>` children with `field`\n/ `header` props - a shape that maps cleanly onto SvGrid's `ColumnDef`\narray. The port is mostly translating columns and events into a Svelte 5\ncomponent. Since PrimeVue 5 the package ships under the PrimeUI licence\nrather than MIT: free for individuals and small organisations under the\nlimits in its licence file, per developer with a licence key otherwise.\nThe facts box below quotes the terms as read on the date shown.\n\n> Estimated effort: **2-4 hours** per grid.\n\n<!-- facts:start primevue-datatable -->\n> **Facts, checked 12 Sep 2026.** `primevue` 5.0.1, Commercial (see licence file), last published 13 Aug 2026, 3,010,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). PrimeVue / PrimeNG / PrimeReact DataTable pricing, as its site states it: primeui.dev lists the Commercial Suite at a launch price of $599 per developer (standard $799) as a perpetual licence with one year of updates, renewable at $399 per developer per year; the Community License is free for individuals, non-profits and organisations under $1M revenue, fewer than five developers, fewer than ten employees and under $3M in venture funding (https://primeui.dev/pricing, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs PrimeVue / PrimeNG / PrimeReact DataTable](https://svgrid.com/compare/primevue-datatable/).\n<!-- facts:end -->\n\n## Vocabulary cheat sheet\n\n| Prime DataTable | sv-grid |\n| ---------------------------------------- | ----------------------------------------- |\n| `<DataTable :value=\"rows\">` | `<SvGrid data={rows}>` |\n| `<Column field=\"name\" header=\"Name\" />` | `{ field: 'name', header: 'Name' }` |\n| `sortable` | `rowSortingFeature` |\n| `:filters` / filter display | `columnFilteringFeature` |\n| `<template #body>` cell slot | `cell: (c) => renderSnippet(...)` |\n| `editMode` + cell editor template | `editorType` (+ custom `cellEditor`) |\n| `:expandedRows` / row expansion | `rowExpandingFeature` |\n| `lazy` + `@page` / `@sort` / `@filter` | `externalSort` / `externalFilter` + events |\n| `paginator` + `:rows` | `showPagination` (+ page size) |\n\n## Before / after\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- <DataTable :value=\"rows\" paginator :rows=\"25\" sortMode=\"multiple\">\n- <Column field=\"name\" header=\"Name\" sortable />\n- <Column field=\"amount\" header=\"Amount\" sortable>\n- <template #body=\"{ data }\">{{ fmt(data.amount) }}</template>\n- </Column>\n- </DataTable>\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} showPagination />\n```\n\n## What changes\n\n- **`<Column>` children → a `ColumnDef[]` array.**\n- **`#body` slots → `cell` snippets** via `renderSnippet`.\n- **Prime theming → `--sg-*` tokens / Tailwind** - no Prime theme\n dependency.\n- **`lazy` → `externalSort` / `externalFilter`** with refetch on events.\n\n## Frequently asked questions\n\n### How do Prime `<Column>` definitions map to SvGrid?\n\nEach `<Column field header />` becomes a `{ field, header }` object in SvGrid's\n`columns` array, and `#body` templates become `renderSnippet` cells. Sorting and\nfiltering move from per-column props to the `rowSortingFeature` /\n`columnFilteringFeature` registration.\n\n### Is SvGrid open-source like the Prime grid core?\n\n`@svgrid/grid` is MIT with no licence key or eligibility conditions. The\nPrime cores were MIT through PrimeVue 4; from PrimeVue 5 the npm package\ncarries the PrimeUI licence, whose free Community License depends on your\nrevenue, developer count, headcount and funding, and whose Commercial\nLicense is per developer with a key. The other difference is framework:\nSvGrid is Svelte 5, not Vue / Angular / React.\n\n### Do I lose Prime theming?\n\nYou re-create the look with `--sg-*` tokens (optionally driven by your Tailwind\ntheme), so the grid matches your design system without a Prime theme dependency.\n\n## What you end up with\n\nSorting, filtering, pagination and row selection in one pass.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable pageable pageSize={3} selectable />\n```\n\n## See also\n\n- [SvGrid vs Prime DataTable](https://svgrid.com/compare/primevue-datatable/) - the side-by-side comparison\n- [Tailwind integration](./tailwind.md) - match your design system\n- [Cell components](./cells/cell-components.md) - snippet cells + editors\n"
|
|
4766
4766
|
},
|
|
4767
4767
|
{
|
|
4768
4768
|
"slug": "help/migrating-from-react-data-grid",
|
|
4769
4769
|
"path": "docs/help/migrating-from-react-data-grid.md",
|
|
4770
4770
|
"title": "Migrating from React Data Grid (adazzle)",
|
|
4771
4771
|
"section": "Help",
|
|
4772
|
-
"markdown": "# Migrating from React Data Grid (adazzle)\n\n`react-data-grid` is a fast, Excel-like React grid with a clean column\nAPI. SvGrid mirrors its shape - virtualized DOM, typed columns, inline\nediting, custom cells - on Svelte 5 runes instead of React, so the port\nis mostly a column rename pass.\n\n> Estimated effort: **2-4 hours** per grid, more if you lean on custom\n> editors.\n\n<!-- facts:start react-data-grid -->\n> **Facts, checked 12 Sep 2026.** `react-data-grid` 7.0.0-beta.61, MIT, last published 14 Jul 2026, 2,180,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `react-data-grid` 7.0.0-beta.61 15.7 KB JS + 2.1 KB CSS, react + react-dom external (measured 12 Sep 2026). React Data Grid pricing, as its site states it: react-data-grid is MIT on npm and free; no licence is sold (https://github.com/adazzle/react-data-grid, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4772
|
+
"markdown": "# Migrating from React Data Grid (adazzle)\n\n`react-data-grid` is a fast, Excel-like React grid with a clean column\nAPI. SvGrid mirrors its shape - virtualized DOM, typed columns, inline\nediting, custom cells - on Svelte 5 runes instead of React, so the port\nis mostly a column rename pass.\n\n> Estimated effort: **2-4 hours** per grid, more if you lean on custom\n> editors.\n\n<!-- facts:start react-data-grid -->\n> **Facts, checked 12 Sep 2026.** `react-data-grid` 7.0.0-beta.61, MIT, last published 14 Jul 2026, 2,180,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `react-data-grid` 7.0.0-beta.61 15.7 KB JS + 2.1 KB CSS, react + react-dom external (measured 12 Sep 2026). React Data Grid pricing, as its site states it: react-data-grid is MIT on npm and free; no licence is sold (https://github.com/adazzle/react-data-grid, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs React Data Grid (adazzle)](https://svgrid.com/compare/react-data-grid/).\n<!-- facts:end -->\n\n## Vocabulary cheat sheet\n\n| react-data-grid | sv-grid |\n| ---------------------------------------- | ----------------------------------------- |\n| `<DataGrid columns rows />` | `<SvGrid columns data />` |\n| `{ key: 'name', name: 'Name' }` | `{ field: 'name', header: 'Name' }` |\n| `renderCell: (p) => <Badge .../>` | `cell: (c) => renderSnippet(Badge, {...})` |\n| `renderEditCell` / `editor` | `editorType` (+ custom `cellEditor`) |\n| `rowKeyGetter={(r) => r.id}` | `getRowId={(r) => r.id}` |\n| `onRowsChange={setRows}` | `onCellValueChange` (+ your state) |\n| `sortColumns` / `onSortColumnsChange` | `rowSortingFeature` + `onSortingChange` |\n| `<DataGrid className=...>` theming | `--sg-*` tokens / Tailwind |\n\n## Before / after\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import DataGrid, { textEditor } from 'react-data-grid'\n- const columns = [\n- { key: 'name', name: 'Name' },\n- { key: 'amount', name: 'Amount', renderEditCell: textEditor },\n- ]\n- <DataGrid columns={columns} rows={rows} rowKeyGetter={(r) => r.id} onRowsChange={setRows} />\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', editorType: 'text' },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features}\n+ getRowId={(r) => r.id} enableInlineEditing\n+ onCellValueChange={(e) => save(e)} />\n```\n\n## What changes\n\n- **React → Svelte 5.** `renderCell` / `renderEditCell` become\n `renderSnippet` snippets and `editorType`.\n- **`onRowsChange` → `onCellValueChange`.** SvGrid writes to its own\n working copy; subscribe to commits and persist where you like.\n- **Filtering UI is built in.** react-data-grid leaves the filter row to\n you; SvGrid ships the Excel-style menu.\n\n## Frequently asked questions\n\n### How do react-data-grid columns map to SvGrid?\n\n`key` becomes `field`, `name` becomes `header`, `renderCell` becomes a\n`renderSnippet` cell, and editors map to `editorType` (or a custom `cellEditor`\nsnippet). `rowKeyGetter` becomes `getRowId`.\n\n### Is SvGrid free like react-data-grid?\n\nYes - `@svgrid/grid` is MIT-licensed, like react-data-grid. SvGrid adds an\noptional paid Enterprise pack for export, import, pivot, and AI.\n\n### Does SvGrid have built-in filtering?\n\nYes. react-data-grid asks you to build the filter UI; SvGrid ships an\nExcel-style column filter menu and a global filter out of the box.\n\n## What you end up with\n\nInline editing with cell-range selection, which is the reason most people picked it.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} editable enableCellSelection sortable />\n```\n\n## See also\n\n- [SvGrid vs React Data Grid](https://svgrid.com/compare/react-data-grid/) - the side-by-side comparison\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - sibling React-to-Svelte guide\n- [Cell components](./cells/cell-components.md) - custom cells + editors\n"
|
|
4773
4773
|
},
|
|
4774
4774
|
{
|
|
4775
4775
|
"slug": "help/migrating-from-shadcn-data-table",
|
|
4776
4776
|
"path": "docs/help/migrating-from-shadcn-data-table.md",
|
|
4777
4777
|
"title": "Migrating from the shadcn-svelte data table",
|
|
4778
4778
|
"section": "Help",
|
|
4779
|
-
"markdown": "# Migrating from the shadcn-svelte data table\n\nThe shadcn-svelte **Data Table** is not the same thing as its `<Table>`\ncomponent. `<Table>` is presentation only. The data table is a recipe\nbuilt on TanStack Table v9 that you copy into your own repo: it already\ndoes sorting, filtering, pagination, row selection, and column\nvisibility. If that is what you have, this is your page. If you have the\nplain styled `<Table>` and hand-wrote the sorting yourself, read\n[Migrating from a UI-kit table](./migrating-from-ui-kit-tables.md)\ninstead.\n\n> Estimated effort: **20-40 min** per table. Your column definitions and\n> your feature registration carry over almost unchanged. Most of the work\n> is deleting files.\n\n<!-- facts:start tanstack-table,svelte-ui-kit-tables -->\n> **Facts, checked 12 Sep 2026.** `@tanstack/svelte-table` 9.2.4, MIT, last published 28 Aug 2026, 231,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@tanstack/svelte-table` 9.2.4 36.3 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). TanStack Table pricing, as its site states it: TanStack Table is MIT and free; tanstack.com is sponsor-supported and offers Enterprise Support as private consulting and expert support, with no licence sold for the table (https://tanstack.com/table/latest, read 12 Sep 2026). Flowbite / Skeleton / shadcn-svelte tables pricing, as its site states it: Flowbite Svelte, Skeleton and shadcn-svelte are MIT component libraries; their table components are free and no grid licence is sold (https://github.com/themesberg/flowbite-svelte, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/), [SvGrid vs Flowbite / Skeleton / shadcn-svelte tables](https://svgrid.com/compare/svelte-ui-kit-tables/).\n<!-- facts:end -->\n\n## Why this port is small\n\nSvGrid speaks the same vocabulary TanStack Table v9 introduced. These are\nreal exports from `@svgrid/grid`, not lookalikes:\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```ts\nimport {\n tableFeatures,\n rowSortingFeature,\n columnFilteringFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n rowExpandingFeature,\n columnGroupingFeature,\n} from '@svgrid/grid'\n```\n\nSo `data-table-features.ts` moves over as-is, and `columns.ts` keeps its\nshape. What does not move is the rendering scaffolding, because SvGrid\nships a renderer and there is nothing to translate it into.\n\n## What happens to each file\n\nThe shadcn recipe generates seven files. Five of them stop existing.\n\n| Their file | Becomes |\n| --- | --- |\n| `data-table-features.ts` | Kept. Same `tableFeatures({...})` call. |\n| `columns.ts` | Kept, minus the `header` render helpers. `{ accessorKey: 'email' }` becomes `{ field: 'email' }`. |\n| `data-table.svelte` | Deleted. It is `<table>` markup over `getHeaderGroups()` / `getRowModel()`, which `<SvGrid>` does. |\n| `data-table-checkbox.svelte` | Deleted. `showRowSelection` renders the column and the select-all header. |\n| `data-table-email-button.svelte` | Deleted. `sortable` makes every header a sort toggle. |\n| `data-table-actions.svelte` | Kept if you want it, as a cell snippet. |\n| `+page.svelte` | Kept. It now renders one component instead of wiring state. |\n\n## Let the codemod do the mechanical part\n\n```bash\nnpx @svgrid/migrate src/routes/payments # preview\nnpx @svgrid/migrate src/routes/payments --write # apply\n```\n\nIt previews by default and only writes with `--write`. Point it at the whole\nroute directory rather than a single file: the shadcn layout keeps `features`\nin its own module, and the codemod follows that import to work out which\nprops the component needs.\n\nIt renames the column keys, re-points the imports, strips the features SvGrid\ndoes not have, and deletes the markup along with the `$state` / `onXChange`\npairs. Custom `cell` and `header` render functions are kept and reported, never\nguessed at. Run your type-checker afterwards - the markup is regenerated rather\nthan edited.\n\n## Before and after\n\n```diff\n- <script lang=\"ts\">\n- import { createSvelteTable, FlexRender } from '$lib/components/ui/data-table'\n- import { columns } from './columns'\n- import { features } from './data-table-features'\n-\n- let sorting = $state([])\n- let filters = $state([])\n- let selection = $state({})\n- let pagination = $state({ pageIndex: 0, pageSize: 10 })\n-\n- const table = createSvelteTable({\n- get data() { return data },\n- columns, features,\n- state: { get sorting() { return sorting }, /* ...and three more... */ },\n- onSortingChange: (u) => (sorting = typeof u === 'function' ? u(sorting) : u),\n- // ...one of these per piece of state...\n- })\n- </script>\n-\n- <Table.Root>\n- <Table.Header>\n- {#each table.getHeaderGroups() as headerGroup}\n- <!-- ...twenty more lines of markup... -->\n- {/each}\n- </Table.Header>\n- <Table.Body>\n- {#each table.getRowModel().rows as row}\n- <!-- ...and twenty more... -->\n- {/each}\n- </Table.Body>\n- </Table.Root>\n\n+ <script lang=\"ts\">\n+ import { SvGrid } from '@svgrid/grid'\n+ import '@svgrid/grid/themes/shadcn.css'\n+ import { columns } from './columns'\n+ import { features } from './data-table-features'\n+ </script>\n+\n+ <SvGrid\n+ {data} {columns} {features}\n+ sortable filterable showGlobalFilter showRowSelection\n+ pageable showPagination pageSize={10}\n+ fitColumns\n+ />\n```\n\nThe four `$state` declarations and their four `onXChange` updaters go\naway with the markup. Sorting, filtering, paging, and selection state\nlive in the grid.\n\nColumn visibility moves too: mark a column `visible: false` to start it\nhidden, and users toggle it from the header column menu. You no longer\nmaintain a dropdown for it.\n\n## One command\n\nUse the CLI you already have:\n\n```sh\nnpx shadcn-svelte@latest add https://svgrid.com/r/data-table.json\n```\n\nThat writes a ready-to-edit `data-table.svelte` into\n`$lib/components/ui/data-table/`, beside your other components, and\ninstalls `@svgrid/grid`. It is a normal registry item, so `components.json`\naliases and your existing setup are respected.\n\nIf you are not in a shadcn project, the same component ships through\nSvGrid's own scaffolder:\n\n```sh\nnpx @svgrid/ui add data-table\n```\n\nBoth routes write the identical file. It is yours to edit, exactly like a\nshadcn recipe. The difference is where the engine lives.\n\n## The upgrade path is the real difference\n\nBoth approaches put a file you own in your repo. Only one puts the\n*engine* in a package.\n\nWhen TanStack Table went from v8 to v9, `useReactTable` became `useTable`,\nthe `get*RowModel()` options became a features object, and `flexRender`\nbecame a component. Every copied data-table had to be hand-fixed, because\nthere is no `npm update` for code you pasted. With SvGrid the file you own\nstays a thin call site, and the behaviour behind it updates with a version\nbump.\n\nThe cost scales with how much you pasted. A seven-file starter is an\nafternoon. The richer community grids paste a whole subsystem - row\nrendering, virtualization, context menus, paste dialogs, hooks, config -\nand every one of those files is now yours to carry through the next\nupstream change.\n\n## Keep your design system\n\nYou do not have to leave shadcn's look, and you do not have to leave its\nmarkup either.\n\n- **Tokens.** `import '@svgrid/grid/themes/shadcn.css'` is a one-line\n match for the default palette in light and dark. To follow a customized\n theme, map your `--background` / `--border` / `--primary` onto the\n `--sg-*` properties - see the [shadcn integration\n guide](./shadcn.md).\n- **Your own markup.** If you want to keep shadcn's `Table.Root` /\n `Table.Row` elements exactly as they are, use the headless core from\n `@svgrid/grid/core` and swap only the engine. See\n [Why headless?](../why-headless.md).\n\n## What you gain\n\nThe official recipe stops where its docs stop: sorting, filtering,\npagination, row selection, column visibility. Community registry items go\nfurther, at the cost of pasting a whole multi-file subsystem into your\nrepo. In SvGrid each of these is a prop:\n\n- **Virtualization** (`virtualization`) - the official recipe has none, so\n a large table is a rewrite rather than a prop.\n- **Inline editing** (`editable`) and cell-range selection\n (`enableCellSelection`).\n- **Grouping with aggregation** (`groupable`) and tree data (`treeData`).\n- **Export** to CSV, and to Excel / PDF on the paid tier.\n- **WAI-ARIA grid semantics and keyboard navigation**, instead of a plain\n `<table>` you keep accessible yourself.\n\n## What you give up\n\n- **A file you can read top to bottom.** The recipe's behaviour is\n visible in your repo; SvGrid's is behind a prop. That is the trade the\n whole page is about.\n- **Pixel-level control of the markup**, unless you go headless.\n- **Weight.** For a short static list that never sorts, the copied\n recipe is smaller.\n\n## Frequently asked questions\n\n### Does SvGrid replace shadcn-svelte?\n\nNo. It replaces one recipe in it. Your buttons, dialogs, and inputs stay\nexactly as they are, and the grid reads the same theme variables they do.\n\n### Can I keep my existing columns.ts?\n\nMostly. Rename `accessorKey` to `field`, drop the `header` render\nhelpers that only existed to draw a sort button, and the rest carries\nover. Custom cells become snippets via `renderSnippet`.\n\n### Do I have to give up owning the code?\n\nYou still own the call site - `npx @svgrid/ui add data-table` writes a\nfile into your project that you edit freely. What you stop owning is the\nrow-model plumbing, which is the part that broke on the v8 to v9 upgrade.\n\n### Is this worth it for a 50-row table?\n\nProbably not, unless you want editing, grouping, or export later. The\ncase gets strong when the table grows past what fits on a page, or when\nthe next feature request is one you would otherwise hand-build.\n\n## What you end up with\n\nSorting, filtering, pagination and selection - the shadcn data-table demo, as props.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable pageable pageSize={3} selectable />\n```\n\n## See also\n\n- [shadcn-svelte integration](./shadcn.md) - matching the theme\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - the\n underlying API map\n- [Migrating from a UI-kit table](./migrating-from-ui-kit-tables.md) - for\n the plain styled `<Table>`\n- [Why headless?](../why-headless.md) - keeping your own markup\n"
|
|
4779
|
+
"markdown": "# Migrating from the shadcn-svelte data table\n\nThe shadcn-svelte **Data Table** is not the same thing as its `<Table>`\ncomponent. `<Table>` is presentation only. The data table is a recipe\nbuilt on TanStack Table v9 that you copy into your own repo: it already\ndoes sorting, filtering, pagination, row selection, and column\nvisibility. If that is what you have, this is your page. If you have the\nplain styled `<Table>` and hand-wrote the sorting yourself, read\n[Migrating from a UI-kit table](./migrating-from-ui-kit-tables.md)\ninstead.\n\n> Estimated effort: **20-40 min** per table. Your column definitions and\n> your feature registration carry over almost unchanged. Most of the work\n> is deleting files.\n\n<!-- facts:start tanstack-table,svelte-ui-kit-tables -->\n> **Facts, checked 12 Sep 2026.** `@tanstack/svelte-table` 9.2.4, MIT, last published 28 Aug 2026, 231,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@tanstack/svelte-table` 9.2.4 36.3 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). TanStack Table pricing, as its site states it: TanStack Table is MIT and free; tanstack.com is sponsor-supported and offers Enterprise Support as private consulting and expert support, with no licence sold for the table (https://tanstack.com/table/latest, read 12 Sep 2026). Flowbite / Skeleton / shadcn-svelte tables pricing, as its site states it: Flowbite Svelte, Skeleton and shadcn-svelte are MIT component libraries; their table components are free and no grid licence is sold (https://github.com/themesberg/flowbite-svelte, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/), [SvGrid vs Flowbite / Skeleton / shadcn-svelte tables](https://svgrid.com/compare/svelte-ui-kit-tables/).\n<!-- facts:end -->\n\n## Why this port is small\n\nSvGrid speaks the same vocabulary TanStack Table v9 introduced. These are\nreal exports from `@svgrid/grid`, not lookalikes:\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```ts\nimport {\n tableFeatures,\n rowSortingFeature,\n columnFilteringFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n rowExpandingFeature,\n columnGroupingFeature,\n} from '@svgrid/grid'\n```\n\nSo `data-table-features.ts` moves over as-is, and `columns.ts` keeps its\nshape. What does not move is the rendering scaffolding, because SvGrid\nships a renderer and there is nothing to translate it into.\n\n## What happens to each file\n\nThe shadcn recipe generates seven files. Five of them stop existing.\n\n| Their file | Becomes |\n| --- | --- |\n| `data-table-features.ts` | Kept. Same `tableFeatures({...})` call. |\n| `columns.ts` | Kept, minus the `header` render helpers. `{ accessorKey: 'email' }` becomes `{ field: 'email' }`. |\n| `data-table.svelte` | Deleted. It is `<table>` markup over `getHeaderGroups()` / `getRowModel()`, which `<SvGrid>` does. |\n| `data-table-checkbox.svelte` | Deleted. `showRowSelection` renders the column and the select-all header. |\n| `data-table-email-button.svelte` | Deleted. `sortable` makes every header a sort toggle. |\n| `data-table-actions.svelte` | Kept if you want it, as a cell snippet. |\n| `+page.svelte` | Kept. It now renders one component instead of wiring state. |\n\n## Let the codemod do the mechanical part\n\n```bash\nnpx @svgrid/migrate src/routes/payments # preview\nnpx @svgrid/migrate src/routes/payments --write # apply\n```\n\nIt previews by default and only writes with `--write`. Point it at the whole\nroute directory rather than a single file: the shadcn layout keeps `features`\nin its own module, and the codemod follows that import to work out which\nprops the component needs.\n\nIt renames the column keys, re-points the imports, strips the features SvGrid\ndoes not have, and deletes the markup along with the `$state` / `onXChange`\npairs. Custom `cell` and `header` render functions are kept and reported, never\nguessed at. Run your type-checker afterwards - the markup is regenerated rather\nthan edited.\n\n## Before and after\n\n```diff\n- <script lang=\"ts\">\n- import { createSvelteTable, FlexRender } from '$lib/components/ui/data-table'\n- import { columns } from './columns'\n- import { features } from './data-table-features'\n-\n- let sorting = $state([])\n- let filters = $state([])\n- let selection = $state({})\n- let pagination = $state({ pageIndex: 0, pageSize: 10 })\n-\n- const table = createSvelteTable({\n- get data() { return data },\n- columns, features,\n- state: { get sorting() { return sorting }, /* ...and three more... */ },\n- onSortingChange: (u) => (sorting = typeof u === 'function' ? u(sorting) : u),\n- // ...one of these per piece of state...\n- })\n- </script>\n-\n- <Table.Root>\n- <Table.Header>\n- {#each table.getHeaderGroups() as headerGroup}\n- <!-- ...twenty more lines of markup... -->\n- {/each}\n- </Table.Header>\n- <Table.Body>\n- {#each table.getRowModel().rows as row}\n- <!-- ...and twenty more... -->\n- {/each}\n- </Table.Body>\n- </Table.Root>\n\n+ <script lang=\"ts\">\n+ import { SvGrid } from '@svgrid/grid'\n+ import '@svgrid/grid/themes/shadcn.css'\n+ import { columns } from './columns'\n+ import { features } from './data-table-features'\n+ </script>\n+\n+ <SvGrid\n+ {data} {columns} {features}\n+ sortable filterable showGlobalFilter showRowSelection\n+ pageable showPagination pageSize={10}\n+ fitColumns\n+ />\n```\n\nThe four `$state` declarations and their four `onXChange` updaters go\naway with the markup. Sorting, filtering, paging, and selection state\nlive in the grid.\n\nColumn visibility moves too: mark a column `visible: false` to start it\nhidden, and users toggle it from the header column menu. You no longer\nmaintain a dropdown for it.\n\n## One command\n\nUse the CLI you already have:\n\n```sh\nnpx shadcn-svelte@latest add https://svgrid.com/r/data-table.json\n```\n\nThat writes a ready-to-edit `data-table.svelte` into\n`$lib/components/ui/data-table/`, beside your other components, and\ninstalls `@svgrid/grid`. It is a normal registry item, so `components.json`\naliases and your existing setup are respected.\n\nIf you are not in a shadcn project, the same component ships through\nSvGrid's own scaffolder:\n\n```sh\nnpx @svgrid/ui add data-table\n```\n\nBoth routes write the identical file. It is yours to edit, exactly like a\nshadcn recipe. The difference is where the engine lives.\n\n## The upgrade path is the real difference\n\nBoth approaches put a file you own in your repo. Only one puts the\n*engine* in a package.\n\nWhen TanStack Table went from v8 to v9, `useReactTable` became `useTable`,\nthe `get*RowModel()` options became a features object, and `flexRender`\nbecame a component. Every copied data-table had to be hand-fixed, because\nthere is no `npm update` for code you pasted. With SvGrid the file you own\nstays a thin call site, and the behaviour behind it updates with a version\nbump.\n\nThe cost scales with how much you pasted. A seven-file starter is an\nafternoon. The richer community grids paste a whole subsystem - row\nrendering, virtualization, context menus, paste dialogs, hooks, config -\nand every one of those files is now yours to carry through the next\nupstream change.\n\n## Keep your design system\n\nYou do not have to leave shadcn's look, and you do not have to leave its\nmarkup either.\n\n- **Tokens.** `import '@svgrid/grid/themes/shadcn.css'` is a one-line\n match for the default palette in light and dark. To follow a customized\n theme, map your `--background` / `--border` / `--primary` onto the\n `--sg-*` properties - see the [shadcn integration\n guide](./shadcn.md).\n- **Your own markup.** If you want to keep shadcn's `Table.Root` /\n `Table.Row` elements exactly as they are, use the headless core from\n `@svgrid/grid/core` and swap only the engine. See\n [Why headless?](../why-headless.md).\n\n## What you gain\n\nThe official recipe stops where its docs stop: sorting, filtering,\npagination, row selection, column visibility. Community registry items go\nfurther, at the cost of pasting a whole multi-file subsystem into your\nrepo. In SvGrid each of these is a prop:\n\n- **Virtualization** (`virtualization`) - the official recipe has none, so\n a large table is a rewrite rather than a prop.\n- **Inline editing** (`editable`) and cell-range selection\n (`enableCellSelection`).\n- **Grouping with aggregation** (`groupable`) and tree data (`treeData`).\n- **Export** to CSV, and to Excel / PDF on the paid tier.\n- **WAI-ARIA grid semantics and keyboard navigation**, instead of a plain\n `<table>` you keep accessible yourself.\n\n## What you give up\n\n- **A file you can read top to bottom.** The recipe's behaviour is\n visible in your repo; SvGrid's is behind a prop. That is the trade the\n whole page is about.\n- **Pixel-level control of the markup**, unless you go headless.\n- **Weight.** For a short static list that never sorts, the copied\n recipe is smaller.\n\n## Frequently asked questions\n\n### Does SvGrid replace shadcn-svelte?\n\nNo. It replaces one recipe in it. Your buttons, dialogs, and inputs stay\nexactly as they are, and the grid reads the same theme variables they do.\n\n### Can I keep my existing columns.ts?\n\nMostly. Rename `accessorKey` to `field`, drop the `header` render\nhelpers that only existed to draw a sort button, and the rest carries\nover. Custom cells become snippets via `renderSnippet`.\n\n### Do I have to give up owning the code?\n\nYou still own the call site - `npx @svgrid/ui add data-table` writes a\nfile into your project that you edit freely. What you stop owning is the\nrow-model plumbing, which is the part that broke on the v8 to v9 upgrade.\n\n### Is this worth it for a 50-row table?\n\nProbably not, unless you want editing, grouping, or export later. The\ncase gets strong when the table grows past what fits on a page, or when\nthe next feature request is one you would otherwise hand-build.\n\n## What you end up with\n\nSorting, filtering, pagination and selection - the shadcn data-table demo, as props.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable pageable pageSize={3} selectable />\n```\n\n## See also\n\n- [shadcn-svelte integration](./shadcn.md) - matching the theme\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - the\n underlying API map\n- [Migrating from a UI-kit table](./migrating-from-ui-kit-tables.md) - for\n the plain styled `<Table>`\n- [Why headless?](../why-headless.md) - keeping your own markup\n"
|
|
4780
4780
|
},
|
|
4781
4781
|
{
|
|
4782
4782
|
"slug": "help/migrating-from-smart-grid",
|
|
4783
4783
|
"path": "docs/help/migrating-from-smart-grid.md",
|
|
4784
4784
|
"title": "Migrating from Smart.Grid (Smart Web Components)",
|
|
4785
4785
|
"section": "Help",
|
|
4786
|
-
"markdown": "# Migrating from Smart.Grid (Smart Web Components)\n\nSmart.Grid (htmlelements.com) and SvGrid come from the **same team**.\nSmart.Grid is a framework-agnostic custom element - it even works inside\nSvelte today - while SvGrid is the reactive, Svelte-5-native option. If\nyou are standardising a Svelte app on idiomatic components, this guide\nmaps a Smart.Grid setup onto SvGrid.\n\n> Estimated effort: **2-4 hours** per grid. The main shift is from a\n> custom element bound through properties / attributes to a reactive\n> Svelte component.\n\n<!-- facts:start smart-grid -->\n> **Facts, checked 12 Sep 2026.** `smart-webcomponents` 27.0.1, ISC, last published 13 Aug 2026, 6,620 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Smart.Grid pricing, as its site states it: htmlelements.com lists the Developer License at $499 (on sale at $399) per developer, perpetual, or $39 per month, and the Team License at $1,499 per five developers; the free Community License covers the core components but not the Grid (https://www.htmlelements.com/license/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4786
|
+
"markdown": "# Migrating from Smart.Grid (Smart Web Components)\n\nSmart.Grid (htmlelements.com) and SvGrid come from the **same team**.\nSmart.Grid is a framework-agnostic custom element - it even works inside\nSvelte today - while SvGrid is the reactive, Svelte-5-native option. If\nyou are standardising a Svelte app on idiomatic components, this guide\nmaps a Smart.Grid setup onto SvGrid.\n\n> Estimated effort: **2-4 hours** per grid. The main shift is from a\n> custom element bound through properties / attributes to a reactive\n> Svelte component.\n\n<!-- facts:start smart-grid -->\n> **Facts, checked 12 Sep 2026.** `smart-webcomponents` 27.0.1, ISC, last published 13 Aug 2026, 6,620 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Smart.Grid pricing, as its site states it: htmlelements.com lists the Developer License at $499 (on sale at $399) per developer, perpetual, or $39 per month, and the Team License at $1,499 per five developers; the free Community License covers the core components but not the Grid (https://www.htmlelements.com/license/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs Smart.Grid (Smart Web Components)](https://svgrid.com/compare/smart-grid/).\n<!-- facts:end -->\n\n## Vocabulary cheat sheet\n\n| Smart.Grid (web component) | sv-grid |\n| ---------------------------------------- | ----------------------------------------- |\n| `<smart-grid>` element | `<SvGrid ... />` |\n| `grid.dataSource = new Smart.DataAdapter`| `data` array (or `externalSort/Filter`) |\n| `{ label: 'Name', dataField: 'name' }` | `{ header: 'Name', field: 'name' }` |\n| `template` / cell template | `cell: (c) => renderSnippet(...)` |\n| `editing` + editor | `enableInlineEditing` + `editorType` |\n| `sorting` / `filtering` | `rowSortingFeature` / `columnFilteringFeature` |\n| `grouping` | `columnGroupingFeature` + `api.setGroupBy()` |\n| `paging` + `pager` | `showPagination` |\n| element events (`change`, ...) | `onCellValueChange`, `onApiReady` |\n| `theme` attribute | `--sg-*` tokens / Tailwind |\n\n## Before / after\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- <smart-grid id=\"grid\" sorting filtering paging></smart-grid>\n- <script>\n- const grid = document.querySelector('#grid')\n- grid.dataSource = new Smart.DataAdapter({ dataSource: rows, dataFields: [...] })\n- grid.columns = [\n- { label: 'Name', dataField: 'name' },\n- { label: 'Amount', dataField: 'amount' },\n- ]\n- </script>\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} showPagination />\n```\n\n## What changes\n\n- **Custom element + DataAdapter → reactive `$state`.** Data binding is a\n prop, not an assigned `dataSource`.\n- **Element templates → Svelte snippets** via `renderSnippet`.\n- **`theme` attribute → `--sg-*` tokens.**\n\n## A note on family\n\nSmart.Grid is a genuinely good framework-agnostic grid from the same\nteam, and it runs in Svelte as a web component. The reason to pick SvGrid\nis *idiomatic* Svelte: runes, snippets, and an MIT core. If you need one\ngrid across Angular, React, Vue, Svelte, and vanilla, Smart.Grid is the\nright call.\n\n## Frequently asked questions\n\n### Is SvGrid from the same team as Smart.Grid?\n\nYes. Smart Web Components (htmlelements.com) and SvGrid are built by the same\nteam. SvGrid is the Svelte-5-native option with an MIT community core.\n\n### Can I keep using Smart.Grid in Svelte instead?\n\nYes - Smart.Grid is a web component and works inside Svelte. Choose SvGrid when\nyou want an idiomatic Svelte component (runes + snippets) rather than a custom\nelement bound through properties.\n\n### How do Smart.Grid columns map to SvGrid?\n\n`label` becomes `header`, `dataField` becomes `field`, and element templates\nbecome `renderSnippet` cells. Sorting / filtering / grouping move to registered\nfeatures.\n\n## More examples\n\n### Smart.Chart integration\n\nMounts a <smart-chart> web component (htmlelements.com) and pipes the grid's displayed rows into its dataSource. Re-aggregates on every filter / sort.\n\n<div data-docs-demo=\"77-smart-chart\" data-height=\"460\"></div>\n\n## What you end up with\n\nSorting, filtering and editing with a footer summary.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable editable summary />\n```\n\n## The ported grid, running\n\nSorting, filtering, editing and a totals row - the working set a Smart grid\nusually carries, as props.\n\n```svelte {runnable}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n city: string\n age: number\n salary: number\n }\n\n const seed: Person[] = [\n { id: 1, name: 'Ada Lovelace', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', city: 'Portland', age: 54, salary: 155000 },\n ]\n\n let rows = $state<Person[]>(seed.map((p) => ({ ...p })))\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 180, editorType: 'text' },\n { field: 'city', header: 'City', width: 150, editorType: 'text' },\n { field: 'salary', header: 'Salary', width: 150, editorType: 'number', summary: 'sum',\n format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n\n<SvGrid data={rows} {columns} sortable filterable editable summary />\n```\n\n## See also\n\n- [SvGrid vs Smart.Grid](https://svgrid.com/compare/smart-grid/) - the side-by-side comparison\n- [About SvGrid](https://svgrid.com/about/) - built by jQWidgets / htmlelements.com\n- [Cell components](./cells/cell-components.md) - snippet-based custom cells\n"
|
|
4787
4787
|
},
|
|
4788
4788
|
{
|
|
4789
4789
|
"slug": "help/migrating-from-svar-svelte-datagrid",
|
|
4790
4790
|
"path": "docs/help/migrating-from-svar-svelte-datagrid.md",
|
|
4791
4791
|
"title": "Migrating from SVAR Svelte DataGrid",
|
|
4792
4792
|
"section": "Help",
|
|
4793
|
-
"markdown": "# Migrating from SVAR Svelte DataGrid\n\nSVAR Svelte DataGrid (`wx-svelte-grid`) is, like SvGrid, an actual\nSvelte-native grid rather than a wrapper, and both are MIT-licensed and\nfree for commercial use. Because both are component-first with\narray-of-object column definitions, a port is mostly a configuration\ntranslation. The reasons people switch are **capability** (SvGrid adds\nrow grouping with aggregation, master-detail, Excel-style cell-range\nselection, integrated charts, and pivot) and **architecture** (SvGrid\nalso exposes a headless engine and an MCP server).\n\n> Estimated effort: **2-4 hours** per grid - a prop and event rename\n> pass, plus re-theming.\n>\n> SVAR's exact prop and event names evolve across releases; check the\n> current SVAR docs and map them onto the SvGrid equivalents below.\n\n<!-- facts:start svar-svelte-datagrid -->\n> **Facts, checked 12 Sep 2026.** `wx-svelte-grid` 2.7.0, MIT, last published 3 Jun 2026, 62,800 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `wx-svelte-grid` 2.7.0 51.5 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). SVAR Svelte DataGrid pricing, as its site states it: The DataGrid is MIT and free for commercial use with no paid tier; svar.dev sells PRO editions of its Gantt, Calendar and Kanban components and offers paid consulting and custom development, with no price list for the grid (https://svar.dev/svelte/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/).\n<!-- facts:end -->\n\n## Concept map\n\n| SVAR DataGrid (wx-svelte-grid) | sv-grid |\n| ----------------------------------------- | ----------------------------------------- |\n| `<Grid {data} {columns} />` | `<SvGrid data={...} columns={...} />` |\n| `columns: [{ id, header, width, ... }]` | `columns: [{ field, header, width, ... }]` |\n| `sizes={{ rowHeight, columnWidth }}` | `rowHeight` prop, `width` per column |\n| `autoRowHeight` | `autoRowHeight` |\n| Per-column `editor` / `template` | `editorType` + `cell` snippet |\n| `sort: true` on a column, `sortMarks` | `rowSortingFeature`; `initialSorting` |\n| Header filters, the Filter component | `columnFilteringFeature`; Excel-style menu and filter row built in |\n| `tree` prop + `data` with children | `treeData={{ parentField }}` or `rowExpandingFeature` with sub rows |\n| `select` / `multiselect` | `selectionMode=\"row\"` (+ checkbox column) |\n| `split={{ left: n }}` (pinned columns) | `initialColumnPinning` or `pinned: 'left' \\| 'right'` per column |\n| `reorder` (row drag) | `rowDragManaged` |\n| `undo` prop, undo/redo hotkeys | `history` prop; `api.undo()` / `api.redo()` |\n| Context menu component | `contextMenu` prop with items |\n| `init={(api) => ...}` | `onApiReady={(api) => ...}` |\n| `api.exec('sort-rows', { key, order })` | `api.setSort(field, 'asc' \\| 'desc')` |\n| `api.exec('filter-rows', { filter })` | `api.setFilter(field, { operator, value })` |\n| `api.on('...')` event bus | `onXxx` callback props |\n| Export to CSV, print API | `api.exportCsv()` (free); print in `@svgrid/enterprise` |\n| `RestDataProvider` | server-side row model / `externalSort` + `externalFilter` |\n| Theme / skin components (Willow, Material)| `--sg-*` CSS custom properties / Tailwind |\n\n## Before / after (shape, not exact prop names)\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- <script>\n- import { Grid } from 'wx-svelte-grid'\n- const columns = [\n- { id: 'name', header: 'Name', width: 200 },\n- { id: 'amount', header: 'Amount', width: 120, editor: 'text' },\n- ]\n- </script>\n-\n- <Grid {data} {columns} />\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name', width: 200 },\n+ { field: 'amount', header: 'Amount', width: 120, editorType: 'text' },\n+ ]\n+ </script>\n+\n+ <SvGrid data={data} columns={columns} features={features} enableInlineEditing />\n```\n\n## Licensing note\n\nBoth grids are MIT and free for commercial use, so licensing is not the\ndeciding factor. The difference is monetization: SVAR keeps the whole\ngrid free (including CSV export and print) and sells PRO editions of its\nGantt, Calendar and Kanban instead, whereas SvGrid's `@svgrid/grid` core is\nMIT and the optional `@svgrid/enterprise` pack (XLSX/PDF export, print,\npivot, import, support) is the paid piece. CSV, TSV and JSON export and the\nin-grid AI helpers are free on SvGrid too. If all you need is CSV export and\nprint, SVAR gives both free; if you need pivot, Excel or PDF output, or a\nsupport SLA, that is Enterprise on SvGrid.\n\n## What you get with SvGrid\n\n- **Row grouping with aggregation**, **master-detail**, **pinned rows**,\n and left/right column freezing - beyond SVAR's documented surface.\n- A **headless engine** (`createSvGrid` + row models) in addition to the\n component, if you want to compose your own layer.\n- **Excel-style filter menu**, **cell-range selection + TSV copy**, a\n **fill handle**, **integrated charts**, and a documented **imperative API**.\n- **In-grid AI helpers** (natural-language filter, smart fill, summarise),\n free against a model you register, and **@svgrid/mcp** so AI assistants\n answer accurately about your grid and can check the code they write.\n\nThe two features most SVAR teams port for:\n\n<div data-docs-demo=\"07-grouping-aggregation\" data-height=\"520\"></div>\n\n<div data-docs-demo=\"181-master-detail-grid\" data-height=\"520\"></div>\n\n## What you give up\n\n- **Free printing.** SVAR's print API is in the MIT grid; SvGrid's print\n view is in `@svgrid/enterprise`.\n- **The React and Vue versions** of the same grid. SvGrid is Svelte-only.\n- **A smaller bundle.** The facts box at the top of the page has both\n packages measured the same way; the difference is the grouping,\n master/detail, range editing, charts and server-side data (flat paging and infinite scroll free; grouping, tree, pivot and transactions on the server are Enterprise) SvGrid\n carries, and features you never import load as separate chunks.\n- **The SVAR suite around the grid.** Gantt, Calendar, Kanban and File\n Manager share SVAR's core; SvGrid's Kanban and scheduler are views of the\n grid in `@svgrid/enterprise`.\n\n## What to check on the SVAR side\n\n- The **wider SVAR suite** (Gantt, Calendar, Kanban) - if you use several\n SVAR components together, staying on SVAR may be simpler.\n- Any **SVAR-specific column features** you rely on; map each to a SvGrid\n `cell` snippet, `editorType`, or feature before porting.\n- **Filter functions.** SVAR filters with a predicate you write; SvGrid's\n filter takes an operator and a value per column, and `externalFilter`\n hands you the rows when you want to keep a custom predicate.\n\n## Frequently asked questions\n\n### Why move from SVAR Svelte DataGrid to SvGrid?\n\nCapability and architecture, not licensing (both are MIT). SvGrid adds row\ngrouping with aggregation, master-detail, Excel-style cell-range selection,\nintegrated charts, and pivot, and it ships a headless engine plus an MCP server\nalongside the component. Both are Svelte-native, so the core grid\nbehaviour is comparable; SvGrid covers more ground.\n\n### Is the migration a rewrite?\n\nNo. Both are component-first with array-of-object columns, so it is mostly a\nprop / event rename pass (`id` → `field`, edit events → `onCellValueChange`)\nplus re-theming through `--sg-*` tokens.\n\n### Are SvGrid and SVAR both free and MIT?\n\nYes. `@svgrid/grid` and the SVAR DataGrid are both MIT and free for\ncommercial, closed-source use. SVAR keeps the whole grid free and sells PRO\neditions of its Gantt, Calendar and Kanban; on SvGrid, only the optional\n`@svgrid/enterprise` add-on (Excel and PDF export, print, pivot, import,\nsupport) is paid. The dated statement from svar.dev is in the facts box at\nthe top of this page.\n\n### How does SVAR's tree data map to SvGrid?\n\nSVAR takes hierarchical data with the `tree` prop. SvGrid takes either a\nflat array with a parent field (`treeData={{ parentField: 'parentId' }}`)\nor nested rows through `rowExpandingFeature`, and the same grid also does\nmaster/detail, which SVAR's docs do not list. The example below runs the\nflat shape:\n\n## What you end up with\n\nGrouping with aggregation and a totals row, the main capability step up.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} groupBy={['department']} summary groupable sortable filterable />\n```\n\nAnd the tree shape, from the same rows with a parent link, which is what SVAR's `tree` prop becomes:\n\n```svelte {runnable}\n<SvGrid data={rows.map((r, i) => ({ ...r, parentId: i === 0 ? null : rows[0].id }))} {columns} treeData={{ parentField: 'parentId' }} sortable />\n```\n\n## See also\n\n- [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/) - the side-by-side comparison, with a source and date for every claim and the measured benchmark\n- [Grouping and aggregation](./grouping-aggregation.md) - the first demo above\n- [Master/detail](./rows/master-detail.md) - the second demo above\n- [Architecture](./architecture.md) - the engine + render-component split\n- [Cell components](./cells/cell-components.md) - custom cells and editors\n"
|
|
4793
|
+
"markdown": "# Migrating from SVAR Svelte DataGrid\n\nSVAR Svelte DataGrid (`wx-svelte-grid`) is, like SvGrid, an actual\nSvelte-native grid rather than a wrapper, and both are MIT-licensed and\nfree for commercial use. Because both are component-first with\narray-of-object column definitions, a port is mostly a configuration\ntranslation. The reasons people switch are **capability** (SvGrid adds\nrow grouping with aggregation, master-detail, Excel-style cell-range\nselection, integrated charts, and pivot) and **architecture** (SvGrid\nalso exposes a headless engine and an MCP server).\n\n> Estimated effort: **2-4 hours** per grid - a prop and event rename\n> pass, plus re-theming.\n>\n> SVAR's exact prop and event names evolve across releases; check the\n> current SVAR docs and map them onto the SvGrid equivalents below.\n\n<!-- facts:start svar-svelte-datagrid -->\n> **Facts, checked 12 Sep 2026.** `wx-svelte-grid` 2.7.0, MIT, last published 3 Jun 2026, 62,800 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `wx-svelte-grid` 2.7.0 51.5 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). SVAR Svelte DataGrid pricing, as its site states it: The DataGrid is MIT and free for commercial use with no paid tier; svar.dev sells PRO editions of its Gantt, Calendar and Kanban components and offers paid consulting and custom development, with no price list for the grid (https://svar.dev/svelte/, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/).\n<!-- facts:end -->\n\n## Concept map\n\n| SVAR DataGrid (wx-svelte-grid) | sv-grid |\n| ----------------------------------------- | ----------------------------------------- |\n| `<Grid {data} {columns} />` | `<SvGrid data={...} columns={...} />` |\n| `columns: [{ id, header, width, ... }]` | `columns: [{ field, header, width, ... }]` |\n| `sizes={{ rowHeight, columnWidth }}` | `rowHeight` prop, `width` per column |\n| `autoRowHeight` | `autoRowHeight` |\n| Per-column `editor` / `template` | `editorType` + `cell` snippet |\n| `sort: true` on a column, `sortMarks` | `rowSortingFeature`; `initialSorting` |\n| Header filters, the Filter component | `columnFilteringFeature`; Excel-style menu and filter row built in |\n| `tree` prop + `data` with children | `treeData={{ parentField }}` or `rowExpandingFeature` with sub rows |\n| `select` / `multiselect` | `selectionMode=\"row\"` (+ checkbox column) |\n| `split={{ left: n }}` (pinned columns) | `initialColumnPinning` or `pinned: 'left' \\| 'right'` per column |\n| `reorder` (row drag) | `rowDragManaged` |\n| `undo` prop, undo/redo hotkeys | `history` prop; `api.undo()` / `api.redo()` |\n| Context menu component | `contextMenu` prop with items |\n| `init={(api) => ...}` | `onApiReady={(api) => ...}` |\n| `api.exec('sort-rows', { key, order })` | `api.setSort(field, 'asc' \\| 'desc')` |\n| `api.exec('filter-rows', { filter })` | `api.setFilter(field, { operator, value })` |\n| `api.on('...')` event bus | `onXxx` callback props |\n| Export to CSV, print API | `api.exportCsv()` (free); print in `@svgrid/enterprise` |\n| `RestDataProvider` | server-side row model / `externalSort` + `externalFilter` |\n| Theme / skin components (Willow, Material)| `--sg-*` CSS custom properties / Tailwind |\n\n## Before / after (shape, not exact prop names)\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- <script>\n- import { Grid } from 'wx-svelte-grid'\n- const columns = [\n- { id: 'name', header: 'Name', width: 200 },\n- { id: 'amount', header: 'Amount', width: 120, editor: 'text' },\n- ]\n- </script>\n-\n- <Grid {data} {columns} />\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name', width: 200 },\n+ { field: 'amount', header: 'Amount', width: 120, editorType: 'text' },\n+ ]\n+ </script>\n+\n+ <SvGrid data={data} columns={columns} features={features} enableInlineEditing />\n```\n\n## Licensing note\n\nBoth grids are MIT and free for commercial use, so licensing is not the\ndeciding factor. The difference is monetization: SVAR keeps the whole\ngrid free (including CSV export and print) and sells PRO editions of its\nGantt, Calendar and Kanban instead, whereas SvGrid's `@svgrid/grid` core is\nMIT and the optional `@svgrid/enterprise` pack (XLSX/PDF export, print,\npivot, import, support) is the paid piece. CSV, TSV and JSON export and the\nin-grid AI helpers are free on SvGrid too. If all you need is CSV export and\nprint, SVAR gives both free; if you need pivot, Excel or PDF output, or a\nsupport SLA, that is Enterprise on SvGrid.\n\n## What you get with SvGrid\n\n- **Row grouping with aggregation**, **master-detail**, **pinned rows**,\n and left/right column freezing - beyond SVAR's documented surface.\n- A **headless engine** (`createSvGrid` + row models) in addition to the\n component, if you want to compose your own layer.\n- **Excel-style filter menu**, **cell-range selection + TSV copy**, a\n **fill handle**, **integrated charts**, and a documented **imperative API**.\n- **In-grid AI helpers** (natural-language filter, smart fill, summarise),\n free against a model you register, and **@svgrid/mcp** so AI assistants\n answer accurately about your grid and can check the code they write.\n\nThe two features most SVAR teams port for:\n\n<div data-docs-demo=\"07-grouping-aggregation\" data-height=\"520\"></div>\n\n<div data-docs-demo=\"181-master-detail-grid\" data-height=\"520\"></div>\n\n## What you give up\n\n- **Free printing.** SVAR's print API is in the MIT grid; SvGrid's print\n view is in `@svgrid/enterprise`.\n- **The React and Vue versions** of the same grid. SvGrid is Svelte-only.\n- **A smaller bundle.** The facts box at the top of the page has both\n packages measured the same way; the difference is the grouping,\n master/detail, range editing, charts and server-side data (flat paging and infinite scroll free; grouping, tree, pivot and transactions on the server are Enterprise) SvGrid\n carries, and features you never import load as separate chunks.\n- **The SVAR suite around the grid.** Gantt, Calendar, Kanban and File\n Manager share SVAR's core; SvGrid's Kanban and scheduler are views of the\n grid in `@svgrid/enterprise`.\n\n## What to check on the SVAR side\n\n- The **wider SVAR suite** (Gantt, Calendar, Kanban) - if you use several\n SVAR components together, staying on SVAR may be simpler.\n- Any **SVAR-specific column features** you rely on; map each to a SvGrid\n `cell` snippet, `editorType`, or feature before porting.\n- **Filter functions.** SVAR filters with a predicate you write; SvGrid's\n filter takes an operator and a value per column, and `externalFilter`\n hands you the rows when you want to keep a custom predicate.\n\n## Frequently asked questions\n\n### Why move from SVAR Svelte DataGrid to SvGrid?\n\nCapability and architecture, not licensing (both are MIT). SvGrid adds row\ngrouping with aggregation, master-detail, Excel-style cell-range selection,\nintegrated charts, and pivot, and it ships a headless engine plus an MCP server\nalongside the component. Both are Svelte-native, so the core grid\nbehaviour is comparable; SvGrid covers more ground.\n\n### Is the migration a rewrite?\n\nNo. Both are component-first with array-of-object columns, so it is mostly a\nprop / event rename pass (`id` → `field`, edit events → `onCellValueChange`)\nplus re-theming through `--sg-*` tokens.\n\n### Are SvGrid and SVAR both free and MIT?\n\nYes. `@svgrid/grid` and the SVAR DataGrid are both MIT and free for\ncommercial, closed-source use. SVAR keeps the whole grid free and sells PRO\neditions of its Gantt, Calendar and Kanban; on SvGrid, only the optional\n`@svgrid/enterprise` add-on (Excel and PDF export, print, pivot, import,\nsupport) is paid. The dated statement from svar.dev is in the facts box at\nthe top of this page.\n\n### How does SVAR's tree data map to SvGrid?\n\nSVAR takes hierarchical data with the `tree` prop. SvGrid takes either a\nflat array with a parent field (`treeData={{ parentField: 'parentId' }}`)\nor nested rows through `rowExpandingFeature`, and the same grid also does\nmaster/detail, which SVAR's docs do not list. The example below runs the\nflat shape:\n\n## What you end up with\n\nGrouping with aggregation and a totals row, the main capability step up.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} groupBy={['department']} summary groupable sortable filterable />\n```\n\nAnd the tree shape, from the same rows with a parent link, which is what SVAR's `tree` prop becomes:\n\n```svelte {runnable}\n<SvGrid data={rows.map((r, i) => ({ ...r, parentId: i === 0 ? null : rows[0].id }))} {columns} treeData={{ parentField: 'parentId' }} sortable />\n```\n\n## See also\n\n- [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/) - the side-by-side comparison, with a source and date for every claim and the measured benchmark\n- [Grouping and aggregation](./grouping-aggregation.md) - the first demo above\n- [Master/detail](./rows/master-detail.md) - the second demo above\n- [Architecture](./architecture.md) - the engine + render-component split\n- [Cell components](./cells/cell-components.md) - custom cells and editors\n"
|
|
4794
4794
|
},
|
|
4795
4795
|
{
|
|
4796
4796
|
"slug": "help/migrating-from-svelte-headless-table",
|
|
4797
4797
|
"path": "docs/help/migrating-from-svelte-headless-table.md",
|
|
4798
4798
|
"title": "Migrating from svelte-headless-table",
|
|
4799
4799
|
"section": "Help",
|
|
4800
|
-
"markdown": "# Migrating from svelte-headless-table\n\nsvelte-headless-table popularised the headless-table pattern in the\nSvelte ecosystem. It is built on Svelte 4 stores and plugins\n(`addSortBy`, `addColumnFilters`, `addPagination`, ...), and it leaves\nthe markup to you. SvGrid keeps the same headless idea but runs on\nSvelte 5 runes and ships a render component, so the port mostly\n*removes* the table you used to hand-author.\n\n> Estimated effort: **1-3 hours** per grid. Most of the time is deleting\n> the `<table>` markup and `Subscribe` blocks you no longer need.\n\n<!-- facts:start svelte-headless-table pkg:@humanspeak/svelte-headless-table -->\n> **Facts, checked 12 Sep 2026.** `svelte-headless-table` 0.18.3, MIT, last published 28 Oct 2024, 90,100 npm downloads in the 30 days to 10 Sep 2026. `@humanspeak/svelte-headless-table` 6.2.0, MIT, last published 27 Aug 2026, 8,640 npm downloads in the same window. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `svelte-headless-table` 0.18.3 5.7 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). svelte-headless-table pricing, as its site states it: svelte-headless-table is MIT and free; no paid licence or support is offered, and the author states there are no plans for a Svelte 5 port (https://github.com/bryanmylee/svelte-headless-table, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/).\n<!-- facts:end -->\n\n## Know your options first\n\nThe original package's last release and its Svelte 4 peer range are in the\nfacts box above, and its README states there are no current plans for a\nSvelte 5 port, so a Svelte 5 upgrade forces a decision. There are three\nhonest answers and you should know all of them:\n\n1. **`@humanspeak/svelte-headless-table`** - a maintained fork on Svelte 5 with\n the same API; its version, publish date and downloads are in the facts box\n too. Changing one package name is the cheapest path by a wide margin. If\n your table works and you only need Svelte 5, do that.\n2. **TanStack Table v9** - its Svelte adapter declares a Svelte 5 peer range.\n Still headless-only, so you keep writing and maintaining the markup.\n3. **SvGrid** - this page. A different trade: you delete the markup and take a\n renderer instead.\n\nPick SvGrid when the markup is the part you are tired of. Note that the blocker\nis not the syntax and not really the install either: `svelte-headless-table@0.18.3`\ndeclares `svelte@^4`, which npm 11 overrides with a warning (older npm needed\n`--legacy-peer-deps`), and the untouched component then type-checks clean in\nlegacy mode. Slots and `let:` still work in Svelte 5 - they are deprecated in\nfavour of snippets, not removed - so the `Subscribe` blocks below keep\nrendering. The trouble starts when that component moves to runes: the library\ntakes a store, your data is a rune, and the bridge between them is yours to\nwrite and maintain. We ran the whole upgrade and captured every line of it in\n[Upgrading a Svelte 4 table to Svelte 5](./svelte-5-upgrade-data-tables.md).\n\n## Run the codemod\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```bash\nnpx @svgrid/migrate # preview the result\nnpx @svgrid/migrate src --write # apply it\n```\n\nIt translates column definitions and plugin config, deletes the\n`Subscribe`/`Render` scaffolding, and reports anything it cannot map rather than\ndropping it silently. It previews by default. See\n[`@svgrid/migrate`](https://www.npmjs.com/package/@svgrid/migrate) for the full\nmapping and its limits.\n\n## Vocabulary cheat sheet\n\n| svelte-headless-table | sv-grid |\n| ----------------------------------------- | ----------------------------------------- |\n| `createTable(data, plugins)` | `createSvGrid({...})` or `<SvGrid>` |\n| `table.createColumns((t) => [...])` | `columns: ColumnDef[]` |\n| `t.column({ accessor: 'x', header })` | `{ field: 'x', header }` |\n| `t.column({ accessor: (r) => ... })` | `{ id, fieldFn: (r) => ... }` |\n| `t.group({ header, columns })` | `{ header, columns: [...] }` (column group) |\n| `addSortBy()` | `rowSortingFeature` |\n| `addColumnFilters()` / `addTableFilter()` | `columnFilteringFeature` |\n| `addPagination()` | Built in; toggle `showPagination` |\n| `addExpandedRows()` / `addSubRows()` | `rowExpandingFeature` |\n| `addGroupBy()` | `columnGroupingFeature` + `api.setGroupBy()` |\n| `addSelectedRows()` | `rowSelectionFeature` |\n| `addDataExport()` | `@svgrid/enterprise` export pack |\n| `createViewModel(columns)` + `Subscribe` | `<SvGrid>` (no view model to wire) |\n| `pluginStates.sort.sortKeys` | `api.setSort(id, dir)` / `onSortingChange` |\n\n### The shortcut form\n\nThat table maps plugins onto the headless *features*, which is what you want if\nyou keep driving the engine yourself. If you are moving to the `<SvGrid>`\ncomponent, every capability also has a boolean prop, and that is what the\ncodemod emits:\n\n| Plugin | `<SvGrid>` prop |\n| --- | --- |\n| `addSortBy()` | `sortable` |\n| `addTableFilter()` | `filterable showGlobalFilter` |\n| `addColumnFilters()` | `filterable showColumnFilters` |\n| `addPagination({ initialPageSize: 25 })` | `pageable pageSize={25}` |\n| `addSelectedRows()` | `showRowSelection` |\n| `addGroupBy()` | `groupable` |\n| `addSubRows()` | `treeData` |\n| `addColumnOrder()` | `enableColumnReorder` |\n| `addResizedColumns()` | nothing - resizing is built in |\n| `addHiddenColumns()` | `visible: false` on the column |\n| `addExpandedRows()` | `treeData`, or `isDetailRow` + `renderDetailRow` |\n| `addGridLayout()` | nothing - SvGrid owns its layout |\n\nEvery capability is off by default and turned on by its prop; there is no\nplugin registration step.\n\n## Before / after\n\n```diff\n- <script>\n- import { createTable } from 'svelte-headless-table'\n- import { addSortBy, addColumnFilters, addPagination } from 'svelte-headless-table/plugins'\n- import { readable } from 'svelte/store'\n-\n- const table = createTable(readable(data), {\n- sort: addSortBy(), filter: addColumnFilters(), page: addPagination(),\n- })\n- const columns = table.createColumns((t) => [\n- t.column({ accessor: 'name', header: 'Name' }),\n- t.column({ accessor: 'amount', header: 'Amount' }),\n- ])\n- const { headerRows, rows, tableAttrs, tableBodyAttrs } = table.createViewModel(columns)\n- </script>\n-\n- <table {...$tableAttrs}>\n- <thead> ...Subscribe over headerRows... </thead>\n- <tbody {...$tableBodyAttrs}> ...Subscribe over rows... </tbody>\n- </table>\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} showPagination />\n```\n\nType the column array against your row type. `GridColumns<(typeof data)[number]>`\nis the shortest form; a bare `GridColumns` widens the row to\n`Record<string, unknown>` and stops checking `field` against your real keys.\n\n## What you get for free\n\n- **The renderer.** No `createViewModel`, no `Subscribe`, no hand-built\n `<table>`. SvGrid ships virtualization, sticky headers, column\n resize, keyboard nav, and ARIA.\n- **Excel-style filter menu** and **cell-range selection + TSV copy**,\n which are BYO in svelte-headless-table.\n- **Inline editing** with typed editors and validation hooks.\n- **In-grid AI helpers** - natural-language filter, smart fill, summarise -\n free in `@svgrid/grid` against a model you register.\n- **Enterprise features** - Excel and PDF export, print, import and pivot -\n in one paid add-on; CSV, TSV and JSON export are free.\n\nIf you would rather keep driving your own `<table>`, the headless demo\nbelow does exactly that on `createSvGrid`, plugins replaced by features:\n\n<div data-docs-demo=\"186-headless-table\" data-height=\"520\"></div>\n\n## What changes\n\n- **Stores → runes.** Reactive data is `$state` / a plain array, not a\n Svelte store you pass to `createTable`. If your rows came from a `derived`\n store, read it with `$` at the call site or move it to `$derived`.\n- **Plugins → features.** Register `rowSortingFeature` etc. in\n `tableFeatures({...})` instead of `addSortBy()` in the plugin bag.\n- **View model → component.** You stop owning the markup; style through\n `--sg-*` tokens (and Tailwind) instead of `tableAttrs`.\n\n## What does not come across\n\n- **Custom `cell` renderers.** `createRender(MyComponent, props)` has no direct\n equivalent; SvGrid uses a `cell` snippet. The codemod preserves yours as a\n `// TODO port:` comment.\n- **Your own plugins.** There is no plugin system to port them into.\n- **`tableAttrs` / `attrs()` spreading.** The component owns its attributes.\n\n## When not to migrate\n\n- You need control of the exact DOM. Use the fork, or SvGrid's\n [headless core](../why-headless.md) at `@svgrid/grid/core`.\n- Your table is a handful of rows with no interaction. A plain `{#each}` is\n less code than either library.\n- You depend on custom plugins. That is a rewrite, not a migration.\n- You only need Svelte 5 support. Use the fork.\n\n## Frequently asked questions\n\n### How hard is it to move from svelte-headless-table to SvGrid?\n\nUsually 1-3 hours per grid, and `npx @svgrid/migrate` does the mechanical part.\nThe plugin-to-feature mapping is almost one-to-one; most of the work is deleting\nthe `createViewModel` + `Subscribe` + `<table>` markup, because SvGrid renders\nthat for you.\n\n### Does SvGrid use Svelte 5 runes instead of stores?\n\nYes. svelte-headless-table is built on Svelte 4 stores; SvGrid is Svelte-5\nnative (`$state` / `$derived` / `$effect`) with snippets for custom cells.\n\n### Is SvGrid still headless like svelte-headless-table?\n\nYes - `createSvGrid` plus the row-model factories is a headless engine you can\ndrive with your own markup, importable on its own from `@svgrid/grid/core`. The\ndifference is that SvGrid *also* ships a batteries-included `<SvGrid>` component\nso you usually do not have to.\n\n### Is svelte-headless-table still maintained?\n\nThe original's last publish date and Svelte 4 peer range are in the facts box\nat the top of the page, read from npm on the date shown, and its README says\nthere are no current plans for a Svelte 5 port. A community fork,\n`@humanspeak/svelte-headless-table`, is maintained and runs on Svelte 5 with\nthe same API; the facts box has its release line too. The fork is the\nlowest-effort option if you are happy with the library and only need Svelte 5.\n\n## What you end up with\n\nSorting, filtering and selection, on a library that still ships for Svelte 5.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable selectable />\n```\n\n## See also\n\n- [Upgrading a Svelte 4 table to Svelte 5](./svelte-5-upgrade-data-tables.md) - the whole upgrade run and captured, step by step\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/) - the side-by-side comparison, with a source and date for every claim\n- [Headless: build a table](./headless/build-a-table.md) - the demo above, step by step\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - sibling headless guide\n- [Why headless?](../why-headless.md) - the design rationale\n- [Architecture](./architecture.md) - the engine + render-component split\n"
|
|
4800
|
+
"markdown": "# Migrating from svelte-headless-table\n\nsvelte-headless-table popularised the headless-table pattern in the\nSvelte ecosystem. It is built on Svelte 4 stores and plugins\n(`addSortBy`, `addColumnFilters`, `addPagination`, ...), and it leaves\nthe markup to you. SvGrid keeps the same headless idea but runs on\nSvelte 5 runes and ships a render component, so the port mostly\n*removes* the table you used to hand-author.\n\n> Estimated effort: **1-3 hours** per grid. Most of the time is deleting\n> the `<table>` markup and `Subscribe` blocks you no longer need.\n\n<!-- facts:start svelte-headless-table pkg:@humanspeak/svelte-headless-table -->\n> **Facts, checked 12 Sep 2026.** `svelte-headless-table` 0.18.3, MIT, last published 28 Oct 2024, 90,100 npm downloads in the 30 days to 10 Sep 2026. `@humanspeak/svelte-headless-table` 6.2.0, MIT, last published 27 Aug 2026, 8,640 npm downloads in the same window. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `svelte-headless-table` 0.18.3 5.7 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). svelte-headless-table pricing, as its site states it: svelte-headless-table is MIT and free; no paid licence or support is offered, and the author states there are no plans for a Svelte 5 port (https://github.com/bryanmylee/svelte-headless-table, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/).\n<!-- facts:end -->\n\n## Know your options first\n\nThe original package's last release and its Svelte 4 peer range are in the\nfacts box above, and its README states there are no current plans for a\nSvelte 5 port, so a Svelte 5 upgrade forces a decision. There are three\nhonest answers and you should know all of them:\n\n1. **`@humanspeak/svelte-headless-table`** - a maintained fork on Svelte 5 with\n the same API; its version, publish date and downloads are in the facts box\n too. Changing one package name is the cheapest path by a wide margin. If\n your table works and you only need Svelte 5, do that.\n2. **TanStack Table v9** - its Svelte adapter declares a Svelte 5 peer range.\n Still headless-only, so you keep writing and maintaining the markup.\n3. **SvGrid** - this page. A different trade: you delete the markup and take a\n renderer instead.\n\nPick SvGrid when the markup is the part you are tired of. Note that the blocker\nis not the syntax and not really the install either: `svelte-headless-table@0.18.3`\ndeclares `svelte@^4`, which npm 11 overrides with a warning (older npm needed\n`--legacy-peer-deps`), and the untouched component then type-checks clean in\nlegacy mode. Slots and `let:` still work in Svelte 5 - they are deprecated in\nfavour of snippets, not removed - so the `Subscribe` blocks below keep\nrendering. The trouble starts when that component moves to runes: the library\ntakes a store, your data is a rune, and the bridge between them is yours to\nwrite and maintain. We ran the whole upgrade and captured every line of it in\n[Upgrading a Svelte 4 table to Svelte 5](./svelte-5-upgrade-data-tables.md).\n\n## Run the codemod\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```bash\nnpx @svgrid/migrate # preview the result\nnpx @svgrid/migrate src --write # apply it\n```\n\nIt translates column definitions and plugin config, deletes the\n`Subscribe`/`Render` scaffolding, and reports anything it cannot map rather than\ndropping it silently. It previews by default. See\n[`@svgrid/migrate`](https://www.npmjs.com/package/@svgrid/migrate) for the full\nmapping and its limits.\n\n## Vocabulary cheat sheet\n\n| svelte-headless-table | sv-grid |\n| ----------------------------------------- | ----------------------------------------- |\n| `createTable(data, plugins)` | `createSvGrid({...})` or `<SvGrid>` |\n| `table.createColumns((t) => [...])` | `columns: ColumnDef[]` |\n| `t.column({ accessor: 'x', header })` | `{ field: 'x', header }` |\n| `t.column({ accessor: (r) => ... })` | `{ id, fieldFn: (r) => ... }` |\n| `t.group({ header, columns })` | `{ header, columns: [...] }` (column group) |\n| `addSortBy()` | `rowSortingFeature` |\n| `addColumnFilters()` / `addTableFilter()` | `columnFilteringFeature` |\n| `addPagination()` | Built in; toggle `showPagination` |\n| `addExpandedRows()` / `addSubRows()` | `rowExpandingFeature` |\n| `addGroupBy()` | `columnGroupingFeature` + `api.setGroupBy()` |\n| `addSelectedRows()` | `rowSelectionFeature` |\n| `addDataExport()` | `@svgrid/enterprise` export pack |\n| `createViewModel(columns)` + `Subscribe` | `<SvGrid>` (no view model to wire) |\n| `pluginStates.sort.sortKeys` | `api.setSort(id, dir)` / `onSortingChange` |\n\n### The shortcut form\n\nThat table maps plugins onto the headless *features*, which is what you want if\nyou keep driving the engine yourself. If you are moving to the `<SvGrid>`\ncomponent, every capability also has a boolean prop, and that is what the\ncodemod emits:\n\n| Plugin | `<SvGrid>` prop |\n| --- | --- |\n| `addSortBy()` | `sortable` |\n| `addTableFilter()` | `filterable showGlobalFilter` |\n| `addColumnFilters()` | `filterable showColumnFilters` |\n| `addPagination({ initialPageSize: 25 })` | `pageable pageSize={25}` |\n| `addSelectedRows()` | `showRowSelection` |\n| `addGroupBy()` | `groupable` |\n| `addSubRows()` | `treeData` |\n| `addColumnOrder()` | `enableColumnReorder` |\n| `addResizedColumns()` | nothing - resizing is built in |\n| `addHiddenColumns()` | `visible: false` on the column |\n| `addExpandedRows()` | `treeData`, or `isDetailRow` + `renderDetailRow` |\n| `addGridLayout()` | nothing - SvGrid owns its layout |\n\nEvery capability is off by default and turned on by its prop; there is no\nplugin registration step.\n\n## Before / after\n\n```diff\n- <script>\n- import { createTable } from 'svelte-headless-table'\n- import { addSortBy, addColumnFilters, addPagination } from 'svelte-headless-table/plugins'\n- import { readable } from 'svelte/store'\n-\n- const table = createTable(readable(data), {\n- sort: addSortBy(), filter: addColumnFilters(), page: addPagination(),\n- })\n- const columns = table.createColumns((t) => [\n- t.column({ accessor: 'name', header: 'Name' }),\n- t.column({ accessor: 'amount', header: 'Amount' }),\n- ])\n- const { headerRows, rows, tableAttrs, tableBodyAttrs } = table.createViewModel(columns)\n- </script>\n-\n- <table {...$tableAttrs}>\n- <thead> ...Subscribe over headerRows... </thead>\n- <tbody {...$tableBodyAttrs}> ...Subscribe over rows... </tbody>\n- </table>\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} showPagination />\n```\n\nType the column array against your row type. `GridColumns<(typeof data)[number]>`\nis the shortest form; a bare `GridColumns` widens the row to\n`Record<string, unknown>` and stops checking `field` against your real keys.\n\n## What you get for free\n\n- **The renderer.** No `createViewModel`, no `Subscribe`, no hand-built\n `<table>`. SvGrid ships virtualization, sticky headers, column\n resize, keyboard nav, and ARIA.\n- **Excel-style filter menu** and **cell-range selection + TSV copy**,\n which are BYO in svelte-headless-table.\n- **Inline editing** with typed editors and validation hooks.\n- **In-grid AI helpers** - natural-language filter, smart fill, summarise -\n free in `@svgrid/grid` against a model you register.\n- **Enterprise features** - Excel and PDF export, print, import and pivot -\n in one paid add-on; CSV, TSV and JSON export are free.\n\nIf you would rather keep driving your own `<table>`, the headless demo\nbelow does exactly that on `createSvGrid`, plugins replaced by features:\n\n<div data-docs-demo=\"186-headless-table\" data-height=\"520\"></div>\n\n## What changes\n\n- **Stores → runes.** Reactive data is `$state` / a plain array, not a\n Svelte store you pass to `createTable`. If your rows came from a `derived`\n store, read it with `$` at the call site or move it to `$derived`.\n- **Plugins → features.** Register `rowSortingFeature` etc. in\n `tableFeatures({...})` instead of `addSortBy()` in the plugin bag.\n- **View model → component.** You stop owning the markup; style through\n `--sg-*` tokens (and Tailwind) instead of `tableAttrs`.\n\n## What does not come across\n\n- **Custom `cell` renderers.** `createRender(MyComponent, props)` has no direct\n equivalent; SvGrid uses a `cell` snippet. The codemod preserves yours as a\n `// TODO port:` comment.\n- **Your own plugins.** There is no plugin system to port them into.\n- **`tableAttrs` / `attrs()` spreading.** The component owns its attributes.\n\n## When not to migrate\n\n- You need control of the exact DOM. Use the fork, or SvGrid's\n [headless core](../why-headless.md) at `@svgrid/grid/core`.\n- Your table is a handful of rows with no interaction. A plain `{#each}` is\n less code than either library.\n- You depend on custom plugins. That is a rewrite, not a migration.\n- You only need Svelte 5 support. Use the fork.\n\n## Frequently asked questions\n\n### How hard is it to move from svelte-headless-table to SvGrid?\n\nUsually 1-3 hours per grid, and `npx @svgrid/migrate` does the mechanical part.\nThe plugin-to-feature mapping is almost one-to-one; most of the work is deleting\nthe `createViewModel` + `Subscribe` + `<table>` markup, because SvGrid renders\nthat for you.\n\n### Does SvGrid use Svelte 5 runes instead of stores?\n\nYes. svelte-headless-table is built on Svelte 4 stores; SvGrid is Svelte-5\nnative (`$state` / `$derived` / `$effect`) with snippets for custom cells.\n\n### Is SvGrid still headless like svelte-headless-table?\n\nYes - `createSvGrid` plus the row-model factories is a headless engine you can\ndrive with your own markup, importable on its own from `@svgrid/grid/core`. The\ndifference is that SvGrid *also* ships a batteries-included `<SvGrid>` component\nso you usually do not have to.\n\n### Is svelte-headless-table still maintained?\n\nThe original's last publish date and Svelte 4 peer range are in the facts box\nat the top of the page, read from npm on the date shown, and its README says\nthere are no current plans for a Svelte 5 port. A community fork,\n`@humanspeak/svelte-headless-table`, is maintained and runs on Svelte 5 with\nthe same API; the facts box has its release line too. The fork is the\nlowest-effort option if you are happy with the library and only need Svelte 5.\n\n## What you end up with\n\nSorting, filtering and selection, on a library that still ships for Svelte 5.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable selectable />\n```\n\n## See also\n\n- [Upgrading a Svelte 4 table to Svelte 5](./svelte-5-upgrade-data-tables.md) - the whole upgrade run and captured, step by step\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/) - the side-by-side comparison, with a source and date for every claim\n- [Headless: build a table](./headless/build-a-table.md) - the demo above, step by step\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - sibling headless guide\n- [Why headless?](../why-headless.md) - the design rationale\n- [Architecture](./architecture.md) - the engine + render-component split\n"
|
|
4801
4801
|
},
|
|
4802
4802
|
{
|
|
4803
4803
|
"slug": "help/migrating-from-syncfusion",
|
|
4804
4804
|
"path": "docs/help/migrating-from-syncfusion.md",
|
|
4805
4805
|
"title": "Migrating from Syncfusion Grid",
|
|
4806
4806
|
"section": "Help",
|
|
4807
|
-
"markdown": "# Migrating from Syncfusion Grid\n\nSyncfusion Grid is a comprehensive commercial grid across JavaScript,\nReact, Vue, Angular, and Blazor, with a free community license for\nqualifying small teams. Moving to SvGrid trades the multi-framework suite\nfor a Svelte-5-native grid with an unconditional MIT core.\n\n> Estimated effort: **3-6 hours** per grid.\n>\n> Syncfusion's option names vary across its framework flavours; map your\n> version's columns and events onto the SvGrid equivalents below.\n\n<!-- facts:start syncfusion-grid -->\n> **Facts, checked 12 Sep 2026.** `@syncfusion/ej2-grids` 34.2.7, Commercial (see licence file), last published 8 Sep 2026, 711,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Syncfusion Grid pricing, as its site states it: syncfusion.com lists the Grid SDK at $959 per developer per year and the UI Component Suite at $1,199 per developer per year, minimum five developers; a free Community License applies to companies and individuals with under $1M annual revenue, up to five developers and no more than ten employees (https://www.syncfusion.com/sales/products, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4807
|
+
"markdown": "# Migrating from Syncfusion Grid\n\nSyncfusion Grid is a comprehensive commercial grid across JavaScript,\nReact, Vue, Angular, and Blazor, with a free community license for\nqualifying small teams. Moving to SvGrid trades the multi-framework suite\nfor a Svelte-5-native grid with an unconditional MIT core.\n\n> Estimated effort: **3-6 hours** per grid.\n>\n> Syncfusion's option names vary across its framework flavours; map your\n> version's columns and events onto the SvGrid equivalents below.\n\n<!-- facts:start syncfusion-grid -->\n> **Facts, checked 12 Sep 2026.** `@syncfusion/ej2-grids` 34.2.7, Commercial (see licence file), last published 8 Sep 2026, 711,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Syncfusion Grid pricing, as its site states it: syncfusion.com lists the Grid SDK at $959 per developer per year and the UI Component Suite at $1,199 per developer per year, minimum five developers; a free Community License applies to companies and individuals with under $1M annual revenue, up to five developers and no more than ten employees (https://www.syncfusion.com/sales/products, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs Syncfusion Grid](https://svgrid.com/compare/syncfusion-grid/).\n<!-- facts:end -->\n\n## Concept map\n\n| Syncfusion Grid | sv-grid |\n| ---------------------------------------- | ----------------------------------------- |\n| `columns: [{ field, headerText }]` | `columns: [{ field, header }]` |\n| `template` / cell template | `cell: (c) => renderSnippet(...)` |\n| `editSettings` + `editType` | `enableInlineEditing` + `editorType` |\n| `allowSorting` / `allowFiltering` | `rowSortingFeature` / `columnFilteringFeature` |\n| `allowGrouping` + `aggregates` | `columnGroupingFeature` + aggregates |\n| `detailTemplate` | `rowExpandingFeature` / master-detail rows |\n| `dataSource` (local / `DataManager`) | `data` array or `externalSort/Filter` |\n| `allowPaging` + `pageSettings` | `showPagination` |\n| `toolbar` export | `@svgrid/enterprise` export pack |\n\n## Shape of the change\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- <ejs-grid [dataSource]=\"rows\" [allowSorting]=\"true\" [allowFiltering]=\"true\"\n- [allowPaging]=\"true\" [editSettings]=\"{ allowEditing: true }\">\n- <e-columns>\n- <e-column field=\"name\" headerText=\"Name\"></e-column>\n- <e-column field=\"amount\" headerText=\"Amount\" format=\"C2\"></e-column>\n- </e-columns>\n- </ejs-grid>\n\n+ <SvGrid\n+ data={rows}\n+ columns={[\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]}\n+ features={tableFeatures({ rowSortingFeature, columnFilteringFeature })}\n+ showPagination enableInlineEditing />\n```\n\n## Why teams switch\n\n- **Svelte 5 native** instead of a multi-framework commercial suite.\n- **Unconditional MIT core** - no revenue / headcount threshold like the\n Syncfusion community license.\n- **Optional Enterprise pack** for export / import / pivot / AI.\n\n## What to weigh\n\n- Syncfusion ships **one of the largest feature sets and suites**\n available, plus Blazor support. If you need that breadth or Blazor,\n weigh it against the Svelte-native fit.\n\n## Frequently asked questions\n\n### Is SvGrid free, unlike the Syncfusion commercial license?\n\n`@svgrid/grid` is MIT - free for everyone, with no revenue or team-size\nconditions. Syncfusion's community license is free only for qualifying small\nteams; otherwise it is commercial.\n\n### How do Syncfusion columns map to SvGrid?\n\n`field` stays `field`, `headerText` becomes `header`, and `template` becomes a\n`renderSnippet` cell. Sorting / filtering / grouping move to registered\nfeatures.\n\n### Does SvGrid support Blazor?\n\nNo - SvGrid is Svelte 5 only. If you need Blazor, that is a genuine reason to\nstay on Syncfusion. For a Svelte stack, SvGrid is the native fit.\n\n## What you end up with\n\nSort, filter, group and inline edit - the four things a Syncfusion grid is usually doing.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} groupBy={['department']} groupable sortable filterable editable />\n```\n\n## See also\n\n- [SvGrid vs Syncfusion Grid](https://svgrid.com/compare/syncfusion-grid/) - the side-by-side comparison\n- [Data export and printing - Enterprise](./export.md) - the Enterprise export pack\n- [Getting started](../getting-started.md) - a working grid in ~15 lines\n"
|
|
4808
4808
|
},
|
|
4809
4809
|
{
|
|
4810
4810
|
"slug": "help/migrating-from-tabulator",
|
|
4811
4811
|
"path": "docs/help/migrating-from-tabulator.md",
|
|
4812
4812
|
"title": "Migrating from Tabulator",
|
|
4813
4813
|
"section": "Help",
|
|
4814
|
-
"markdown": "# Migrating from Tabulator\n\nTabulator is a feature-rich vanilla-JS table you instantiate against a\nDOM element and drive imperatively (`table.setData(...)`,\n`table.on('cellEdited', ...)`). SvGrid covers a similar feature surface\nbut as a Svelte 5 component: data is a reactive `$state` array, custom\ncells are snippets, and there is no manual mount / teardown.\n\n> Estimated effort: **2-4 hours** per grid - column translation plus\n> swapping imperative `setData` for reactive state.\n\n<!-- facts:start tabulator -->\n> **Facts, checked 12 Sep 2026.** `tabulator-tables` 6.5.2, MIT, last published 23 Jun 2026, 672,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `tabulator-tables` 6.5.2 106.9 KB JS + 3.8 KB CSS (measured 12 Sep 2026). Tabulator pricing, as its site states it: Tabulator is MIT and free; no licence or support plan is sold (https://github.com/olifolkerd/tabulator, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4814
|
+
"markdown": "# Migrating from Tabulator\n\nTabulator is a feature-rich vanilla-JS table you instantiate against a\nDOM element and drive imperatively (`table.setData(...)`,\n`table.on('cellEdited', ...)`). SvGrid covers a similar feature surface\nbut as a Svelte 5 component: data is a reactive `$state` array, custom\ncells are snippets, and there is no manual mount / teardown.\n\n> Estimated effort: **2-4 hours** per grid - column translation plus\n> swapping imperative `setData` for reactive state.\n\n<!-- facts:start tabulator -->\n> **Facts, checked 12 Sep 2026.** `tabulator-tables` 6.5.2, MIT, last published 23 Jun 2026, 672,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `tabulator-tables` 6.5.2 106.9 KB JS + 3.8 KB CSS (measured 12 Sep 2026). Tabulator pricing, as its site states it: Tabulator is MIT and free; no licence or support plan is sold (https://github.com/olifolkerd/tabulator, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs Tabulator](https://svgrid.com/compare/tabulator/).\n<!-- facts:end -->\n\n## Vocabulary cheat sheet\n\n| Tabulator | sv-grid |\n| -------------------------------------- | ----------------------------------------- |\n| `new Tabulator(el, { data, columns })` | `<SvGrid data={...} columns={...} />` |\n| `{ title: 'Name', field: 'name' }` | `{ header: 'Name', field: 'name' }` |\n| `formatter: fn` / `formatter: 'money'` | `cell: (c) => renderSnippet(...)` or `format` |\n| `editor: 'input' / 'number' / ...` | `editorType: 'text' / 'number' / ...` |\n| `headerFilter: true` | `columnFilteringFeature` |\n| `dataTree: true` | `rowExpandingFeature` + tree row shape |\n| `table.setData(rows)` | reassign the `$state` data array |\n| `table.on('cellEdited', ...)` | `onCellValueChange` |\n| `table.setSort(field, dir)` | `api.setSort(field, dir)` |\n| `layout: 'fitColumns'` | `fitColumns` prop |\n\n## Before / after\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import { TabulatorFull as Tabulator } from 'tabulator-tables'\n-\n- const table = new Tabulator('#grid', {\n- data: rows,\n- layout: 'fitColumns',\n- columns: [\n- { title: 'Name', field: 'name' },\n- { title: 'Amount', field: 'amount', formatter: 'money', editor: 'number' },\n- ],\n- })\n- table.on('cellEdited', (cell) => save(cell.getData()))\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' }, editorType: 'number' },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} fitColumns enableInlineEditing\n+ onCellValueChange={(e) => save(e)} />\n```\n\n## What changes\n\n- **Imperative → reactive.** No `setData()` - reassign the `$state`\n array and the grid updates.\n- **String formatters → snippets.** Custom cells are Svelte snippets /\n components, not HTML-string formatters.\n- **Mount / teardown disappears.** No `new Tabulator(el)` and no manual\n destroy on unmount.\n\n## Frequently asked questions\n\n### Is migrating from Tabulator to SvGrid hard?\n\nIt is a configuration translation plus one mindset shift: you stop calling\n`setData()` and instead let a reactive `$state` array drive the grid. Budget\n2-4 hours per grid.\n\n### Is SvGrid free like Tabulator?\n\nYes. `@svgrid/grid` is MIT-licensed like Tabulator. The optional\n`@svgrid/enterprise` pack (export, import, pivot, AI) is the only paid piece.\n\n### Can I keep Tabulator's custom formatters?\n\nYou re-create them as Svelte snippets via `renderSnippet`. Any Svelte\ncomponent or markup works, not just an HTML string.\n\n## What you end up with\n\nSort, filter and edit, with pagination underneath.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable editable pageable pageSize={3} />\n```\n\n## See also\n\n- [SvGrid vs Tabulator](https://svgrid.com/compare/tabulator/) - the side-by-side comparison\n- [Cell components](./cells/cell-components.md) - snippet-based custom cells\n- [Architecture](./architecture.md) - engine + render-component split\n"
|
|
4815
4815
|
},
|
|
4816
4816
|
{
|
|
4817
4817
|
"slug": "help/migrating-from-tanstack-table",
|
|
4818
4818
|
"path": "docs/help/migrating-from-tanstack-table.md",
|
|
4819
4819
|
"title": "Migrating from TanStack Table",
|
|
4820
4820
|
"section": "Help",
|
|
4821
|
-
"markdown": "# Migrating from TanStack Table\n\nTanStack Table (formerly React Table) is the closest conceptual\nsibling to sv-grid - both are \"headless data grid\" libraries with\nexplicit row-model pipelines, and the v9 Svelte adapter,\n`@tanstack/svelte-table`, targets Svelte 5 with the same runes-first\nshape. If you already think in `createTable()` + a features object,\nthis is a half-day port; the vocabulary below covers the v8 names too.\n\n> Estimated effort: **30 min** per grid for read-only views, **2-4\n> hours** for editing-heavy grids.\n\n<!-- facts:start tanstack-table -->\n> **Facts, checked 12 Sep 2026.** `@tanstack/svelte-table` 9.2.4, MIT, last published 28 Aug 2026, 231,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@tanstack/svelte-table` 9.2.4 36.3 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). TanStack Table pricing, as its site states it: TanStack Table is MIT and free; tanstack.com is sponsor-supported and offers Enterprise Support as private consulting and expert support, with no licence sold for the table (https://tanstack.com/table/latest, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/).\n<!-- facts:end -->\n\n> **On v9?** SvGrid exports the same feature vocabulary, so most of this\n> page is automated. Run `npx @svgrid/migrate src` to preview the port, and\n> see [Migrating from the shadcn-svelte data table](./migrating-from-shadcn-data-table.md)\n> if that is where your table came from.\n\n## Vocabulary cheat sheet\n\n| TanStack Table | sv-grid |\n| ------------------------------- | ---------------------------------------- |\n| `useReactTable({...})` | `createSvGrid({...})` or `<SvGrid>` |\n| `getCoreRowModel()` | `createCoreRowModel()` |\n| `getSortedRowModel()` | Auto-registered by `rowSortingFeature` |\n| `getFilteredRowModel()` | Auto-registered by `columnFilteringFeature` |\n| `getPaginationRowModel()` | Built in; toggle with `showPagination` |\n| `getGroupedRowModel()` | `columnGroupingFeature` + `api.setGroupBy()` |\n| `getExpandedRowModel()` | `rowExpandingFeature` |\n| `flexRender(col.cell, ctx)` | `renderSnippet(MyCell, props)` OR string field |\n| `columnHelper.accessor('field')` | `{ field: 'field' }` directly |\n| `table.getRowModel().rows` | `api.getDisplayedRows()` |\n| `table.setColumnFilters(...)` | `api.setFilter(id, {...})` per column |\n| `meta` (column / table) | n/a - use column `cellClass` / `cell` instead |\n\n## Imports\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import {\n- useReactTable, getCoreRowModel, getSortedRowModel, getFilteredRowModel,\n- flexRender, createColumnHelper,\n- } from '@tanstack/react-table'\n\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ renderSnippet,\n+ } from '@svgrid/grid'\n```\n\n## Column definitions\n\n```diff\n- const columnHelper = createColumnHelper<Order>()\n- const columns = [\n- columnHelper.accessor('orderId', { header: 'Order ID' }),\n- columnHelper.accessor('amount', { header: 'Amount', cell: ({ getValue }) => fmt(getValue<number>()) }),\n- ]\n\n+ const columns: ColumnDef<typeof features, Order>[] = [\n+ { field: 'orderId', header: 'Order ID' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n```\n\nThe `fieldFn` form is the same:\n\n```diff\n- columnHelper.accessor((row) => row.profile.name, { id: 'name', header: 'Name' })\n\n+ { id: 'name', fieldFn: (row) => row.profile.name, header: 'Name' }\n```\n\n## Mounting\n\n```diff\n- const table = useReactTable({\n- data, columns,\n- getCoreRowModel: getCoreRowModel(),\n- getSortedRowModel: getSortedRowModel(),\n- getFilteredRowModel: getFilteredRowModel(),\n- })\n- return (\n- <table>\n- <thead>{table.getHeaderGroups().map(/* ... */)}</thead>\n- <tbody>{table.getRowModel().rows.map(/* ... */)}</tbody>\n- </table>\n- )\n\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+\n+ <SvGrid data={rows} columns={columns} features={features} />\n```\n\nSv-grid bundles the render + virtualization. No `<table>` you have\nto author yourself.\n\n## Imperative state\n\n| TanStack Table | sv-grid |\n| ------------------------------------------- | ---------------------------------------- |\n| `table.setColumnFilters([{id, value}])` | `api.setFilter(id, { operator: 'contains', value })` |\n| `table.getColumn('id')?.setFilterValue(v)` | `api.setFilter(id, { operator: 'contains', value: v })` |\n| `table.setSorting([{id, desc}])` | `api.setSort(id, desc ? 'desc' : 'asc')` |\n| `table.setRowSelection(state)` | n/a - use `api.clearRowSelection()` + UI events |\n| `table.toggleAllRowsExpanded()` | `api.expandAllGroups()` |\n| `table.getColumn('x').toggleVisibility()` | `api.setColumnVisible('x', false)` |\n| `table.options.meta?.foo` | Pass through component props / `$state` |\n\n## Custom cells\n\n```diff\n- {\n- header: 'Status',\n- cell: ({ row }) => <Badge tone={row.original.status} />,\n- }\n\n+ {\n+ field: 'status', header: 'Status',\n+ cell: (ctx) => renderSnippet(StatusCell, { tone: ctx.row.original.status }),\n+ }\n```\n\n`renderSnippet` accepts any Svelte 5 snippet; `renderComponent`\naccepts a regular component if you prefer SFCs.\n\n## Server-side data\n\n```diff\n- const [pagination, setPagination] = useState({pageIndex: 0, pageSize: 25})\n- const [sorting, setSorting] = useState([])\n- const table = useReactTable({\n- data, columns, manualPagination: true, manualSorting: true,\n- state: { pagination, sorting },\n- onPaginationChange: setPagination,\n- onSortingChange: setSorting,\n- })\n\n+ <SvGrid\n+ data={rows} columns={columns} features={features}\n+ externalSort={true}\n+ externalFilter={true}\n+ onSortingChange={(clauses) => refetch({ sort: clauses })}\n+ onFiltersChange={(f) => refetch({ filters: f.columns })}\n+ />\n```\n\nOr hand the fetching to a controller and pass it as one prop:\n`createServerDataSource(source, { mode: 'infinite' })` owns the blocks,\nthe sort and filter round trips and the placeholder rows, and the\nmanual-flag wiring above disappears. TanStack Table has no server row\nmodel; per-group fetching is yours to write, where the Enterprise\n`createServerRowModel` does it over the same contract.\n\n<div data-docs-demo=\"148-server-row-model\" data-height=\"480\"></div>\n\n## What you get for free vs TanStack Table\n\n- **Renderer**. TanStack is headless-only; you draw the `<table>`.\n Sv-grid ships an opinionated, fast renderer with virtualization,\n scroll, sticky headers, column resize, keyboard nav, ARIA.\n- **Inline editing**. `editorType: 'text' | 'number' | 'date' |\n 'list' | ...` - built-in editors with parsing + validation hooks.\n- **CSP-clean**. No `eval`. The shipped tests confirm.\n- **In-grid AI helpers**. Natural-language filter, smart fill, summarise\n and classify, free in `@svgrid/grid` against a model you register.\n- **Enterprise features**. Excel and PDF export, print, import and pivot\n in one paid add-on; CSV, TSV and JSON export are free.\n\nThe headless demo below is the shape a TanStack app has today - a plain\n`<table>` driven by the engine - running on `createSvGrid`:\n\n<div data-docs-demo=\"186-headless-table\" data-height=\"520\"></div>\n\n## What you give up\n\n- **One engine across frameworks.** TanStack has adapters for React,\n Vue, Solid, Qwik, Lit and Svelte; sv-grid is Svelte 5-native and has\n no React wrapper.\n- **The smallest engine-only bundle.** The facts box at the top of the\n page has both packages measured the same way; the difference is the\n renderer, virtualizer, filter UI and editors you would otherwise write.\n- **TanStack Virtual and the shadcn-svelte data table recipe.** Sv-grid\n virtualizes on its own and has its own\n [shadcn-svelte guide](./migrating-from-shadcn-data-table.md).\n- **`meta` for arbitrary side-channel state.** Pass props directly.\n- **`@tanstack/match-sorter-utils` integration**. The grid's filter\n has a `contains` operator; if you need fuzzy match, plug your\n matcher in via the column's `cell` snippet or use\n `externalFilter={true}` and run the matcher yourself.\n\n## Frequently asked questions\n\n### How long does it take to migrate from TanStack Table to SvGrid?\n\nAbout 30 minutes per read-only grid and 2-4 hours for editing-heavy grids.\nBoth libraries use explicit row-model pipelines, so `createTable()` +\n`getCoreRowModel()` maps almost directly onto `createSvGrid()` +\n`createCoreRowModel()`.\n\n### Why switch from TanStack Table to SvGrid on Svelte 5?\n\nTanStack Table is headless-only and multi-framework, so you build the entire\nDOM, virtualization, filter UI, and editing layer yourself. SvGrid keeps the\nheadless core but ships a batteries-included `<SvGrid>` render component -\nvirtualization, Excel-style filters, cell selection, and inline editing work\nin one prop pass.\n\n### Is SvGrid free like TanStack Table?\n\nYes - `@svgrid/grid` is MIT-licensed, like TanStack Table. SvGrid\nadditionally offers an optional paid `@svgrid/enterprise` pack for Excel and\nPDF export, print, pivot and import, which TanStack Table does not provide at\nall; TanStack sells Enterprise Support as consulting instead, as the facts box\nabove notes.\n\n### Does the TanStack Svelte adapter support Svelte 5?\n\nYes. The v9 line of `@tanstack/svelte-table` declares a Svelte 5 peer range\nand reads rune data through getters; the version in the facts box above is\nthe one read from npm. If you are on the v8 adapter with Svelte 4 stores,\nthe port to sv-grid is the same work as the port to v9, minus the markup.\n\n## What you end up with\n\nThe same model you had, with the rendering already written.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable pageable pageSize={3} selectable />\n```\n\n## See also\n\n- [SvGrid vs TanStack Table](https://svgrid.com/compare/tanstack-table/) -\n the side-by-side comparison, with a source and date for every claim\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](./comparison.md) -\n the measured benchmark, TanStack column included\n- [Architecture](./architecture.md) - the headless engine + render\n component split\n- [Migrating from AG Grid](./migrating-from-ag-grid.md) - sibling guide\n- [Why headless?](../why-headless.md) - the design rationale\n"
|
|
4821
|
+
"markdown": "# Migrating from TanStack Table\n\nTanStack Table (formerly React Table) is the closest conceptual\nsibling to sv-grid - both are \"headless data grid\" libraries with\nexplicit row-model pipelines, and the v9 Svelte adapter,\n`@tanstack/svelte-table`, targets Svelte 5 with the same runes-first\nshape. If you already think in `createTable()` + a features object,\nthis is a half-day port; the vocabulary below covers the v8 names too.\n\n> Estimated effort: **30 min** per grid for read-only views, **2-4\n> hours** for editing-heavy grids.\n\n<!-- facts:start tanstack-table -->\n> **Facts, checked 12 Sep 2026.** `@tanstack/svelte-table` 9.2.4, MIT, last published 28 Aug 2026, 231,000 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@tanstack/svelte-table` 9.2.4 36.3 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). TanStack Table pricing, as its site states it: TanStack Table is MIT and free; tanstack.com is sponsor-supported and offers Enterprise Support as private consulting and expert support, with no licence sold for the table (https://tanstack.com/table/latest, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/).\n<!-- facts:end -->\n\n> **On v9?** SvGrid exports the same feature vocabulary, so most of this\n> page is automated. Run `npx @svgrid/migrate src` to preview the port, and\n> see [Migrating from the shadcn-svelte data table](./migrating-from-shadcn-data-table.md)\n> if that is where your table came from.\n\n## Vocabulary cheat sheet\n\n| TanStack Table | sv-grid |\n| ------------------------------- | ---------------------------------------- |\n| `useReactTable({...})` | `createSvGrid({...})` or `<SvGrid>` |\n| `getCoreRowModel()` | `createCoreRowModel()` |\n| `getSortedRowModel()` | Auto-registered by `rowSortingFeature` |\n| `getFilteredRowModel()` | Auto-registered by `columnFilteringFeature` |\n| `getPaginationRowModel()` | Built in; toggle with `showPagination` |\n| `getGroupedRowModel()` | `columnGroupingFeature` + `api.setGroupBy()` |\n| `getExpandedRowModel()` | `rowExpandingFeature` |\n| `flexRender(col.cell, ctx)` | `renderSnippet(MyCell, props)` OR string field |\n| `columnHelper.accessor('field')` | `{ field: 'field' }` directly |\n| `table.getRowModel().rows` | `api.getDisplayedRows()` |\n| `table.setColumnFilters(...)` | `api.setFilter(id, {...})` per column |\n| `meta` (column / table) | n/a - use column `cellClass` / `cell` instead |\n\n## Imports\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- import {\n- useReactTable, getCoreRowModel, getSortedRowModel, getFilteredRowModel,\n- flexRender, createColumnHelper,\n- } from '@tanstack/react-table'\n\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ renderSnippet,\n+ } from '@svgrid/grid'\n```\n\n## Column definitions\n\n```diff\n- const columnHelper = createColumnHelper<Order>()\n- const columns = [\n- columnHelper.accessor('orderId', { header: 'Order ID' }),\n- columnHelper.accessor('amount', { header: 'Amount', cell: ({ getValue }) => fmt(getValue<number>()) }),\n- ]\n\n+ const columns: ColumnDef<typeof features, Order>[] = [\n+ { field: 'orderId', header: 'Order ID' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n```\n\nThe `fieldFn` form is the same:\n\n```diff\n- columnHelper.accessor((row) => row.profile.name, { id: 'name', header: 'Name' })\n\n+ { id: 'name', fieldFn: (row) => row.profile.name, header: 'Name' }\n```\n\n## Mounting\n\n```diff\n- const table = useReactTable({\n- data, columns,\n- getCoreRowModel: getCoreRowModel(),\n- getSortedRowModel: getSortedRowModel(),\n- getFilteredRowModel: getFilteredRowModel(),\n- })\n- return (\n- <table>\n- <thead>{table.getHeaderGroups().map(/* ... */)}</thead>\n- <tbody>{table.getRowModel().rows.map(/* ... */)}</tbody>\n- </table>\n- )\n\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+\n+ <SvGrid data={rows} columns={columns} features={features} />\n```\n\nSv-grid bundles the render + virtualization. No `<table>` you have\nto author yourself.\n\n## Imperative state\n\n| TanStack Table | sv-grid |\n| ------------------------------------------- | ---------------------------------------- |\n| `table.setColumnFilters([{id, value}])` | `api.setFilter(id, { operator: 'contains', value })` |\n| `table.getColumn('id')?.setFilterValue(v)` | `api.setFilter(id, { operator: 'contains', value: v })` |\n| `table.setSorting([{id, desc}])` | `api.setSort(id, desc ? 'desc' : 'asc')` |\n| `table.setRowSelection(state)` | n/a - use `api.clearRowSelection()` + UI events |\n| `table.toggleAllRowsExpanded()` | `api.expandAllGroups()` |\n| `table.getColumn('x').toggleVisibility()` | `api.setColumnVisible('x', false)` |\n| `table.options.meta?.foo` | Pass through component props / `$state` |\n\n## Custom cells\n\n```diff\n- {\n- header: 'Status',\n- cell: ({ row }) => <Badge tone={row.original.status} />,\n- }\n\n+ {\n+ field: 'status', header: 'Status',\n+ cell: (ctx) => renderSnippet(StatusCell, { tone: ctx.row.original.status }),\n+ }\n```\n\n`renderSnippet` accepts any Svelte 5 snippet; `renderComponent`\naccepts a regular component if you prefer SFCs.\n\n## Server-side data\n\n```diff\n- const [pagination, setPagination] = useState({pageIndex: 0, pageSize: 25})\n- const [sorting, setSorting] = useState([])\n- const table = useReactTable({\n- data, columns, manualPagination: true, manualSorting: true,\n- state: { pagination, sorting },\n- onPaginationChange: setPagination,\n- onSortingChange: setSorting,\n- })\n\n+ <SvGrid\n+ data={rows} columns={columns} features={features}\n+ externalSort={true}\n+ externalFilter={true}\n+ onSortingChange={(clauses) => refetch({ sort: clauses })}\n+ onFiltersChange={(f) => refetch({ filters: f.columns })}\n+ />\n```\n\nOr hand the fetching to a controller and pass it as one prop:\n`createServerDataSource(source, { mode: 'infinite' })` owns the blocks,\nthe sort and filter round trips and the placeholder rows, and the\nmanual-flag wiring above disappears. TanStack Table has no server row\nmodel; per-group fetching is yours to write, where the Enterprise\n`createServerRowModel` does it over the same contract.\n\n<div data-docs-demo=\"148-server-row-model\" data-height=\"480\"></div>\n\n## What you get for free vs TanStack Table\n\n- **Renderer**. TanStack is headless-only; you draw the `<table>`.\n Sv-grid ships an opinionated, fast renderer with virtualization,\n scroll, sticky headers, column resize, keyboard nav, ARIA.\n- **Inline editing**. `editorType: 'text' | 'number' | 'date' |\n 'list' | ...` - built-in editors with parsing + validation hooks.\n- **CSP-clean**. No `eval`. The shipped tests confirm.\n- **In-grid AI helpers**. Natural-language filter, smart fill, summarise\n and classify, free in `@svgrid/grid` against a model you register.\n- **Enterprise features**. Excel and PDF export, print, import and pivot\n in one paid add-on; CSV, TSV and JSON export are free.\n\nThe headless demo below is the shape a TanStack app has today - a plain\n`<table>` driven by the engine - running on `createSvGrid`:\n\n<div data-docs-demo=\"186-headless-table\" data-height=\"520\"></div>\n\n## What you give up\n\n- **One engine across frameworks.** TanStack has adapters for React,\n Vue, Solid, Qwik, Lit and Svelte; sv-grid is Svelte 5-native and has\n no React wrapper.\n- **The smallest engine-only bundle.** The facts box at the top of the\n page has both packages measured the same way; the difference is the\n renderer, virtualizer, filter UI and editors you would otherwise write.\n- **TanStack Virtual and the shadcn-svelte data table recipe.** Sv-grid\n virtualizes on its own and has its own\n [shadcn-svelte guide](./migrating-from-shadcn-data-table.md).\n- **`meta` for arbitrary side-channel state.** Pass props directly.\n- **`@tanstack/match-sorter-utils` integration**. The grid's filter\n has a `contains` operator; if you need fuzzy match, plug your\n matcher in via the column's `cell` snippet or use\n `externalFilter={true}` and run the matcher yourself.\n\n## Frequently asked questions\n\n### How long does it take to migrate from TanStack Table to SvGrid?\n\nAbout 30 minutes per read-only grid and 2-4 hours for editing-heavy grids.\nBoth libraries use explicit row-model pipelines, so `createTable()` +\n`getCoreRowModel()` maps almost directly onto `createSvGrid()` +\n`createCoreRowModel()`.\n\n### Why switch from TanStack Table to SvGrid on Svelte 5?\n\nTanStack Table is headless-only and multi-framework, so you build the entire\nDOM, virtualization, filter UI, and editing layer yourself. SvGrid keeps the\nheadless core but ships a batteries-included `<SvGrid>` render component -\nvirtualization, Excel-style filters, cell selection, and inline editing work\nin one prop pass.\n\n### Is SvGrid free like TanStack Table?\n\nYes - `@svgrid/grid` is MIT-licensed, like TanStack Table. SvGrid\nadditionally offers an optional paid `@svgrid/enterprise` pack for Excel and\nPDF export, print, pivot and import, which TanStack Table does not provide at\nall; TanStack sells Enterprise Support as consulting instead, as the facts box\nabove notes.\n\n### Does the TanStack Svelte adapter support Svelte 5?\n\nYes. The v9 line of `@tanstack/svelte-table` declares a Svelte 5 peer range\nand reads rune data through getters; the version in the facts box above is\nthe one read from npm. If you are on the v8 adapter with Svelte 4 stores,\nthe port to sv-grid is the same work as the port to v9, minus the markup.\n\n## What you end up with\n\nThe same model you had, with the rendering already written.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable pageable pageSize={3} selectable />\n```\n\n## See also\n\n- [SvGrid vs TanStack Table](https://svgrid.com/compare/tanstack-table/) -\n the side-by-side comparison, with a source and date for every claim\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](./comparison.md) -\n the measured benchmark, TanStack column included\n- [Architecture](./architecture.md) - the headless engine + render\n component split\n- [Migrating from AG Grid](./migrating-from-ag-grid.md) - sibling guide\n- [Why headless?](../why-headless.md) - the design rationale\n"
|
|
4822
4822
|
},
|
|
4823
4823
|
{
|
|
4824
4824
|
"slug": "help/migrating-from-ui-kit-tables",
|
|
4825
4825
|
"path": "docs/help/migrating-from-ui-kit-tables.md",
|
|
4826
4826
|
"title": "Migrating from a UI-kit table (Flowbite / Skeleton / shadcn-svelte)",
|
|
4827
4827
|
"section": "Help",
|
|
4828
|
-
"markdown": "# Migrating from a UI-kit table (Flowbite / Skeleton / shadcn-svelte)\n\nFlowbite-Svelte, Skeleton, and shadcn-svelte all ship a styled `<Table>`\ncomponent. They are presentation components: they render the rows you\npass and match your design tokens, but sorting, filtering,\nvirtualization, and editing are yours to write by hand. Moving to SvGrid\nreplaces that hand-rolled logic with built-in features - while still\nletting you match the design system.\n\n> **Not the shadcn-svelte data table.** That one is a separate recipe\n> built on TanStack Table v9, and it already does sorting, filtering,\n> pagination, and row selection. If that is what you have, read\n> [Migrating from the shadcn-svelte data table](./migrating-from-shadcn-data-table.md)\n> instead - the port is different, and smaller.\n\n<!-- facts:start svelte-ui-kit-tables -->\n> **Facts, checked 12 Sep 2026.** `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the 30 days to 10 Sep 2026. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Flowbite / Skeleton / shadcn-svelte tables pricing, as its site states it: Flowbite Svelte, Skeleton and shadcn-svelte are MIT component libraries; their table components are free and no grid licence is sold (https://github.com/themesberg/flowbite-svelte, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4828
|
+
"markdown": "# Migrating from a UI-kit table (Flowbite / Skeleton / shadcn-svelte)\n\nFlowbite-Svelte, Skeleton, and shadcn-svelte all ship a styled `<Table>`\ncomponent. They are presentation components: they render the rows you\npass and match your design tokens, but sorting, filtering,\nvirtualization, and editing are yours to write by hand. Moving to SvGrid\nreplaces that hand-rolled logic with built-in features - while still\nletting you match the design system.\n\n> **Not the shadcn-svelte data table.** That one is a separate recipe\n> built on TanStack Table v9, and it already does sorting, filtering,\n> pagination, and row selection. If that is what you have, read\n> [Migrating from the shadcn-svelte data table](./migrating-from-shadcn-data-table.md)\n> instead - the port is different, and smaller.\n\n<!-- facts:start svelte-ui-kit-tables -->\n> **Facts, checked 12 Sep 2026.** `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the 30 days to 10 Sep 2026. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026). Flowbite / Skeleton / shadcn-svelte tables pricing, as its site states it: Flowbite Svelte, Skeleton and shadcn-svelte are MIT component libraries; their table components are free and no grid licence is sold (https://github.com/themesberg/flowbite-svelte, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs Flowbite / Skeleton / shadcn-svelte tables](https://svgrid.com/compare/svelte-ui-kit-tables/).\n<!-- facts:end -->\n\n> Estimated effort: **30 min - 1 hour** per table. You are mostly\n> deleting `{#each}` markup and the sort / filter state you wrote\n> yourself.\n\n## When this guide applies\n\nYou have a table that started simple and has grown:\n\n- You added a click-to-sort handler and a sort-state variable.\n- You added a search box and an array `.filter(...)`.\n- The list got long and now you want virtualization or pagination.\n- You started editing cells inline and it got messy.\n\nThat is the moment a styled `<Table>` stops paying for itself.\n\n## Before / after\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- <script>\n- import { Table, TableHead, TableHeadCell, TableBody, TableBodyRow, TableBodyCell } from 'flowbite-svelte'\n- let sortKey = 'name', asc = true\n- $: sorted = [...rows].sort((a, b) => (a[sortKey] > b[sortKey] ? 1 : -1) * (asc ? 1 : -1))\n- </script>\n-\n- <Table>\n- <TableHead>\n- <TableHeadCell on:click={() => (sortKey = 'name')}>Name</TableHeadCell>\n- <TableHeadCell on:click={() => (sortKey = 'amount')}>Amount</TableHeadCell>\n- </TableHead>\n- <TableBody>\n- {#each sorted as row}\n- <TableBodyRow>\n- <TableBodyCell>{row.name}</TableBodyCell>\n- <TableBodyCell>{row.amount}</TableBodyCell>\n- </TableBodyRow>\n- {/each}\n- </TableBody>\n- </Table>\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} showPagination />\n```\n\nThe sort handler, the `sorted` derivation, and the `{#each}` all go\naway. Sorting is a click on the header; filtering is the column menu.\n\n## Keep your design system\n\nSvGrid is unstyled-by-token, so it can match Flowbite / Skeleton /\nshadcn:\n\n- Re-theme through the `--sg-*` CSS custom properties (borders, header\n background, zebra rows, hover, selection, density).\n- Or drive those tokens from your Tailwind theme - see the\n [Tailwind integration](./tailwind.md) guide.\n\n## What you get for free\n\n- **Sorting, filtering, and pagination** without writing handlers.\n- **Row + column virtualization** so thousands of rows stay smooth.\n- **Inline editing**, **cell-range selection + copy**, grouping, tree,\n and master/detail when you need them.\n- **Accessibility** - WAI-ARIA grid roles and keyboard navigation built\n in, instead of a plain `<table>`.\n\n## What you give up\n\n- The **tiny footprint** of a styled `<table>` for a truly static list.\n- A **pixel-perfect**, zero-config match with the rest of the kit - you\n re-create the look with tokens instead (a one-time setup).\n\n## Frequently asked questions\n\n### When should I replace a Flowbite / Skeleton / shadcn table with a data grid?\n\nWhen the table needs sorting, filtering, virtualization, inline editing, or\nlarge datasets. These styled `<Table>` components are presentation only;\nonce you are hand-writing table behaviour, a data grid like SvGrid removes\nthat code. (shadcn-svelte also ships a separate TanStack-based data table -\nsee [that migration guide](./migrating-from-shadcn-data-table.md).)\n\n### Can SvGrid match my existing UI-kit styling?\n\nYes. SvGrid themes through `--sg-*` CSS variables, which you can wire to your\nTailwind / design-system tokens so it matches Flowbite, Skeleton, or\nshadcn-svelte.\n\n### Is it overkill for a small static table?\n\nFor a small, static table that never sorts or filters, a styled `<table>` is\nlighter and fine. Switch when the behaviour - not just the styling - becomes the\nwork.\n\n## What you end up with\n\nEverything the presentational table could not do: sort, filter, page, edit.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable pageable pageSize={3} editable />\n```\n\n## See also\n\n- [SvGrid vs UI-kit tables](https://svgrid.com/compare/svelte-ui-kit-tables/) - the side-by-side comparison\n- [Tailwind integration](./tailwind.md) - match your design system\n- [Getting started](../getting-started.md) - a working grid in ~15 lines\n"
|
|
4829
4829
|
},
|
|
4830
4830
|
{
|
|
4831
4831
|
"slug": "help/migrating-from-vincjo-datatables",
|
|
4832
4832
|
"path": "docs/help/migrating-from-vincjo-datatables.md",
|
|
4833
4833
|
"title": "Migrating from @vincjo/datatables",
|
|
4834
4834
|
"section": "Help",
|
|
4835
|
-
"markdown": "# Migrating from @vincjo/datatables\n\n`@vincjo/datatables` is a small, ergonomic Svelte datatable helper: you\nwrap your data in a handler and it gives you reactive sorting,\nfiltering, and pagination while you keep your own table markup. SvGrid\ncovers the same job and then keeps going - virtualization, an\nExcel-style filter menu, inline editing, and a render component - so the\nport is mostly about deciding how much markup you want to keep.\n\n> Estimated effort: **30 min - 2 hours** per table. A simple list is a\n> 30-minute swap; a feature-heavy one trends toward two hours.\n\n<!-- facts:start vincjo-datatables -->\n> **Facts, checked 12 Sep 2026.** `@vincjo/datatables` 2.8.1, MIT, last published 4 Jun 2026, 72,800 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@vincjo/datatables` 2.8.1 10.2 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). @vincjo/datatables pricing, as its site states it: @vincjo/datatables is MIT on npm and free; no licence is sold (https://github.com/vincjo/datatables, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $
|
|
4835
|
+
"markdown": "# Migrating from @vincjo/datatables\n\n`@vincjo/datatables` is a small, ergonomic Svelte datatable helper: you\nwrap your data in a handler and it gives you reactive sorting,\nfiltering, and pagination while you keep your own table markup. SvGrid\ncovers the same job and then keeps going - virtualization, an\nExcel-style filter menu, inline editing, and a render component - so the\nport is mostly about deciding how much markup you want to keep.\n\n> Estimated effort: **30 min - 2 hours** per table. A simple list is a\n> 30-minute swap; a feature-heavy one trends toward two hours.\n\n<!-- facts:start vincjo-datatables -->\n> **Facts, checked 12 Sep 2026.** `@vincjo/datatables` 2.8.1, MIT, last published 4 Jun 2026, 72,800 npm downloads in the 30 days to 10 Sep 2026. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `@vincjo/datatables` 2.8.1 10.2 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). @vincjo/datatables pricing, as its site states it: @vincjo/datatables is MIT on npm and free; no licence is sold (https://github.com/vincjo/datatables, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs @vincjo/datatables](https://svgrid.com/compare/vincjo-datatables/).\n<!-- facts:end -->\n\n## Vocabulary cheat sheet\n\n| @vincjo/datatables | sv-grid |\n| ------------------------------------------ | ----------------------------------------- |\n| `new TableHandler(data, { rowsPerPage })` | `createSvGrid({...})` or `<SvGrid>` |\n| `<ThSort {table} field=\"name\">` | `rowSortingFeature` (header sort built in) |\n| `<ThFilter {table} field=\"name\">` | `columnFilteringFeature` |\n| `table.global.set(query)` (search) | `api.setState({ globalFilter: query })` |\n| `<Pagination {table} />` / `<RowCount>` | Built in; toggle `showPagination` |\n| `table.rows` (current page rows) | `api.getDisplayedRows()` |\n| Server mode (`table.load(...)`) | `externalSort` / `externalFilter` + refetch |\n| Your own `<table>` + `{#each table.rows}` | `<SvGrid>` render component |\n\n## Before / after\n\nThe example at the end of this page runs against these rows:\n\n```svelte {preamble}\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n\n type Person = {\n id: number\n name: string\n department: string\n city: string\n age: number\n salary: number\n }\n\n const people: Person[] = [\n { id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },\n { id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },\n { id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },\n { id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },\n { id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },\n ]\n\n let rows = $state<Person[]>(people)\n\n const columns: GridColumns<Person> = [\n { field: 'name', header: 'Name', width: 200, editorType: 'text' },\n { field: 'department', header: 'Department', width: 150, editorType: 'text' },\n { field: 'city', header: 'City', width: 140, editorType: 'text' },\n { field: 'age', header: 'Age', width: 90, editorType: 'number' },\n { field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },\n ]\n</script>\n```\n\n```diff\n- <script>\n- import { TableHandler, ThSort, ThFilter, Pagination } from '@vincjo/datatables'\n- const table = new TableHandler(rows, { rowsPerPage: 25 })\n- </script>\n-\n- <table>\n- <thead><tr>\n- <ThSort {table} field=\"name\">Name</ThSort>\n- <ThSort {table} field=\"amount\">Amount</ThSort>\n- </tr></thead>\n- <tbody>\n- {#each table.rows as row}\n- <tr><td>{row.name}</td><td>{row.amount}</td></tr>\n- {/each}\n- </tbody>\n- </table>\n- <Pagination {table} />\n\n+ <script lang=\"ts\">\n+ import {\n+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,\n+ type ColumnDef,\n+ } from '@svgrid/grid'\n+\n+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })\n+ const columns: ColumnDef<typeof features, Row>[] = [\n+ { field: 'name', header: 'Name' },\n+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },\n+ ]\n+ </script>\n+\n+ <SvGrid data={rows} columns={columns} features={features} showPagination />\n```\n\n## Server-side data\n\n```diff\n- // @vincjo/datatables: drive a server with the handler's load hook\n- const table = new TableHandler(rows, { rowsPerPage: 25 })\n- table.load((state) => fetchRows(state)) // sort/filter/page sent to your API\n\n+ <SvGrid\n+ data={rows} columns={columns} features={features}\n+ externalSort={true} externalFilter={true}\n+ onSortingChange={(clauses) => refetch({ sort: clauses })}\n+ onFiltersChange={(f) => refetch({ filters: f.columns })}\n+ />\n```\n\n## What you get for free\n\n- **A render component** with virtualization - you stop authoring the\n `<table>` and the `{#each}`.\n- **Excel-style filter menu**, **cell-range selection + copy**, and\n **inline editing** with typed editors.\n- **Grouping, tree data, and master/detail** when the table grows up.\n- **Enterprise features** - export, import, pivot, AI.\n\n## What you give up\n\n- **The tiny footprint.** If all you ever need is sort / filter /\n paginate over a small list, `@vincjo/datatables` stays smaller.\n- **Total markup control.** SvGrid renders the table; you theme it with\n `--sg-*` tokens and Tailwind rather than writing every `<td>`.\n\n## Frequently asked questions\n\n### Should I move from @vincjo/datatables to SvGrid?\n\nMove when a hand-rolled table stops being enough - when you need virtualization\nfor large datasets, an Excel-style filter menu, inline editing, grouping, or\ntree data. For a small sort/filter/paginate list, `@vincjo/datatables` is a fine,\nlighter choice.\n\n### Is SvGrid also MIT-licensed like @vincjo/datatables?\n\nYes. `@svgrid/grid` is MIT, like `@vincjo/datatables`. SvGrid adds an\noptional paid `@svgrid/enterprise` pack (export, import, pivot, AI).\n\n### Can I keep my own table markup after switching?\n\nYes. SvGrid has a headless core (`createSvGrid` + row-model factories) you can\ndrive with your own markup, the same way `@vincjo/datatables` lets you. Most\nteams use the `<SvGrid>` component instead because it removes the boilerplate.\n\n## What you end up with\n\nSorting, filtering and pagination without the hand-written table around it.\n\n```svelte {runnable}\n<SvGrid data={rows} {columns} sortable filterable pageable pageSize={3} />\n```\n\n## See also\n\n- [SvGrid vs @vincjo/datatables](https://svgrid.com/compare/vincjo-datatables/) - the side-by-side comparison\n- [Migrating from svelte-headless-table](./migrating-from-svelte-headless-table.md) - sibling Svelte guide\n- [Why headless?](../why-headless.md) - keep your own markup if you want to\n"
|
|
4836
4836
|
},
|
|
4837
4837
|
{
|
|
4838
4838
|
"slug": "help/missing-features",
|
|
@@ -5245,7 +5245,7 @@ export const docs = [
|
|
|
5245
5245
|
"path": "docs/help/svelte-5-upgrade-data-tables.md",
|
|
5246
5246
|
"title": "Upgrading a Svelte 4 table to Svelte 5: what breaks, what does not, and the three ways out",
|
|
5247
5247
|
"section": "Help",
|
|
5248
|
-
"markdown": "\n# Upgrading a Svelte 4 table to Svelte 5: what breaks, what does not, and the three ways out\n\nIf your Svelte 4 app has a table built on `svelte-headless-table`, the Svelte 5\nupgrade forces a decision about it, and most of what is written about that\ndecision is guesswork. This page is not. We put the table from the library's\nown documentation into a Svelte 4 project, upgraded it to Svelte 5 one step at a\ntime, and captured every line the tools printed. The script and the captures\nare in the repo at\n[tools/migration-lab](https://github.com/sv-grid/sv-grid/tree/main/tools/migration-lab);\nevery code block below is a quote from those files, checked by a test, and the\nfirst line of each capture records the versions it was made with.\n\n<!-- facts:start svelte-headless-table pkg:@humanspeak/svelte-headless-table -->\n> **Facts, checked 12 Sep 2026.** `svelte-headless-table` 0.18.3, MIT, last published 28 Oct 2024, 90,100 npm downloads in the 30 days to 10 Sep 2026. `@humanspeak/svelte-headless-table` 6.2.0, MIT, last published 27 Aug 2026, 8,640 npm downloads in the same window. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `svelte-headless-table` 0.18.3 5.7 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). svelte-headless-table pricing, as its site states it: svelte-headless-table is MIT and free; no paid licence or support is offered, and the author states there are no plans for a Svelte 5 port (https://github.com/bryanmylee/svelte-headless-table, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $599 per developer per year. Side by side, with sources: [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/).\n<!-- facts:end -->\n\nThe short version: the install warns and goes through, the untouched component\nkeeps compiling, and the trouble starts the day you write your first rune in\nthat component. The three exits are a maintained fork, TanStack Table v9, and\nSvGrid, and they trade different things.\n\n## The component we upgraded\n\nA `PeopleTable` written the way svelte-headless-table's docs teach it: a\n`writable` over a prop, a `$:` to keep it in sync, three plugins, the view model\nread through `<Subscribe>` and `<Render>`, a pager on `pluginStates.page`, and a\n`select` event dispatched from the row.\n\n<!-- captured: fixture/svelte4/PeopleTable.svelte -->\n```svelte\n<script lang=\"ts\">\n // The table as svelte-headless-table's own docs show it: a store for the\n // data, plugins for behaviour, and a view model read through <Subscribe>\n // and <Render>. Svelte 4 throughout: `export let`, `$:`, a dispatcher,\n // `on:click`, and `let:` slot props.\n import { createEventDispatcher } from 'svelte'\n import { writable } from 'svelte/store'\n import { createTable, Subscribe, Render } from 'svelte-headless-table'\n import { addSortBy, addColumnFilters, addPagination } from 'svelte-headless-table/plugins'\n import type { Person } from './people'\n\n export let people: Person[] = []\n export let pageSize = 5\n\n const dispatch = createEventDispatcher<{ select: Person }>()\n\n const data = writable<Person[]>(people)\n $: data.set(people)\n\n const table = createTable(data, {\n sort: addSortBy(),\n filter: addColumnFilters(),\n page: addPagination({ initialPageSize: pageSize }),\n })\n```\n\nThe full file is 83 lines; the 40 that follow are the `<table>`, three levels\nof `<Subscribe let:...>` and a `<p>` with the pager. On the pinned Svelte 4\ntoolchain it checks clean:\n\n<!-- captured: 01-svelte4-baseline.txt -->\n```text\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\nsvelte-check found 0 errors and 0 warnings\n```\n\n## Step 1: the install warns and goes through\n\n`svelte-headless-table` declares `peerDependencies: { svelte: \"^4.0.0\" }`, and\nthat range is not going to change: the facts box above has the last release\ndate, and the project's README says there are no plans for a Svelte 5 port.\nSo what does `npm install svelte@5` do against it? On npm 11, this:\n\n<!-- captured: 02-npm-install-svelte5.txt -->\n```text\n$ npm install svelte@5.57.1\n\nadded 10 packages, removed 10 packages, and changed 2 packages in <time>\nnpm warn ERESOLVE overriding peer dependency\nnpm warn While resolving: svgrid-migration-lab@undefined\nnpm warn Found: svelte@4.2.20\nnpm warn node_modules/svelte\nnpm warn peer svelte@\"^4.0.0 || ^5.0.0-next.0\" from svelte-check@4.7.6\nnpm warn node_modules/svelte-check\nnpm warn dev svelte-check@\"4.7.6\" from the root project\nnpm warn 5 more (svelte-headless-table, svelte-keyed, svelte-render, ...)\nnpm warn\nnpm warn Could not resolve dependency:\nnpm warn peer svelte@\"^4.0.0\" from svelte-headless-table@0.18.3\nnpm warn node_modules/svelte-headless-table\nnpm warn dev svelte-headless-table@\"0.18.3\" from the root project\nnpm warn ERESOLVE overriding peer dependency\nnpm warn ERESOLVE overriding peer dependency\nnpm warn ERESOLVE overriding peer dependency\n\n(exit 0)\n```\n\nExit 0. npm 11 overrides the conflict and tells you so; older npm releases\nstopped with an `ERESOLVE` error until you added `--legacy-peer-deps`, and\npnpm prints an unmet-peer warning of its own. Either way, the peer range is a\nstatement, not a lock: the library's author is telling you it was never run\nagainst the Svelte you now have. Nothing enforces it.\n\n## Step 2: the untouched component still compiles\n\nSvelte 5 compiles Svelte 4 components in legacy mode, so `export let`, `$:`,\n`createEventDispatcher`, `on:click` and `let:` slot props all keep working\nuntil you opt a file into runes. With Svelte 5 installed and the component\nexactly as it was:\n\n<!-- captured: 03-svelte5-legacy-component.txt -->\n```text\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\nsvelte-check found 0 errors and 0 warnings\n```\n\nThis is the part the scare stories leave out. If your only goal is to be on\nSvelte 5, you can install it, keep the table exactly as it is, and ship. The\nlibrary's own components (`<Subscribe>`, `<Render>`) compile in legacy mode\ntoo.\n\n## Step 3: the first rune\n\nWhat you cannot do is make that component a runes component and keep the\ntable as it is. Port `PeopleTable` by the rules in the\n[official migration guide](https://svelte.dev/docs/svelte/v5-migration-guide):\n`export let` becomes `$props()`, `$:` becomes `$derived` and `$effect`, the\ndispatcher becomes a callback prop, `on:click` becomes `onclick`. Leave the\nsvelte-headless-table wiring alone, because the guide has nothing to say about\nit. The checker now says:\n\n<!-- captured: 04-svelte5-runes-component.txt -->\n```text\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\n<lab>\\src\\PeopleTable.svelte:19:35\nWarn: This reference only captures the initial value of `people`. Did you mean to reference it inside a closure instead?\nhttps://svelte.dev/e/state_referenced_locally (svelte)\n\n<lab>\\src\\PeopleTable.svelte:27:44\nWarn: This reference only captures the initial value of `pageSize`. Did you mean to reference it inside a closure instead?\nhttps://svelte.dev/e/state_referenced_locally (svelte)\n\n====================================\nsvelte-check found 0 errors and 2 warnings in 1 file\n```\n\nTwo warnings, no errors, and both are the same fact: the library takes a store,\nyour data is now a rune, and the `writable(people)` you built to bridge them\ncaptured the first value of `people` and nothing after. The fix is an\n`$effect` that writes the prop into the store on every change, which is what\nthe ported fixture does, and it works. It is also a bridge you now own, in\nevery component that has a table, between a reactivity model the library was\nbuilt for and the one your app is written in.\n\nThat is the actual shape of the problem. Not a red build: a component that\ncompiles, with a store-and-slot-props library bolted to a runes app by code you\nmaintain, on a package that will not move. The pieces it leans on are the ones\nSvelte 5 has deprecated: `let:` slot props and `<slot>` in favour of snippets,\nand `<svelte:component>`, which is what `<Render>` uses underneath\n(`svelte-render` 2.0.1, `PropsRenderer.svelte`, peer `svelte ^4.0.0`). They\nkeep working in legacy mode today; deprecated syntax is what the next major\nremoves, and this library will not be updated when it does.\n\n## The three ways out\n\nYou have three honest options, and you should know all of them before picking.\n\n1. **`@humanspeak/svelte-headless-table`**, a maintained fork on Svelte 5 with\n the same API. Its version, publish date and downloads are in the facts box.\n Switching is one package rename; you keep every line of markup and every\n `<Subscribe>`, and you keep the store bridge from step 3. If your table\n works and Svelte 5 is all you need, this is the cheapest exit by a wide\n margin.\n2. **TanStack Table v9.** Its Svelte adapter declares a Svelte 5 peer range and\n its state shape is runes-first, so the bridge goes away. It is still\n headless: you write and maintain the `<table>`, the virtualizer, the filter\n UI and the editors yourself. The\n [TanStack migration guide](./migrating-from-tanstack-table.md) covers the\n vocabulary.\n3. **SvGrid.** A different trade: you delete the markup and take a renderer.\n The column definitions and the plugin list carry over; the `<table>`, the\n `<Subscribe>` blocks, the pager and the store bridge do not exist any more,\n because `<SvGrid>` renders all of that. The rest of this page is what that\n looks like on the fixture above.\n\nPick 1 if the markup is fine and the library being dead does not bother you.\nPick 2 if you want the markup and a maintained engine. Pick 3 if the markup is\nthe part you are tired of.\n\n## Step 4: the codemod\n\n`npx @svgrid/migrate` ports a svelte-headless-table component to SvGrid. It\npreviews by default and only writes with `--write`, and it says what it could\nnot map instead of dropping it. On the Svelte 4 original:\n\n<!-- captured: 05-codemod.txt -->\n```text\n warning A custom `cell` renderer was found. SvGrid renders cells with a snippet, not `createRender`, so this one needs porting by hand - it is preserved as a comment.\n warning The template still reads `pageIndex`, `pageCount`, `shown` from the view model, which is gone. <SvGrid> renders its own pager and row count (`pageable`, `showPagination`), so remove that markup, or read the grid through `onApiReady` if you need the numbers.\n warning The table markup dispatched `select` from a row; that handler went with the `<tr>`. Wire it to `onRowClick={({ row }) => ...}` (or `onCellClick`) on <SvGrid>, and turn the `createEventDispatcher` into a callback prop if the component is moving to runes.\n note Column resizing, keyboard navigation and ARIA grid semantics are built into <SvGrid>; the markup that provided them is intentionally gone.\n\n1 file(s) would change, with 3 warning(s).\nRe-run with --write to apply.\n```\n\nThree warnings, each naming a thing it left for you. Write it, swap the\npackages, and check:\n\n<!-- captured: 06-after-codemod.txt -->\n```text\n$ npm install @svgrid/grid@3.0.4 --legacy-peer-deps\n\nadded 1 package in <time>\n\n(exit 0)\n\n$ npm uninstall svelte-headless-table --legacy-peer-deps\n\nremoved 4 packages in <time>\n\n(exit 0)\n\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\n<lab>\\src\\PeopleTable.svelte:31:23\nError: `$pageIndex` is an illegal variable name. To reference a global variable called `$pageIndex`, use `globalThis.$pageIndex`\nhttps://svelte.dev/e/global_reference_invalid (svelte)\n```\n\n<!-- captured: 06-after-codemod.txt -->\n```text\nsvelte-check found 9 errors and 0 warnings in 1 file\n```\n\nAll nine are the pager `<p>` the second warning named, reading `shown`,\n`$pageIndex` and `$pageCount` from a view model that no longer exists. The\ncodemod does not delete markup outside the `<table>`, because it cannot know\nwhat else is in there; it tells you what will not compile. Delete the `<p>`\n(the grid draws its own pager), turn the `select` event into a callback prop\non `onRowClick` as the third warning says, and:\n\n<!-- captured: 07-hand-edits.txt -->\n```text\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\nsvelte-check found 0 errors and 0 warnings\n```\n\n## What you end up with\n\nThe component after the codemod and the two hand edits:\n\n<!-- captured: PeopleTable.after.svelte -->\n```svelte\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n import type { Person } from './people'\n export let people: Person[] = []\n export let pageSize = 5\n export let onselect: (person: Person) => void = () => {}\n\n const columns: GridColumns<(typeof people)[number]> = [\n {\n header: 'Name',\n field: 'name',\n },\n {\n header: 'Department',\n field: 'department',\n },\n {\n header: 'City',\n field: 'city',\n },\n {\n header: 'Salary',\n field: 'salary',\n // TODO port: cell: ({ value }) => value.toLocaleString('en-US', { style: 'currency', currency: 'USD\n },\n ]\n</script>\n\n<SvGrid data={people} {columns} sortable filterable showColumnFilters pageable pageSize={pageSize}\n onRowClick={({ row }) => onselect(row)} />\n```\n\n83 lines became 31. The `TODO port:` comment is the one thing left to do by\nhand: the currency cell becomes `format: { type: 'currency', currency: 'USD' }`\non the column, and the comment goes. There is no store, no `$:`, no\n`<Subscribe>`, no `let:`, and nothing in the file that Svelte 5 has deprecated,\nso the same component moves to runes whenever you like with the official\nmigration script and nothing else to port.\n\n## What to read next\n\n- [Migrating from svelte-headless-table](./migrating-from-svelte-headless-table.md) -\n the plugin-by-plugin mapping and what the codemod will not do\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/) -\n the side-by-side, with a source and date for every claim\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - exit 2 in detail\n- [Migrating from the shadcn-svelte data table](./migrating-from-shadcn-data-table.md) -\n the same codemod on the TanStack-based recipe\n- [Why headless?](../why-headless.md) - if you want to keep your own markup\n on a maintained Svelte 5 engine, `@svgrid/grid/core` is that too\n\n## Frequently asked questions\n\n### Does svelte-headless-table work with Svelte 5?\n\nIn legacy mode, yes: the install prints a peer-dependency warning and the\nuntouched component type-checks clean, as the captures above show. What does\nnot work is moving a component that uses it to runes without maintaining a\nstore bridge yourself, and the library is not going to be updated for the\ndeprecations that bridge leans on.\n\n### Is the peer dependency conflict an error?\n\nOn npm 11 it is a warning and the install exits 0; on older npm it was an\n`ERESOLVE` error until you passed `--legacy-peer-deps`; pnpm warns. It never\nstops the code from running. It tells you the library was not built against\nthe Svelte you have.\n\n### Should I just use the maintained fork?\n\nIf your table works and all you need is Svelte 5, yes, and this page says so.\nThe fork keeps the same API, so you keep the same markup and the same store\nbridge. Move to SvGrid when the markup and the bridge are what you want gone.\n\n### How much of the port does the codemod do?\n\nThe column definitions, the plugin list and the `<table>` replacement, and it\nnames what it leaves: custom cell renderers, markup outside the table that read\nthe view model, and events the rows dispatched. On the fixture that was two\nhand edits and one `format` option.\n\n### Can I rerun this myself?\n\n`node tools/migration-lab/run.mjs` in the repo. It installs the pinned Svelte 4\ntoolchain into its own folder, upgrades it, runs the codemod from the checkout,\nand rewrites the captured files; the header of each one records the versions.\nBump the pins to try a newer Svelte.\n"
|
|
5248
|
+
"markdown": "\n# Upgrading a Svelte 4 table to Svelte 5: what breaks, what does not, and the three ways out\n\nIf your Svelte 4 app has a table built on `svelte-headless-table`, the Svelte 5\nupgrade forces a decision about it, and most of what is written about that\ndecision is guesswork. This page is not. We put the table from the library's\nown documentation into a Svelte 4 project, upgraded it to Svelte 5 one step at a\ntime, and captured every line the tools printed. The script and the captures\nare in the repo at\n[tools/migration-lab](https://github.com/sv-grid/sv-grid/tree/main/tools/migration-lab);\nevery code block below is a quote from those files, checked by a test, and the\nfirst line of each capture records the versions it was made with.\n\n<!-- facts:start svelte-headless-table pkg:@humanspeak/svelte-headless-table -->\n> **Facts, checked 12 Sep 2026.** `svelte-headless-table` 0.18.3, MIT, last published 28 Oct 2024, 90,100 npm downloads in the 30 days to 10 Sep 2026. `@humanspeak/svelte-headless-table` 6.2.0, MIT, last published 27 Aug 2026, 8,640 npm downloads in the same window. `@svgrid/grid` 3.0.3, MIT, last published 11 Sep 2026, 16,900 npm downloads in the same window. Bundle, minified and gzipped, each package built alone with Svelte external: SvGrid 3.0.4 97.6 KB JS + 10.5 KB CSS (measured 22 Sep 2026); `svelte-headless-table` 0.18.3 5.7 KB JS, no separate stylesheet, svelte external (measured 12 Sep 2026). svelte-headless-table pricing, as its site states it: svelte-headless-table is MIT and free; no paid licence or support is offered, and the author states there are no plans for a Svelte 5 port (https://github.com/bryanmylee/svelte-headless-table, read 12 Sep 2026). SvGrid: MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise. Side by side, with sources: [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/).\n<!-- facts:end -->\n\nThe short version: the install warns and goes through, the untouched component\nkeeps compiling, and the trouble starts the day you write your first rune in\nthat component. The three exits are a maintained fork, TanStack Table v9, and\nSvGrid, and they trade different things.\n\n## The component we upgraded\n\nA `PeopleTable` written the way svelte-headless-table's docs teach it: a\n`writable` over a prop, a `$:` to keep it in sync, three plugins, the view model\nread through `<Subscribe>` and `<Render>`, a pager on `pluginStates.page`, and a\n`select` event dispatched from the row.\n\n<!-- captured: fixture/svelte4/PeopleTable.svelte -->\n```svelte\n<script lang=\"ts\">\n // The table as svelte-headless-table's own docs show it: a store for the\n // data, plugins for behaviour, and a view model read through <Subscribe>\n // and <Render>. Svelte 4 throughout: `export let`, `$:`, a dispatcher,\n // `on:click`, and `let:` slot props.\n import { createEventDispatcher } from 'svelte'\n import { writable } from 'svelte/store'\n import { createTable, Subscribe, Render } from 'svelte-headless-table'\n import { addSortBy, addColumnFilters, addPagination } from 'svelte-headless-table/plugins'\n import type { Person } from './people'\n\n export let people: Person[] = []\n export let pageSize = 5\n\n const dispatch = createEventDispatcher<{ select: Person }>()\n\n const data = writable<Person[]>(people)\n $: data.set(people)\n\n const table = createTable(data, {\n sort: addSortBy(),\n filter: addColumnFilters(),\n page: addPagination({ initialPageSize: pageSize }),\n })\n```\n\nThe full file is 83 lines; the 40 that follow are the `<table>`, three levels\nof `<Subscribe let:...>` and a `<p>` with the pager. On the pinned Svelte 4\ntoolchain it checks clean:\n\n<!-- captured: 01-svelte4-baseline.txt -->\n```text\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\nsvelte-check found 0 errors and 0 warnings\n```\n\n## Step 1: the install warns and goes through\n\n`svelte-headless-table` declares `peerDependencies: { svelte: \"^4.0.0\" }`, and\nthat range is not going to change: the facts box above has the last release\ndate, and the project's README says there are no plans for a Svelte 5 port.\nSo what does `npm install svelte@5` do against it? On npm 11, this:\n\n<!-- captured: 02-npm-install-svelte5.txt -->\n```text\n$ npm install svelte@5.57.1\n\nadded 10 packages, removed 10 packages, and changed 2 packages in <time>\nnpm warn ERESOLVE overriding peer dependency\nnpm warn While resolving: svgrid-migration-lab@undefined\nnpm warn Found: svelte@4.2.20\nnpm warn node_modules/svelte\nnpm warn peer svelte@\"^4.0.0 || ^5.0.0-next.0\" from svelte-check@4.7.6\nnpm warn node_modules/svelte-check\nnpm warn dev svelte-check@\"4.7.6\" from the root project\nnpm warn 5 more (svelte-headless-table, svelte-keyed, svelte-render, ...)\nnpm warn\nnpm warn Could not resolve dependency:\nnpm warn peer svelte@\"^4.0.0\" from svelte-headless-table@0.18.3\nnpm warn node_modules/svelte-headless-table\nnpm warn dev svelte-headless-table@\"0.18.3\" from the root project\nnpm warn ERESOLVE overriding peer dependency\nnpm warn ERESOLVE overriding peer dependency\nnpm warn ERESOLVE overriding peer dependency\n\n(exit 0)\n```\n\nExit 0. npm 11 overrides the conflict and tells you so; older npm releases\nstopped with an `ERESOLVE` error until you added `--legacy-peer-deps`, and\npnpm prints an unmet-peer warning of its own. Either way, the peer range is a\nstatement, not a lock: the library's author is telling you it was never run\nagainst the Svelte you now have. Nothing enforces it.\n\n## Step 2: the untouched component still compiles\n\nSvelte 5 compiles Svelte 4 components in legacy mode, so `export let`, `$:`,\n`createEventDispatcher`, `on:click` and `let:` slot props all keep working\nuntil you opt a file into runes. With Svelte 5 installed and the component\nexactly as it was:\n\n<!-- captured: 03-svelte5-legacy-component.txt -->\n```text\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\nsvelte-check found 0 errors and 0 warnings\n```\n\nThis is the part the scare stories leave out. If your only goal is to be on\nSvelte 5, you can install it, keep the table exactly as it is, and ship. The\nlibrary's own components (`<Subscribe>`, `<Render>`) compile in legacy mode\ntoo.\n\n## Step 3: the first rune\n\nWhat you cannot do is make that component a runes component and keep the\ntable as it is. Port `PeopleTable` by the rules in the\n[official migration guide](https://svelte.dev/docs/svelte/v5-migration-guide):\n`export let` becomes `$props()`, `$:` becomes `$derived` and `$effect`, the\ndispatcher becomes a callback prop, `on:click` becomes `onclick`. Leave the\nsvelte-headless-table wiring alone, because the guide has nothing to say about\nit. The checker now says:\n\n<!-- captured: 04-svelte5-runes-component.txt -->\n```text\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\n<lab>\\src\\PeopleTable.svelte:19:35\nWarn: This reference only captures the initial value of `people`. Did you mean to reference it inside a closure instead?\nhttps://svelte.dev/e/state_referenced_locally (svelte)\n\n<lab>\\src\\PeopleTable.svelte:27:44\nWarn: This reference only captures the initial value of `pageSize`. Did you mean to reference it inside a closure instead?\nhttps://svelte.dev/e/state_referenced_locally (svelte)\n\n====================================\nsvelte-check found 0 errors and 2 warnings in 1 file\n```\n\nTwo warnings, no errors, and both are the same fact: the library takes a store,\nyour data is now a rune, and the `writable(people)` you built to bridge them\ncaptured the first value of `people` and nothing after. The fix is an\n`$effect` that writes the prop into the store on every change, which is what\nthe ported fixture does, and it works. It is also a bridge you now own, in\nevery component that has a table, between a reactivity model the library was\nbuilt for and the one your app is written in.\n\nThat is the actual shape of the problem. Not a red build: a component that\ncompiles, with a store-and-slot-props library bolted to a runes app by code you\nmaintain, on a package that will not move. The pieces it leans on are the ones\nSvelte 5 has deprecated: `let:` slot props and `<slot>` in favour of snippets,\nand `<svelte:component>`, which is what `<Render>` uses underneath\n(`svelte-render` 2.0.1, `PropsRenderer.svelte`, peer `svelte ^4.0.0`). They\nkeep working in legacy mode today; deprecated syntax is what the next major\nremoves, and this library will not be updated when it does.\n\n## The three ways out\n\nYou have three honest options, and you should know all of them before picking.\n\n1. **`@humanspeak/svelte-headless-table`**, a maintained fork on Svelte 5 with\n the same API. Its version, publish date and downloads are in the facts box.\n Switching is one package rename; you keep every line of markup and every\n `<Subscribe>`, and you keep the store bridge from step 3. If your table\n works and Svelte 5 is all you need, this is the cheapest exit by a wide\n margin.\n2. **TanStack Table v9.** Its Svelte adapter declares a Svelte 5 peer range and\n its state shape is runes-first, so the bridge goes away. It is still\n headless: you write and maintain the `<table>`, the virtualizer, the filter\n UI and the editors yourself. The\n [TanStack migration guide](./migrating-from-tanstack-table.md) covers the\n vocabulary.\n3. **SvGrid.** A different trade: you delete the markup and take a renderer.\n The column definitions and the plugin list carry over; the `<table>`, the\n `<Subscribe>` blocks, the pager and the store bridge do not exist any more,\n because `<SvGrid>` renders all of that. The rest of this page is what that\n looks like on the fixture above.\n\nPick 1 if the markup is fine and the library being dead does not bother you.\nPick 2 if you want the markup and a maintained engine. Pick 3 if the markup is\nthe part you are tired of.\n\n## Step 4: the codemod\n\n`npx @svgrid/migrate` ports a svelte-headless-table component to SvGrid. It\npreviews by default and only writes with `--write`, and it says what it could\nnot map instead of dropping it. On the Svelte 4 original:\n\n<!-- captured: 05-codemod.txt -->\n```text\n warning A custom `cell` renderer was found. SvGrid renders cells with a snippet, not `createRender`, so this one needs porting by hand - it is preserved as a comment.\n warning The template still reads `pageIndex`, `pageCount`, `shown` from the view model, which is gone. <SvGrid> renders its own pager and row count (`pageable`, `showPagination`), so remove that markup, or read the grid through `onApiReady` if you need the numbers.\n warning The table markup dispatched `select` from a row; that handler went with the `<tr>`. Wire it to `onRowClick={({ row }) => ...}` (or `onCellClick`) on <SvGrid>, and turn the `createEventDispatcher` into a callback prop if the component is moving to runes.\n note Column resizing, keyboard navigation and ARIA grid semantics are built into <SvGrid>; the markup that provided them is intentionally gone.\n\n1 file(s) would change, with 3 warning(s).\nRe-run with --write to apply.\n```\n\nThree warnings, each naming a thing it left for you. Write it, swap the\npackages, and check:\n\n<!-- captured: 06-after-codemod.txt -->\n```text\n$ npm install @svgrid/grid@3.0.4 --legacy-peer-deps\n\nadded 1 package in <time>\n\n(exit 0)\n\n$ npm uninstall svelte-headless-table --legacy-peer-deps\n\nremoved 4 packages in <time>\n\n(exit 0)\n\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\n<lab>\\src\\PeopleTable.svelte:31:23\nError: `$pageIndex` is an illegal variable name. To reference a global variable called `$pageIndex`, use `globalThis.$pageIndex`\nhttps://svelte.dev/e/global_reference_invalid (svelte)\n```\n\n<!-- captured: 06-after-codemod.txt -->\n```text\nsvelte-check found 9 errors and 0 warnings in 1 file\n```\n\nAll nine are the pager `<p>` the second warning named, reading `shown`,\n`$pageIndex` and `$pageCount` from a view model that no longer exists. The\ncodemod does not delete markup outside the `<table>`, because it cannot know\nwhat else is in there; it tells you what will not compile. Delete the `<p>`\n(the grid draws its own pager), turn the `select` event into a callback prop\non `onRowClick` as the third warning says, and:\n\n<!-- captured: 07-hand-edits.txt -->\n```text\n$ npx svelte-check --tsconfig ./tsconfig.json --output human --threshold warning\nsvelte-check found 0 errors and 0 warnings\n```\n\n## What you end up with\n\nThe component after the codemod and the two hand edits:\n\n<!-- captured: PeopleTable.after.svelte -->\n```svelte\n<script lang=\"ts\">\n import { SvGrid, type GridColumns } from '@svgrid/grid'\n import type { Person } from './people'\n export let people: Person[] = []\n export let pageSize = 5\n export let onselect: (person: Person) => void = () => {}\n\n const columns: GridColumns<(typeof people)[number]> = [\n {\n header: 'Name',\n field: 'name',\n },\n {\n header: 'Department',\n field: 'department',\n },\n {\n header: 'City',\n field: 'city',\n },\n {\n header: 'Salary',\n field: 'salary',\n // TODO port: cell: ({ value }) => value.toLocaleString('en-US', { style: 'currency', currency: 'USD\n },\n ]\n</script>\n\n<SvGrid data={people} {columns} sortable filterable showColumnFilters pageable pageSize={pageSize}\n onRowClick={({ row }) => onselect(row)} />\n```\n\n83 lines became 31. The `TODO port:` comment is the one thing left to do by\nhand: the currency cell becomes `format: { type: 'currency', currency: 'USD' }`\non the column, and the comment goes. There is no store, no `$:`, no\n`<Subscribe>`, no `let:`, and nothing in the file that Svelte 5 has deprecated,\nso the same component moves to runes whenever you like with the official\nmigration script and nothing else to port.\n\n## What to read next\n\n- [Migrating from svelte-headless-table](./migrating-from-svelte-headless-table.md) -\n the plugin-by-plugin mapping and what the codemod will not do\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/) -\n the side-by-side, with a source and date for every claim\n- [Migrating from TanStack Table](./migrating-from-tanstack-table.md) - exit 2 in detail\n- [Migrating from the shadcn-svelte data table](./migrating-from-shadcn-data-table.md) -\n the same codemod on the TanStack-based recipe\n- [Why headless?](../why-headless.md) - if you want to keep your own markup\n on a maintained Svelte 5 engine, `@svgrid/grid/core` is that too\n\n## Frequently asked questions\n\n### Does svelte-headless-table work with Svelte 5?\n\nIn legacy mode, yes: the install prints a peer-dependency warning and the\nuntouched component type-checks clean, as the captures above show. What does\nnot work is moving a component that uses it to runes without maintaining a\nstore bridge yourself, and the library is not going to be updated for the\ndeprecations that bridge leans on.\n\n### Is the peer dependency conflict an error?\n\nOn npm 11 it is a warning and the install exits 0; on older npm it was an\n`ERESOLVE` error until you passed `--legacy-peer-deps`; pnpm warns. It never\nstops the code from running. It tells you the library was not built against\nthe Svelte you have.\n\n### Should I just use the maintained fork?\n\nIf your table works and all you need is Svelte 5, yes, and this page says so.\nThe fork keeps the same API, so you keep the same markup and the same store\nbridge. Move to SvGrid when the markup and the bridge are what you want gone.\n\n### How much of the port does the codemod do?\n\nThe column definitions, the plugin list and the `<table>` replacement, and it\nnames what it leaves: custom cell renderers, markup outside the table that read\nthe view model, and events the rows dispatched. On the fixture that was two\nhand edits and one `format` option.\n\n### Can I rerun this myself?\n\n`node tools/migration-lab/run.mjs` in the repo. It installs the pinned Svelte 4\ntoolchain into its own folder, upgrades it, runs the codemod from the checkout,\nand rewrites the captured files; the header of each one records the versions.\nBump the pins to try a newer Svelte.\n"
|
|
5249
5249
|
},
|
|
5250
5250
|
{
|
|
5251
5251
|
"slug": "help/tailwind",
|
|
@@ -6001,7 +6001,7 @@ export const docs = [
|
|
|
6001
6001
|
"path": "docs/help/web-components/enterprise.md",
|
|
6002
6002
|
"title": "Enterprise features from the element",
|
|
6003
6003
|
"section": "help/web-components",
|
|
6004
|
-
"markdown": "# Enterprise features from the element\n\n`@svgrid/grid-wc` is MIT and complete on its own. The paid pack -\n[@svgrid/enterprise](https://svgrid.com/pricing/) - is a separate install, and\nmost of it works from a React, Vue or Angular host with no Svelte in your build.\n\nWhere the line falls is a packaging consequence, not a policy: four of the\nenterprise entry points are plain JavaScript, and the main entry pulls Svelte\ncomponents with it.\n\n## The spreadsheet as an element\n\nThe whole spreadsheet shell, ribbon and formula engine included, is its own\nelement: [`<sv-sheet>`](sv-sheet.md), from `@svgrid/enterprise/wc`, with\nReact and Vue wrappers beside it. It needs no `<sv-grid>` and no Svelte in\nthe host.\n\n## The api handle\n\nEverything here needs the grid's imperative api. The element parks it on itself\nonce the grid has mounted, and fires `apiready` at the same moment:\n\n```js\nconst grid = document.querySelector('sv-grid')\ngrid.addEventListener('apiready', () => {\n // grid.api is now the SvGridApi\n})\n```\n\nIn React the wrapper surfaces both:\n\n```tsx {nocheck}\nimport { useRef, useState } from 'react'\nimport { SvGrid, type SvGridHandle } from '@svgrid/grid-wc/react'\n\nconst ref = useRef<SvGridHandle>(null)\nconst [ready, setReady] = useState(false)\n\n<SvGrid ref={ref} data={rows} columns={columns} onApiReady={() => setReady(true)} />\n// ref.current.api - the same object `apiready` carries\n```\n\n## Works with no Svelte in your build\n\nThese four entry points are plain JavaScript. Import them from any bundler,\nincluding Angular's, and pass them the element's api.\n\n### Excel, PDF, HTML, CSV and TSV export\n\n```js\nimport { exportGrid } from '@svgrid/enterprise/export'\n\nawait exportGrid(grid.api, { format: 'xlsx', filename: 'orders' })\n```\n\n`format` takes `xlsx`, `pdf`, `html`, `csv` or `tsv`. Pass `download: false` to\nget the file back instead of saving it - useful for uploading or attaching it:\n\n```js\nconst { blob, filename, mime } = await exportGrid(grid.api, {\n format: 'pdf',\n download: false,\n})\n```\n\nCSV and TSV are already free in `@svgrid/grid`; `xlsx` and `pdf` are the paid\nformats.\n\n### Import\n\n```js\nimport { importData } from '@svgrid/enterprise/import'\n\nconst { rows, errors, total } = await importData(grid.api, {\n file, // a File, Blob, or inline CSV / TSV / JSON text\n format: 'auto', // sniffs xlsx vs text\n})\n```\n\n### Print\n\n```js\nimport { printGrid } from '@svgrid/enterprise/print'\n\nawait printGrid(grid.api, { title: 'Q3 orders', orientation: 'landscape' })\n```\n\n### Pivot model\n\n`createPivotModel` is a pure function - rows in, model out - so it needs no api\nat all, though the element's rows are the obvious input:\n\n```js\nimport { createPivotModel } from '@svgrid/enterprise/pivot'\n\nconst model = createPivotModel(grid.api.getData(), {\n rows: ['region'],\n cols: ['status'],\n values: [{ field: 'total', agg: 'sum' }],\n})\n```\n\nFeed `model.rows` and `model.columns` into a second, read-only `<sv-grid>`.\n\n## The license key\n\n```js\nimport { setLicenseKey } from '@svgrid/enterprise/license'\n\nsetLicenseKey('
|
|
6004
|
+
"markdown": "# Enterprise features from the element\n\n`@svgrid/grid-wc` is MIT and complete on its own. The paid pack -\n[@svgrid/enterprise](https://svgrid.com/pricing/) - is a separate install, and\nmost of it works from a React, Vue or Angular host with no Svelte in your build.\n\nWhere the line falls is a packaging consequence, not a policy: four of the\nenterprise entry points are plain JavaScript, and the main entry pulls Svelte\ncomponents with it.\n\n## The spreadsheet as an element\n\nThe whole spreadsheet shell, ribbon and formula engine included, is its own\nelement: [`<sv-sheet>`](sv-sheet.md), from `@svgrid/enterprise/wc`, with\nReact and Vue wrappers beside it. It needs no `<sv-grid>` and no Svelte in\nthe host.\n\n## The api handle\n\nEverything here needs the grid's imperative api. The element parks it on itself\nonce the grid has mounted, and fires `apiready` at the same moment:\n\n```js\nconst grid = document.querySelector('sv-grid')\ngrid.addEventListener('apiready', () => {\n // grid.api is now the SvGridApi\n})\n```\n\nIn React the wrapper surfaces both:\n\n```tsx {nocheck}\nimport { useRef, useState } from 'react'\nimport { SvGrid, type SvGridHandle } from '@svgrid/grid-wc/react'\n\nconst ref = useRef<SvGridHandle>(null)\nconst [ready, setReady] = useState(false)\n\n<SvGrid ref={ref} data={rows} columns={columns} onApiReady={() => setReady(true)} />\n// ref.current.api - the same object `apiready` carries\n```\n\n## Works with no Svelte in your build\n\nThese four entry points are plain JavaScript. Import them from any bundler,\nincluding Angular's, and pass them the element's api.\n\n### Excel, PDF, HTML, CSV and TSV export\n\n```js\nimport { exportGrid } from '@svgrid/enterprise/export'\n\nawait exportGrid(grid.api, { format: 'xlsx', filename: 'orders' })\n```\n\n`format` takes `xlsx`, `pdf`, `html`, `csv` or `tsv`. Pass `download: false` to\nget the file back instead of saving it - useful for uploading or attaching it:\n\n```js\nconst { blob, filename, mime } = await exportGrid(grid.api, {\n format: 'pdf',\n download: false,\n})\n```\n\nCSV and TSV are already free in `@svgrid/grid`; `xlsx` and `pdf` are the paid\nformats.\n\n### Import\n\n```js\nimport { importData } from '@svgrid/enterprise/import'\n\nconst { rows, errors, total } = await importData(grid.api, {\n file, // a File, Blob, or inline CSV / TSV / JSON text\n format: 'auto', // sniffs xlsx vs text\n})\n```\n\n### Print\n\n```js\nimport { printGrid } from '@svgrid/enterprise/print'\n\nawait printGrid(grid.api, { title: 'Q3 orders', orientation: 'landscape' })\n```\n\n### Pivot model\n\n`createPivotModel` is a pure function - rows in, model out - so it needs no api\nat all, though the element's rows are the obvious input:\n\n```js\nimport { createPivotModel } from '@svgrid/enterprise/pivot'\n\nconst model = createPivotModel(grid.api.getData(), {\n rows: ['region'],\n cols: ['status'],\n values: [{ field: 'total', agg: 'sum' }],\n})\n```\n\nFeed `model.rows` and `model.columns` into a second, read-only `<sv-grid>`.\n\n## The license key\n\n```js\nimport { setLicenseKey } from '@svgrid/enterprise/license'\n\nsetLicenseKey('YOUR-LICENSE-KEY')\n```\n\nCall it once, before the first export. With **no** key nothing breaks: the paid\nfeatures still run, the grid shows a small watermark, and the console carries a\none-time notice.\n\nA key that is not your license key (a typo, a placeholder) behaves like no key:\nthe features run with the watermark, and the console warns once that the key is\nnot valid. Nothing throws.\n\n## Needs a Svelte-aware bundler\n\nThe main entry - `@svgrid/enterprise` - imports the pack's Svelte components, so\na host that cannot compile `.svelte` files cannot import it. With Vite plus\n[`@sveltejs/vite-plugin-svelte`](https://github.com/sveltejs/vite-plugin-svelte)\nit works, and three more things become available:\n\n```js\nimport { installEnterprise, enableBoardView, enableSchedulerView } from '@svgrid/enterprise'\n\ninstallEnterprise(grid.api) // adds api.exportData / importData / print / pivot / ai\nenableBoardView() // makes the element's `board` prop render a Kanban board\nenableSchedulerView() // makes its `scheduler` prop render a calendar\n```\n\n`installEnterprise` is a convenience: it hangs the same export, import, print\nand pivot functions off the api object rather than you importing them. The board\nand scheduler views are the part you cannot get any other way, because they are\nSvelte components rendered inside the element.\n\nAngular CLI builds have no Svelte compiler, so for Angular the four entry points\nabove are the whole of what is reachable.\n\n## Summary\n\n| Feature | Any bundler | Needs a Svelte-aware build |\n| --- | --- | --- |\n| xlsx / pdf / html / csv / tsv export | ✓ | |\n| Import (xlsx / csv / tsv / json) | ✓ | |\n| Print | ✓ | |\n| Pivot model | ✓ | |\n| License key | ✓ | |\n| `installEnterprise(api)` | | ✓ |\n| Kanban board view | | ✓ |\n| Scheduler / calendar view | | ✓ |\n\nSee also [limitations](./limitations.md) for what the element itself cannot do,\nregardless of licensing.\n"
|
|
6005
6005
|
},
|
|
6006
6006
|
{
|
|
6007
6007
|
"slug": "help/web-components/frameworks",
|
|
@@ -6078,7 +6078,7 @@ export const docs = [
|
|
|
6078
6078
|
"path": "docs/legal/EULA.md",
|
|
6079
6079
|
"title": "SVGRID END USER LICENSE AGREEMENT",
|
|
6080
6080
|
"section": "Legal",
|
|
6081
|
-
"markdown": "\n# SVGRID END USER LICENSE AGREEMENT\n\nThis End User License Agreement (\"EULA\") governs your use of SvGrid. Please read\nit carefully before downloading, installing, or using any portion of the\nSoftware. By downloading, installing, or using the Software you agree to be bound\nby the terms and conditions of this EULA. If you do not agree, you are not\npermitted to use the Software or any portion of it.\n\nVersion 1.2. A PDF copy: [SvGrid-EULA.pdf](/legal/SvGrid-EULA.pdf).\n\nSvGrid is distributed in two editions under two different sets of terms:\n\n- The **Community Edition** (`@svgrid/grid`, `@svgrid/grid-wc`, `@svgrid/ui`,\n `@svgrid/mcp`, `@svgrid/migrate`, `@svgrid/create` and `@svgrid/create-studio`)\n is free and open source under the **MIT License**. Sections 2 and 3 apply to\n it.\n- The **Commercial Packages** (`@svgrid/enterprise` and `@svgrid/studio`) are\n commercial software, licensed and not sold, under the terms in Sections 4\n through 12.\n\n## 1. DEFINITIONS\n\n- **\"Software\"** means SvGrid, including its modules, components, program files,\n source code, examples, media, and documentation, as well as any portion of\n them.\n- **\"Community Edition\"** means the `@svgrid/grid`, `@svgrid/grid-wc`,\n `@svgrid/ui`, `@svgrid/mcp`, `@svgrid/migrate`, `@svgrid/create` and\n `@svgrid/create-studio` packages, and any other SvGrid package published\n under the MIT License.\n- **\"Enterprise Package\"** means the `@svgrid/enterprise` package and any other\n SvGrid package published under this commercial license.\n- **\"Spreadsheet Module\"** means the workbook, formula engine, and spreadsheet\n file-format features of the Enterprise Package, including `<SvSheet>`, the\n `<sv-sheet>` custom element, the formula evaluator, and the readers and\n writers for the `.xlsx`, `.xls`, `.ods` and `.csv` formats.\n- **\"Studio\"** means the `@svgrid/studio` package together with the Studio\n designer, code generator, and SQL data sources shipped in the Enterprise\n Package.\n- **\"Grid Edition\"** means an Enterprise license whose scope excludes the\n Spreadsheet Module and Studio.\n- **\"Suite Edition\"** means an Enterprise license whose scope includes the\n Enterprise Package in full, the Spreadsheet Module, and Studio.\n- **\"Author\"** means jQWidgets Ltd.\n- **\"Subscriber\"** means the individual or organization that has obtained a valid\n Enterprise license.\n- **\"Developer\"** means any individual who writes or modifies source code that\n imports the Enterprise Package. Read-only users and end users are not\n Developers.\n- **\"License Key\"** means a key issued by the Author that activates the\n Enterprise Package for the edition and the number of Developer seats covered\n by the Subscriber's order.\n- **\"Evaluation Key\"** means a time-limited key issued by the Author under\n Section 7 for the sole purpose of evaluating the Enterprise Package. An\n Evaluation Key is not a License Key.\n- **\"OEM License\"** means a separately negotiated license, described in\n Section 4A, that permits redistribution beyond the grant in Section 4(c).\n\n## 2. COMMUNITY EDITION - MIT LICENSE\n\nThe Community Edition is licensed under the MIT License. You may use, copy,\nmodify, merge, publish, distribute, sublicense, and sell copies of the Community\nEdition, including in proprietary and commercial products, free of charge,\nsubject only to the conditions of the MIT License (preservation of the copyright\nand permission notice). No License Key is required, there is no row-count cap,\nand there is no usage reporting. The full text of the MIT License is included in\nthe repository at `packages/grid/LICENSE`.\n\n## 3. COMMUNITY EDITION - NO WARRANTY\n\nThe Community Edition is provided \"as is\" under the MIT License, without warranty\nof any kind. The warranty disclaimer and limitation of liability of the MIT\nLicense apply to it.\n\n## 4. ENTERPRISE LICENSE - GRANT\n\nSubject to the Subscriber's compliance with this EULA and to continued payment of\nthe applicable license fee where an updates-and-support term is in effect, the\nAuthor grants the Subscriber a non-exclusive, non-transferable,\nnon-sublicensable license to:\n\n (a) install and use the Enterprise Package on developer workstations and in\n the Subscriber's development, staging, and production deployments;\n (b) modify the Enterprise Package for the Subscriber's internal use, provided\n that all copyright notices and license terms are preserved;\n (c) distribute the Enterprise Package bundled inside the Subscriber's own\n application, provided that the Enterprise Package is not the primary product\n distributed, that it remains under this EULA, and that the distribution is\n not one of the cases listed in Section 4A, which require an OEM License.\n\nThe scope of the license is determined by the Subscriber's order:\n\n- A **Grid Developer License** covers the Enterprise Package excluding the\n Spreadsheet Module and Studio, on an unlimited number of deployed production\n applications within the Subscriber's organization, including subsidiaries and\n sister products, plus any number of internal development and staging\n environments.\n- A **Suite Developer License** covers the Enterprise Package in full, including\n the Spreadsheet Module and Studio, on the same unlimited application scope.\n- An **Enterprise / Custom (Site or Organization-wide) License** covers the scope\n defined in the separately negotiated order or master agreement.\n- An **OEM License** covers the redistribution cases in Section 4A.\n\nUse of the Spreadsheet Module or Studio under a Grid Developer License is outside\nthe licensed scope. Consistent with Section 7, the Software does not block such\nuse: the feature runs, and the watermark and the console notice described in\nSection 7 are displayed for it. Bringing that use into scope requires a Suite\nDeveloper License.\n\n## 4A. OEM AND REDISTRIBUTION LICENSE\n\nSection 4(c) covers the ordinary case, in which the Subscriber ships its own\napplication and the Enterprise Package is one component inside it. An **OEM\nLicense**, negotiated separately with the Author, is required where any of the\nfollowing applies:\n\n (a) the Subscriber distributes the Enterprise Package, or any part of it, to\n third parties as a component, library, SDK, template, or building block\n that those third parties use to build their own applications;\n (b) the Subscriber's product is a platform, application builder, low-code or\n no-code tool, or development environment in which the Subscriber's own\n customers author applications, reports, or workbooks that render through\n the Enterprise Package;\n (c) the Subscriber sublicenses, resells, or white-labels the Enterprise\n Package under another name;\n (d) the Subscriber deploys the Enterprise Package in a multi-tenant hosted\n product in which the Spreadsheet Module or Studio is a material part of\n what the Subscriber's customers are paying for.\n\nAn OEM License is priced separately from Developer seats, is granted for a\ndefined term and a defined product, and may carry a redistribution volume or\nroyalty basis recorded in the order. Developer seats under Sections 4 and 5 do\nnot convey the rights in this Section, however many seats are purchased.\n\nFor the avoidance of doubt, ordinary business software that is sold to customers\nis covered by Section 4(c) and does not require an OEM License. A SaaS\napplication whose users view, edit, and export their own data in a grid or a\nworkbook is the Subscriber's own application, not redistribution. The test in\nthis Section is whether third parties receive the Enterprise Package as\nsomething they build with, not whether the Subscriber charges for its product.\n\nThe evaluation in Section 7 is granted to the party deciding whether to license\nthe Enterprise Package for itself. It does not extend through a Subscriber to\nthe Subscriber's own customers: a product described in (a) to (d) may not rely\non the unlicensed state of the Enterprise Package, on an Evaluation Key, or on\na development key as the licensing basis for what it delivers to third parties,\nand the watermark and console notice appearing in a third party's application\ndo not make that application an evaluation under Section 7. An OEM License\nnames the License Key that may be embedded in the redistributed product so\nthat its users see neither; a Developer License Key, an Evaluation Key, or a\ndevelopment key must not be embedded in or distributed with a product that\nrequires an OEM License.\n\nRequests: sales@jqwidgets.com.\n\n## 5. ENTERPRISE LICENSE - SEATS\n\nThe Enterprise Package is licensed per Developer. The number of Developer seats\nand the edition, Grid or Suite, are determined by the Subscriber's order. All\nseats on one order share one edition. Production seats and end users are\nunlimited and are not counted. One License Key activates every grid instance in\nscope; there is no per-page or per-component accounting. A seat is tied to a role,\nnot to a named individual: if a Developer leaves and is replaced, the seat\ntransfers to the replacement at no additional cost. License Keys must not be\nshared outside the Developer seats covered by the Subscriber's order.\n\n## 6. ENTERPRISE LICENSE - PERPETUAL LICENSE AND UPDATES/SUPPORT TERM\n\nThe Enterprise license is **perpetual**: the Subscriber owns the right to use the\nversions of the Enterprise Package released during a paid term forever. Each\norder includes a one (1) year term of software updates and support, which\n**renews automatically each year** at the then-current rate until cancelled. The\nSubscriber may **cancel at any time**. On cancellation or lapse of the\nupdates-and-support term:\n\n (a) every version of the Enterprise Package released during a paid term keeps\n working and keeps validating against the Subscriber's License Key;\n (b) the Subscriber stops receiving new releases and support issued after the\n paid term ends.\n\nThe Author will not disable working features of a paying or previously paying\nSubscriber.\n\n## 7. ENTERPRISE LICENSE - EVALUATION\n\nThe Author grants a 30-day evaluation period for the Enterprise Package. During\nthe evaluation, the Enterprise Package in full, including the Spreadsheet Module\nand Studio, may be installed and used without a License Key for the sole purpose\nof deciding whether to obtain an Enterprise license, on developer workstations\nand in internal development, staging and demonstration environments. Production\nuse requires a License Key.\n\nWhile the Enterprise Package is loaded without a License Key, the grid and the\nspreadsheet display a small watermark and the Software emits a console notice\nabout the Enterprise Package, and the first use of an Enterprise feature may\nshow a one-time upgrade card naming that feature. No functionality is disabled,\nand the Software does not stop working when the 30 days have passed: the\nwatermark and the notice stay until a License Key is set. Continued use after\nthe evaluation period, or any production use, without a License Key is outside\nthis EULA.\n\nOn request, the Author issues an Evaluation Key with a 30-day expiry that runs\nthe Enterprise Package in full without the watermark and the notice, so that\nstaging and demonstration deployments can be shown to evaluators as they would\nship. When the Evaluation Key expires the Software keeps running, displays the\nwatermark again, and emits a console notice naming the expiry date; nothing in a\ndeployed application breaks. An Evaluation Key must not be used in production,\nshared outside the evaluating organization, or embedded in a product\ndistributed to third parties. Any development key published by the Author for\nlocal development and testing is subject to the same limits.\n\nThe same mechanism applies to a feature outside a Subscriber's edition. A Grid\nDeveloper License that reaches the Spreadsheet Module or Studio is treated as\nunlicensed for that feature: the feature runs, and the watermark and a console\nnotice naming the covering edition stay until the license is upgraded. The\nAuthor does not disable a feature that is already running in a Subscriber's\napplication.\n\n## 8. ENTERPRISE LICENSE - OPEN SOURCE PROJECTS\n\nThe Author issues a free Enterprise License Key for projects that are open source\nunder an OSI-approved license, hosted in a public repository, and are not a paid\nproduct. Such keys are issued at the Suite Edition, provide the full Enterprise\nfeature set with no watermark, and are renewable annually for as long as the\nproject remains open source. Requests\nare made to the Author with the repository URL.\n\n## 9. ENTERPRISE LICENSE - LICENSE KEY AND VALIDATION\n\nLicense Key validation is performed entirely client-side. No network call is made\nto validate a License Key, and no telemetry is sent. Air-gapped deployments are\nsupported.\n\nThe check is deliberately not a cryptographic one. The Software classifies the\nkey string: whether it carries the Author's prefix, which edition it names,\nwhether it appears on the Author's revoked list, whether it is a development or\nevaluation sentinel, and any expiry date the key encodes. It does nothing more.\nA key can be read out of a deployed bundle by anyone with developer tools, and an\nunlicensed or out-of-edition build still runs. This is stated plainly because the\nlicense is a legal agreement and not a technical lock, and the Author would\nrather describe the mechanism accurately than imply protection that is not there.\nKeys are revocable: a key the Author revokes stops being accepted in later\nreleases.\n\nEach License Key embeds a stable identifier used only to cross-reference the\nSubscriber's order during support. The Subscriber must not remove, obscure, or\ndisable the License Key check, the watermark, or the console notice.\n\n## 10. ENTERPRISE LICENSE - RESTRICTIONS\n\nThe Subscriber may NOT:\n\n (a) redistribute the Enterprise Package as a standalone package, library, or\n component;\n (b) sublicense, rent, lease, or sell the Enterprise Package to third parties;\n (c) remove, obscure, or disable the License Key check or any copyright or\n proprietary notices;\n (d) use the Enterprise Package to develop a data-grid, table, or spreadsheet\n component product that competes with the Software for distribution to\n third parties;\n (e) share License Keys outside of the Developer seats covered by the\n Subscriber's order;\n (f) ship to production a use of the Spreadsheet Module or Studio that the\n Subscriber's edition does not cover, or a redistribution described in\n Section 4A without an OEM License.\n\n## 11. INTELLECTUAL PROPERTY\n\nAll intellectual property rights in the Enterprise Package, including patents,\ntrademarks, copyrights, and trade secret rights, are and remain the property of\nthe Author. The Enterprise Package is licensed, not sold. Purchasing a license,\nincluding a license that provides access to source code, does not transfer any\nintellectual property rights or ownership in the Software. \"SvGrid\", \"jQWidgets\",\nand \"HTMLElements\" are trademarks of the Author. All rights not expressly granted\nby this EULA are reserved. This Section does not restrict any right granted to you\nfor the Community Edition under the MIT License.\n\n## 12. THIRD-PARTY COMPONENTS\n\nThe Enterprise Package includes a vendored copy of the data-export utility from\nSmart UI / jQWidgets, redistributed under the same ownership (Copyright (c)\n2011-2026 jQWidgets). Optional peer dependencies, including `jszip` and `pdfmake`,\nare licensed by their respective authors under their own terms (MIT) and are not\nbundled into the package; you install them separately.\n\n## 13. DISCLAIMER OF WARRANTY\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THE AUTHOR DOES NOT\nWARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS OR THAT ITS OPERATION WILL\nBE UNINTERRUPTED OR ERROR FREE. YOU ASSUME RESPONSIBILITY FOR SELECTING THE\nSOFTWARE TO ACHIEVE YOUR INTENDED RESULTS AND FOR THE RESULTS OBTAINED FROM IT.\n\n## 14. LIMITATION OF LIABILITY\n\nIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, OR\nCONSEQUENTIAL DAMAGES, OR FOR ANY DAMAGES WHATSOEVER INCLUDING BUT NOT LIMITED TO\nLOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, OR LOSS OF BUSINESS INFORMATION,\nARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF ADVISED OF\nTHE POSSIBILITY OF SUCH DAMAGES. REGARDLESS OF THE FORM OF ACTION, THE AUTHOR'S\nAGGREGATE LIABILITY ARISING OUT OF OR RELATED TO THIS EULA SHALL NOT EXCEED THE\nLICENSE FEES PAID BY THE SUBSCRIBER IN THE TWELVE (12) MONTHS PRECEDING THE EVENT\nGIVING RISE TO THE CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE MAXIMUM\nEXTENT ALLOWED BY APPLICABLE LAW.\n\n## 15. TERMINATION\n\nThis EULA, with respect to the Enterprise Package, terminates automatically upon\nthe Subscriber's material breach of Sections 4, 4A, 5, 10, or 11. On termination for\nbreach, the Subscriber must cease all use of the Enterprise Package, remove it\nfrom development environments, and stop deploying new versions of any application\nthat depends on it. Existing copies already deployed to production may continue to\noperate, but no new deployments are permitted. License fees for licenses\ncancelled due to violation of this EULA are non-refundable. Any provision\nintended to survive termination will survive. Termination of the Enterprise\nlicense does not affect rights granted for the Community Edition under the MIT\nLicense.\n\n## 16. SEVERABILITY\n\nIf any provision of this EULA is held invalid or unenforceable, that provision\nwill be enforced to the maximum extent permissible and the remaining provisions\nwill remain in full force and effect.\n\n## 17. EXPORT REGULATIONS\n\nThe Software may be subject to export or import regulations, and you agree to\ncomply strictly with all such laws and regulations.\n\n## 18. GOVERNING LAW\n\nThis EULA is governed by the laws of the jurisdiction in which the Author is\nregistered, and any dispute arising out of or related to it will be handled\nthere.\n\n## 19. CONTACT\n\n- Sales and licensing: sales@jqwidgets.com\n- Support: support@jqwidgets.com\n- General: info@jqwidgets.com\n- Pricing: https://svgrid.com/pricing/\n\nEND OF AGREEMENT\n"
|
|
6081
|
+
"markdown": "\n# SVGRID END USER LICENSE AGREEMENT\n\nThis End User License Agreement (\"EULA\") governs your use of SvGrid. Please read\nit carefully before downloading, installing, or using any portion of the\nSoftware. By downloading, installing, or using the Software you agree to be bound\nby the terms and conditions of this EULA. If you do not agree, you are not\npermitted to use the Software or any portion of it.\n\nVersion 1.2. A PDF copy: [SvGrid-EULA.pdf](/legal/SvGrid-EULA.pdf).\n\nSvGrid is distributed in two editions under two different sets of terms:\n\n- The **Community Edition** (`@svgrid/grid`, `@svgrid/grid-wc`, `@svgrid/ui`,\n `@svgrid/mcp`, `@svgrid/migrate`, `@svgrid/create` and `@svgrid/create-studio`)\n is free and open source under the **MIT License**. Sections 2 and 3 apply to\n it.\n- The **Commercial Packages** (`@svgrid/enterprise` and `@svgrid/studio`) are\n commercial software, licensed and not sold, under the terms in Sections 4\n through 12.\n\n## 1. DEFINITIONS\n\n- **\"Software\"** means SvGrid, including its modules, components, program files,\n source code, examples, media, and documentation, as well as any portion of\n them.\n- **\"Community Edition\"** means the `@svgrid/grid`, `@svgrid/grid-wc`,\n `@svgrid/ui`, `@svgrid/mcp`, `@svgrid/migrate`, `@svgrid/create` and\n `@svgrid/create-studio` packages, and any other SvGrid package published\n under the MIT License.\n- **\"Enterprise Package\"** means the `@svgrid/enterprise` package and any other\n SvGrid package published under this commercial license.\n- **\"Spreadsheet Module\"** means the workbook, formula engine, and spreadsheet\n file-format features of the Enterprise Package, including `<SvSheet>`, the\n `<sv-sheet>` custom element, the formula evaluator, and the readers and\n writers for the `.xlsx`, `.xls`, `.ods` and `.csv` formats.\n- **\"Studio\"** means the `@svgrid/studio` package together with the Studio\n designer, code generator, and SQL data sources shipped in the Enterprise\n Package.\n- **\"Grid Edition\"** means an Enterprise license whose scope excludes the\n Spreadsheet Module and Studio.\n- **\"Suite Edition\"** means an Enterprise license whose scope includes the\n Enterprise Package in full, the Spreadsheet Module, and Studio.\n- **\"Author\"** means jQWidgets Ltd.\n- **\"Subscriber\"** means the individual or organization that has obtained a valid\n Enterprise license.\n- **\"Developer\"** means any individual who writes or modifies source code that\n imports the Enterprise Package. Read-only users and end users are not\n Developers.\n- **\"License Key\"** means a key issued by the Author that activates the\n Enterprise Package for the edition and the number of Developer seats covered\n by the Subscriber's order.\n- **\"Evaluation Key\"** means a time-limited key issued by the Author under\n Section 7 for the sole purpose of evaluating the Enterprise Package. An\n Evaluation Key is not a License Key.\n- **\"OEM License\"** means a separately negotiated license, described in\n Section 4A, that permits redistribution beyond the grant in Section 4(c).\n\n## 2. COMMUNITY EDITION - MIT LICENSE\n\nThe Community Edition is licensed under the MIT License. You may use, copy,\nmodify, merge, publish, distribute, sublicense, and sell copies of the Community\nEdition, including in proprietary and commercial products, free of charge,\nsubject only to the conditions of the MIT License (preservation of the copyright\nand permission notice). No License Key is required, there is no row-count cap,\nand there is no usage reporting. The full text of the MIT License is included in\nthe repository at `packages/grid/LICENSE`.\n\n## 3. COMMUNITY EDITION - NO WARRANTY\n\nThe Community Edition is provided \"as is\" under the MIT License, without warranty\nof any kind. The warranty disclaimer and limitation of liability of the MIT\nLicense apply to it.\n\n## 4. ENTERPRISE LICENSE - GRANT\n\nSubject to the Subscriber's compliance with this EULA and to continued payment of\nthe applicable license fee where an updates-and-support term is in effect, the\nAuthor grants the Subscriber a non-exclusive, non-transferable,\nnon-sublicensable license to:\n\n (a) install and use the Enterprise Package on developer workstations and in\n the Subscriber's development, staging, and production deployments;\n (b) modify the Enterprise Package for the Subscriber's internal use, provided\n that all copyright notices and license terms are preserved;\n (c) distribute the Enterprise Package bundled inside the Subscriber's own\n application, provided that the Enterprise Package is not the primary product\n distributed, that it remains under this EULA, and that the distribution is\n not one of the cases listed in Section 4A, which require an OEM License.\n\nThe scope of the license is determined by the Subscriber's order:\n\n- A **Grid Developer License** covers the Enterprise Package excluding the\n Spreadsheet Module and Studio, on an unlimited number of deployed production\n applications within the Subscriber's organization, including subsidiaries and\n sister products, plus any number of internal development and staging\n environments.\n- A **Suite Developer License** covers the Enterprise Package in full, including\n the Spreadsheet Module and Studio, on the same unlimited application scope.\n- An **Indie Developer License** covers the same scope as a Grid Developer\n License. It is available only to a Subscriber that is an individual working on\n their own account, or an organization whose total revenue, together with its\n affiliates, was less than one million US dollars (USD 1,000,000) in the twelve\n (12) months before the order. By placing an Indie order the Subscriber confirms\n that it meets this condition. A Subscriber that no longer meets it must move its\n seats to a Grid Developer License no later than its next renewal. An Indie\n Developer License includes no support (see Section 6).\n- An **Enterprise / Custom (Site or Organization-wide) License** covers the scope\n defined in the separately negotiated order or master agreement.\n- An **OEM License** covers the redistribution cases in Section 4A.\n\nUse of the Spreadsheet Module or Studio under a Grid Developer License or an\nIndie Developer License is outside the licensed scope. The License Key does not\ndistinguish editions (Section 9), so the Software neither blocks nor flags such\nuse; it remains outside the license, and bringing it into scope requires a\nSuite Developer License.\n\n## 4A. OEM AND REDISTRIBUTION LICENSE\n\nSection 4(c) covers the ordinary case, in which the Subscriber ships its own\napplication and the Enterprise Package is one component inside it. An **OEM\nLicense**, negotiated separately with the Author, is required where any of the\nfollowing applies:\n\n (a) the Subscriber distributes the Enterprise Package, or any part of it, to\n third parties as a component, library, SDK, template, or building block\n that those third parties use to build their own applications;\n (b) the Subscriber's product is a platform, application builder, low-code or\n no-code tool, or development environment in which the Subscriber's own\n customers author applications, reports, or workbooks that render through\n the Enterprise Package;\n (c) the Subscriber sublicenses, resells, or white-labels the Enterprise\n Package under another name;\n (d) the Subscriber deploys the Enterprise Package in a multi-tenant hosted\n product in which the Spreadsheet Module or Studio is a material part of\n what the Subscriber's customers are paying for.\n\nAn OEM License is priced separately from Developer seats, is granted for a\ndefined term and a defined product, and may carry a redistribution volume or\nroyalty basis recorded in the order. Developer seats under Sections 4 and 5 do\nnot convey the rights in this Section, however many seats are purchased.\n\nFor the avoidance of doubt, ordinary business software that is sold to customers\nis covered by Section 4(c) and does not require an OEM License. A SaaS\napplication whose users view, edit, and export their own data in a grid or a\nworkbook is the Subscriber's own application, not redistribution. The test in\nthis Section is whether third parties receive the Enterprise Package as\nsomething they build with, not whether the Subscriber charges for its product.\n\nThe evaluation in Section 7 is granted to the party deciding whether to license\nthe Enterprise Package for itself. It does not extend through a Subscriber to\nthe Subscriber's own customers: a product described in (a) to (d) may not rely\non the unlicensed state of the Enterprise Package, on an Evaluation Key, or on\na development key as the licensing basis for what it delivers to third parties,\nand the watermark and console notice appearing in a third party's application\ndo not make that application an evaluation under Section 7. An OEM License\nnames the License Key that may be embedded in the redistributed product so\nthat its users see neither; a Developer License Key, an Evaluation Key, or a\ndevelopment key must not be embedded in or distributed with a product that\nrequires an OEM License.\n\nRequests: sales@jqwidgets.com.\n\n## 5. ENTERPRISE LICENSE - SEATS\n\nThe Enterprise Package is licensed per Developer. The number of Developer seats\nand the edition, Grid or Suite, are determined by the Subscriber's order. All\nseats on one order share one edition. Production seats and end users are\nunlimited and are not counted. One License Key activates every grid instance in\nscope; there is no per-page or per-component accounting. A seat is tied to a role,\nnot to a named individual: if a Developer leaves and is replaced, the seat\ntransfers to the replacement at no additional cost. License Keys must not be\nshared outside the Developer seats covered by the Subscriber's order.\n\n## 6. ENTERPRISE LICENSE - PERPETUAL LICENSE AND UPDATES/SUPPORT TERM\n\nThe Enterprise license is **perpetual**: the Subscriber owns the right to use the\nversions of the Enterprise Package released during a paid term forever. Each\norder includes a one (1) year term of software updates and support, which\n**renews automatically each year** at the then-current rate until cancelled. The\nSubscriber may **cancel at any time**. On cancellation or lapse of the\nupdates-and-support term:\n\n (a) every version of the Enterprise Package released during a paid term keeps\n working and keeps validating against the Subscriber's License Key;\n (b) the Subscriber stops receiving new releases and support issued after the\n paid term ends.\n\nFor an Indie Developer License, the yearly term covers software updates only;\nno support is included beyond the public issue tracker.\n\nThe Author will not disable working features of a paying or previously paying\nSubscriber.\n\n## 7. ENTERPRISE LICENSE - EVALUATION\n\nThe Author grants a 30-day evaluation period for the Enterprise Package. During\nthe evaluation, the Enterprise Package in full, including the Spreadsheet Module\nand Studio, may be installed and used without a License Key for the sole purpose\nof deciding whether to obtain an Enterprise license, on developer workstations\nand in internal development, staging and demonstration environments. Production\nuse requires a License Key.\n\nWhile the Enterprise Package is loaded without a License Key, the grid and the\nspreadsheet display a small watermark and the Software emits a console notice\nabout the Enterprise Package, and the first use of an Enterprise feature may\nshow a one-time upgrade card naming that feature. No functionality is disabled,\nand the Software does not stop working when the 30 days have passed: the\nwatermark and the notice stay until a License Key is set. Continued use after\nthe evaluation period, or any production use, without a License Key is outside\nthis EULA.\n\nThe Author does not issue separate Evaluation Keys; evaluation runs without a\nkey as described above. The Author does not disable a feature that is already\nrunning in a Subscriber's application.\n\n## 8. ENTERPRISE LICENSE - OPEN SOURCE PROJECTS\n\nThe Author grants a free Enterprise license, at the Suite Edition, to projects\nthat are open source under an OSI-approved license, hosted in a public\nrepository, and are not a paid product, renewable annually for as long as the\nproject remains open source. Requests are made to the Author with the\nrepository URL. The License Key must be kept out of the public repository, for\nexample by injecting it at build time from a secret.\n\n## 9. ENTERPRISE LICENSE - LICENSE KEY AND VALIDATION\n\nLicense Key validation is performed entirely client-side. No network call is made\nto validate a License Key, and no telemetry is sent. Air-gapped deployments are\nsupported.\n\nEvery Subscriber receives the same License Key. The Software compares a SHA-256\ndigest of the key it is given with the digest of the Author's License Key, and\ndoes nothing more; it does not read an edition, a seat count or an expiry date\nfrom the key. The Subscriber's edition, seats and updates-and-support term are\nset by its order and this EULA. A key that does not match runs as unlicensed:\nthe features keep working and the watermark and the console notice show.\n\nA key can be read out of a deployed bundle by anyone with developer tools, and an\nunlicensed build still runs. This is stated plainly because the license is a\nlegal agreement and not a technical lock, and the Author would rather describe\nthe mechanism accurately than imply protection that is not there. The Author may\nreplace the License Key in a later release; versions released before the\nreplacement keep accepting the earlier key.\n\nThe Subscriber must not publish the License Key, for example in a public\nrepository, and must not remove, obscure, or disable the License Key check, the\nwatermark, or the console notice.\n\n## 10. ENTERPRISE LICENSE - RESTRICTIONS\n\nThe Subscriber may NOT:\n\n (a) redistribute the Enterprise Package as a standalone package, library, or\n component;\n (b) sublicense, rent, lease, or sell the Enterprise Package to third parties;\n (c) remove, obscure, or disable the License Key check or any copyright or\n proprietary notices;\n (d) use the Enterprise Package to develop a data-grid, table, or spreadsheet\n component product that competes with the Software for distribution to\n third parties;\n (e) share License Keys outside of the Developer seats covered by the\n Subscriber's order;\n (f) ship to production a use of the Spreadsheet Module or Studio that the\n Subscriber's edition does not cover, or a redistribution described in\n Section 4A without an OEM License.\n\n## 11. INTELLECTUAL PROPERTY\n\nAll intellectual property rights in the Enterprise Package, including patents,\ntrademarks, copyrights, and trade secret rights, are and remain the property of\nthe Author. The Enterprise Package is licensed, not sold. Purchasing a license,\nincluding a license that provides access to source code, does not transfer any\nintellectual property rights or ownership in the Software. \"SvGrid\", \"jQWidgets\",\nand \"HTMLElements\" are trademarks of the Author. All rights not expressly granted\nby this EULA are reserved. This Section does not restrict any right granted to you\nfor the Community Edition under the MIT License.\n\n## 12. THIRD-PARTY COMPONENTS\n\nThe Enterprise Package includes a vendored copy of the data-export utility from\nSmart UI / jQWidgets, redistributed under the same ownership (Copyright (c)\n2011-2026 jQWidgets). Optional peer dependencies, including `jszip` and `pdfmake`,\nare licensed by their respective authors under their own terms (MIT) and are not\nbundled into the package; you install them separately.\n\n## 13. DISCLAIMER OF WARRANTY\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THE AUTHOR DOES NOT\nWARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS OR THAT ITS OPERATION WILL\nBE UNINTERRUPTED OR ERROR FREE. YOU ASSUME RESPONSIBILITY FOR SELECTING THE\nSOFTWARE TO ACHIEVE YOUR INTENDED RESULTS AND FOR THE RESULTS OBTAINED FROM IT.\n\n## 14. LIMITATION OF LIABILITY\n\nIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, OR\nCONSEQUENTIAL DAMAGES, OR FOR ANY DAMAGES WHATSOEVER INCLUDING BUT NOT LIMITED TO\nLOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, OR LOSS OF BUSINESS INFORMATION,\nARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF ADVISED OF\nTHE POSSIBILITY OF SUCH DAMAGES. REGARDLESS OF THE FORM OF ACTION, THE AUTHOR'S\nAGGREGATE LIABILITY ARISING OUT OF OR RELATED TO THIS EULA SHALL NOT EXCEED THE\nLICENSE FEES PAID BY THE SUBSCRIBER IN THE TWELVE (12) MONTHS PRECEDING THE EVENT\nGIVING RISE TO THE CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE MAXIMUM\nEXTENT ALLOWED BY APPLICABLE LAW.\n\n## 15. TERMINATION\n\nThis EULA, with respect to the Enterprise Package, terminates automatically upon\nthe Subscriber's material breach of Sections 4, 4A, 5, 10, or 11. On termination for\nbreach, the Subscriber must cease all use of the Enterprise Package, remove it\nfrom development environments, and stop deploying new versions of any application\nthat depends on it. Existing copies already deployed to production may continue to\noperate, but no new deployments are permitted. License fees for licenses\ncancelled due to violation of this EULA are non-refundable. Any provision\nintended to survive termination will survive. Termination of the Enterprise\nlicense does not affect rights granted for the Community Edition under the MIT\nLicense.\n\n## 16. SEVERABILITY\n\nIf any provision of this EULA is held invalid or unenforceable, that provision\nwill be enforced to the maximum extent permissible and the remaining provisions\nwill remain in full force and effect.\n\n## 17. EXPORT REGULATIONS\n\nThe Software may be subject to export or import regulations, and you agree to\ncomply strictly with all such laws and regulations.\n\n## 18. GOVERNING LAW\n\nThis EULA is governed by the laws of the jurisdiction in which the Author is\nregistered, and any dispute arising out of or related to it will be handled\nthere.\n\n## 19. CONTACT\n\n- Sales and licensing: sales@jqwidgets.com\n- Support: support@jqwidgets.com\n- General: info@jqwidgets.com\n- Pricing: https://svgrid.com/pricing/\n\nEND OF AGREEMENT\n"
|
|
6082
6082
|
},
|
|
6083
6083
|
{
|
|
6084
6084
|
"slug": "recipes/autosave-with-debounce",
|
|
@@ -6897,126 +6897,126 @@ export const docs = [
|
|
|
6897
6897
|
"path": "docs/_data/comparisons/ag-grid.json",
|
|
6898
6898
|
"title": "SvGrid vs AG Grid (community + enterprise)",
|
|
6899
6899
|
"section": "Comparisons",
|
|
6900
|
-
"markdown": "# SvGrid vs AG Grid (community + enterprise)\n\nCanonical URL: https://svgrid.com/compare/ag-grid/\nFacts verified: 2026-09-12\nCompetitor package: ag-grid-community\nCompetitor site: https://www.ag-grid.com/\n\nAG Grid is the most widely used JavaScript data grid, sold for React, Angular, Vue and plain JavaScript, with Svelte covered only by community-built integrations.\n\n## Verdict\n\nAG Grid has the longer track record and the wider Enterprise catalogue; SvGrid is Svelte-5-native, smaller on a Svelte page, and puts most of what AG Grid sells as Enterprise into its MIT core. Pick AG Grid for parity with React and Angular teams; pick SvGrid for a Svelte-first stack.\n\nMigration guide: moving from AG Grid (community + enterprise) to SvGrid: https://svgrid.com/docs/help/migrating-from-ag-grid/\n\n## At a glance\n\n| Fact | SvGrid | AG Grid (community + enterprise) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 36.1.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 5 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript, React, Angular, Vue) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 12,400,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 317.5 KB JS, no separate stylesheet | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript, React, Angular, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $599 per developer per year | AG Grid Community is free under MIT. AG Grid Enterprise is listed at $999 USD per developer with one year of updates and Zendesk support; the Enterprise Bundle with AG Charts Enterprise is $1,498 USD per developer | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; ag-grid-community 36.1.0 entry `createGrid + AllCommunityModule + themeQuartz` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nAG Grid is the heavyweight of the category: a Community edition under MIT and an Enterprise edition sold per developer that adds the set filter, range selection, master/detail, tree data, row grouping, pivoting, integrated charts, Excel export and the server-side row model. Its own pages mark each of those as Enterprise, and the sources at the bottom of this page link to them.\n\nFor Svelte there is no official package. ag-grid.com names React, Angular, Vue and JavaScript and points Svelte users to community-built integrations, so in practice you call the JavaScript API from onMount and manage the DOM yourself. SvGrid is the inverse: a Svelte 5 component with runes and snippets, and a headless core underneath it.\n\n## Looking for a AG Grid alternative for Svelte?\n\nThe usual reason to look is that AG Grid on Svelte means the JavaScript API inside onMount plus a wrapper you do not control. SvGrid gives you a component that speaks runes natively and an MIT core with no row cap and no licence key. What you give up is breadth: AG Grid has more Enterprise modules, more integrations and a far larger body of examples, and if you need one grid across three frameworks it is still the right answer.\n\n## What they have in common\n\n- A full grid with sorting, filtering, grouping, virtualization, editing and selection.\n- Documentation with a runnable example per feature.\n- TypeScript-first APIs with an imperative grid API for code outside the component.\n- An MIT core plus a paid tier with support.\n- An official MCP server so AI assistants read the real docs instead of guessing.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native: runes for state, snippets for cells, no wrapper layer and no DOM imperatives.\n- A smaller bundle on a Svelte page; the At a glance table above carries both measured numbers and the method.\n- Set-style Excel filters, cell-range selection with clipboard, master/detail, tree data, row grouping with aggregation, integrated charts, the column tool panel and the context menu are in the MIT core. AG Grid lists each of these under Enterprise. Flat server-side data (paging, infinite block scroll) is free in both; the server-side row model with lazy grouping, tree, pivot, transactions and selection across unloaded rows is a paid module in both.\n- In-grid AI helpers (natural-language filter, smart fill, summarise, classify, anomalies) ship free in @svgrid/grid with your own model provider.\n- @svgrid/mcp validates props and imports against the real API surface and scaffolds a project, on top of docs and examples.\n- @svgrid/enterprise costs $599 per developer per year for the enterprise grid, unlimited applications; AG Grid Enterprise's per-developer price is in the pricing line above.\n\n## Where AG Grid (community + enterprise) is stronger\n\n- A longer production record across very large enterprise deployments, and the largest body of third-party examples and answers of any grid.\n- The viewport row model, where the server pushes the visible window over a socket; SvGrid has no equivalent.\n- AG Charts, a separately licensed charting product with far more chart types than SvGridChart.\n- One grid API across React, Angular and Vue teams.\n- Enterprise support through Zendesk with one year of updates on the licence.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | AG Grid (community + enterprise) |\n| --- | --- | --- |\n| Svelte 5 native | Yes - runes and snippets | No - JavaScript build; Svelte is pointed to community-built integrations |\n| Sorting and filtering | Yes | Yes |\n| Excel-style set filter | Yes - MIT core | Paid tier - the Set Filter page is marked Enterprise |\n| Row and column virtualization | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Cell-range selection and clipboard | Yes - MIT core, with a fill handle | Paid tier - Range Selection and Clipboard are Enterprise |\n| Master/detail | Yes - MIT core | Paid tier - Enterprise |\n| Tree data | Yes - MIT core | Paid tier - the Tree Data page is marked Enterprise |\n| Row grouping with aggregation | Yes - MIT core | Paid tier - Enterprise |\n| Pivot tables | Paid tier - @svgrid/enterprise | Paid tier - Enterprise |\n| Integrated charts | Yes - SvGridChart in the MIT core | Paid tier - Enterprise, through AG Charts |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes - MIT core: createServerDataSource, page or infinite block scroll | Yes - Infinite Row Model, Community |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise: createServerRowModel | Paid tier - Server-Side Row Model, Enterprise |\n| Global search over server-side data | Yes - filterModel.global goes to the server | No - the Quick Filter is not supported by the Infinite or Server-Side row models |\n| Viewport row model (server pushes the visible window) | No - not built; real-time deltas merge into loaded rows instead | Paid tier - Viewport Row Model, Enterprise |\n| CSV export | Yes - MIT core | Yes - Community, through the API |\n| Excel export | Paid tier - @svgrid/enterprise | Paid tier - Enterprise |\n| Column tool panel | Yes - MIT core | Paid tier - Tool Panels are Enterprise |\n| Context menu | Yes - MIT core | Paid tier - Enterprise |\n| MCP server for AI assistants | Yes - @svgrid/mcp, MIT: docs, examples, code check, scaffold, preview | Yes - ag-mcp, MIT: docs search, version detection, upgrade prompts |\n| In-grid AI helpers (natural-language filter, smart fill) | Yes - MIT core, bring your own model | No - not in the feature list |\n| Paid support | Yes - with @svgrid/enterprise, per developer per year | Yes - Enterprise licence, Zendesk |\n| Core licence | Yes - MIT | Yes - MIT (Community) |\n\n## Measured performance\n\nMeasured 12 Sep 2026 with the harness in the repository (pnpm bench:compare): 100,000 rows, fastest of 7 samples per operation, each grid in a fresh page, Chromium through Playwright, headless, on win32 10.0.26200 x64, Intel(R) Core(TM) Ultra 7 255U; a developer workstation, not a dedicated bench rig. Versions: @svgrid/grid 3.0.3, ag-grid-community 36.1.0. Lower is better.\n\n| Operation | SvGrid | AG Grid (community + enterprise) |\n| --- | --- | --- |\n| Mount | 75.5 ms | 51.4 ms |\n| Sort, text column | 149 ms | 282.8 ms |\n| Sort, numeric column | 115.7 ms | 270 ms |\n| Filter, one column (indicative only) | 99.6 ms | 170.4 ms |\n| Scroll, p95 frame | 34.6 ms | 35.9 ms |\n| Rows kept in the DOM (virtualization on) | 27 | 35 |\n\nThe filter row is not like for like: each grid is driven through its own single-column filter API, and the amount of work differs. The comparison guide explains the method, what is left out and why.\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a grid shaped by Svelte idioms rather than a wrapper around a JavaScript build.\n- You want the set filter, master/detail, tree data, range selection, grouping and flat server-side infinite scroll without an Enterprise licence.\n- You want a paid support tier priced per developer per year at $599.\n- You want an assistant that can check the code it writes against the real API, not only read the docs.\n\n## When to choose AG Grid (community + enterprise)\n\n- You depend on a specific AG Grid Enterprise module, the viewport row model or server-side pivoting.\n- You run the same grid across React, Angular and Vue teams and want one library.\n- Your procurement already covers AG Grid Enterprise, or you need AG Charts.\n- You want the largest possible pool of existing examples, answers and contractors.\n\n## Migration effort\n\nEstimated effort: 1-3 hours per grid.\n\nWhat you give up:\n\n- AG Charts as a separately licensed charting product with far more chart types than SvGridChart.\n- The viewport row model; SvGrid's server-side row model covers sort, filter, grouping, tree, pivot, transactions and select-all across unloaded rows, but the server cannot push the visible window.\n- One grid API across React, Angular and Vue teams.\n- The largest body of third-party examples, Stack Overflow answers and contractors of any grid.\n\nMigration guide: moving from AG Grid (community + enterprise) to SvGrid: https://svgrid.com/docs/help/migrating-from-ag-grid/\n\n## Live example\n\nMigration From Ag Grid: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/139-migration-from-ag-grid/\n\n## The bottom line\n\nAG Grid is the safer pick for a multi-framework organisation, or when you need its deepest Enterprise modules, AG Charts or the viewport row model. For a Svelte-first team, SvGrid covers the Enterprise surface most teams actually buy AG Grid for, in the MIT core: master/detail, tree data, range selection, grouping, flat server-side infinite scroll and integrated charts, with pivot tables, the server-side row model and Excel, PDF and print output in the @svgrid/enterprise pack. The bundle and benchmark numbers on this page are measured on the dates shown, so read them rather than either vendor's adjectives.\n\n## Frequently asked questions\n\n### Does AG Grid support Svelte?\n\nNot with an official package. ag-grid.com names React, Angular, Vue and JavaScript, and points Svelte, Solid and Python users to community-built integrations. In practice you create the grid from the JavaScript API inside onMount and keep its state in sync with your Svelte state by hand.\n\n### Which AG Grid Enterprise features does SvGrid include in its MIT core?\n\nThe set-style Excel filter, cell-range selection with clipboard, master/detail, tree data, row grouping with aggregation, integrated charts, the column tool panel and the context menu. AG Grid's own pages list each of these under Enterprise. Pivot tables, the server-side row model (grouping, tree, pivot, transactions, selection) and Excel, PDF and print output are in @svgrid/enterprise, as they are in AG Grid Enterprise; flat server-side infinite scroll is free in both.\n\n### What does SvGrid not have that AG Grid Enterprise has?\n\nThe viewport row model, AG Charts as a full charting product, and the breadth of niche Enterprise modules that come from a decade of enterprise customers. SvGrid's server-side row model handles sort, filter, grouping, tree, pivot, transactions and selection across unloaded rows; if your requirement is the viewport model, AG Grid Enterprise is the better fit.\n\n### Does AG Grid have an MCP server too?\n\nYes. ag-mcp (MIT) gives an assistant AG Grid's docs, examples and version-specific upgrade prompts. @svgrid/mcp covers the same ground for SvGrid and adds a code checker that validates props and imports against the real API surface, a scaffold tool and a preview. Neither is an in-grid feature; SvGrid's natural-language filter, smart fill and summarise helpers are, and they ship free in @svgrid/grid with your own model provider.\n\n### How much does AG Grid Enterprise cost compared with SvGrid?\n\nAG Grid Enterprise is sold per developer with one year of updates; the price as ag-grid.com listed it on the date we read it is in the pricing line at the top of this page. SvGrid's core is MIT and @svgrid/enterprise is $599 per developer per year for the enterprise grid or $999 with the spreadsheet and Studio, both for unlimited applications. Compare what each paid tier adds before comparing prices: most of what AG Grid sells as Enterprise is in SvGrid's free core.\n\n### How long does a migration from AG Grid to SvGrid take?\n\nThe migration guide budgets one to three hours per grid. Column definitions map almost one to one, the imperative API has equivalents on SvGridApi, and most of the time goes into moving cell renderers to snippets. The guide also lists what does not map, so you can decide before you start.\n\n### Is SvGrid a good AG Grid alternative for Svelte?\n\nThe usual reason to look is that AG Grid on Svelte means the JavaScript API inside onMount plus a wrapper you do not control. SvGrid gives you a component that speaks runes natively and an MIT core with no row cap and no licence key. What you give up is breadth: AG Grid has more Enterprise modules, more integrations and a far larger body of examples, and if you need one grid across three frameworks it is still the right answer.\n\n## Related comparisons and docs\n\n- [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/)\n- [SvGrid vs Handsontable](https://svgrid.com/compare/handsontable/)\n- [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Performance benchmarks](https://svgrid.com/docs/help/benchmarks/)\n- [Server-side data](https://svgrid.com/docs/help/server-side-data/)\n- [MCP server](https://svgrid.com/docs/help/mcp-server/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- ag-pricing: Enterprise is per developer at $999 USD with one year of updates and Zendesk support; the Enterprise Bundle is $1,498 USD; Community is free under MIT (checked 12 Sep 2026) https://www.ag-grid.com/license-pricing/\n- ag-community-vs-enterprise: Lists Range Selection, Clipboard, Master/Detail, Row Grouping, Pivot Tables and Aggregations, Integrated Charts, Excel export, Server-Side Row Model, Tool Panels and Context Menu under Enterprise Features; no AI feature in either list (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/community-vs-enterprise/\n- ag-set-filter: The Set Filter page is marked enterprise (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/filter-set/\n- ag-tree-data: The Tree Data page is marked enterprise (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/tree-data/\n- ag-csv-export: CSV export is available in Community through the API; the context-menu export and Excel export are Enterprise (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/csv-export/\n- ag-mcp: Official MCP server installed with npx ag-mcp: search_docs, detect_version, set_version and list_versions tools, quick-start and upgrade-grid prompts, docs and examples as resources; described as help for integrating and maintaining grid code, not an in-grid feature. The ag-mcp package on npm is MIT (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/mcp-server/\n- ag-home: Names React, Angular, Vue and JavaScript; says Svelte, Solid and Python users can use community-built integrations; the 36.1.0 release notes list an AI Coding Skill (checked 12 Sep 2026) https://www.ag-grid.com/\n- ag-row-models: The row-models feature table lists the Infinite Row Model as Community and the Server-Side and Viewport row models as Enterprise; the Quick Filter row is marked unsupported for the Infinite, Server-Side and Viewport models (checked 15 Sep 2026) https://www.ag-grid.com/javascript-data-grid/row-models/\n"
|
|
6900
|
+
"markdown": "# SvGrid vs AG Grid (community + enterprise)\n\nCanonical URL: https://svgrid.com/compare/ag-grid/\nFacts verified: 2026-09-12\nCompetitor package: ag-grid-community\nCompetitor site: https://www.ag-grid.com/\n\nAG Grid is the most widely used JavaScript data grid, sold for React, Angular, Vue and plain JavaScript, with Svelte covered only by community-built integrations.\n\n## Verdict\n\nAG Grid has the longer track record and the wider Enterprise catalogue; SvGrid is Svelte-5-native, smaller on a Svelte page, and puts most of what AG Grid sells as Enterprise into its MIT core. Pick AG Grid for parity with React and Angular teams; pick SvGrid for a Svelte-first stack.\n\nMigration guide: moving from AG Grid (community + enterprise) to SvGrid: https://svgrid.com/docs/help/migrating-from-ag-grid/\n\n## At a glance\n\n| Fact | SvGrid | AG Grid (community + enterprise) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 36.1.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 5 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript, React, Angular, Vue) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 12,400,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 317.5 KB JS, no separate stylesheet | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript, React, Angular, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | AG Grid Community is free under MIT. AG Grid Enterprise is listed at $999 USD per developer with one year of updates and Zendesk support; the Enterprise Bundle with AG Charts Enterprise is $1,498 USD per developer | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; ag-grid-community 36.1.0 entry `createGrid + AllCommunityModule + themeQuartz` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nAG Grid is the heavyweight of the category: a Community edition under MIT and an Enterprise edition sold per developer that adds the set filter, range selection, master/detail, tree data, row grouping, pivoting, integrated charts, Excel export and the server-side row model. Its own pages mark each of those as Enterprise, and the sources at the bottom of this page link to them.\n\nFor Svelte there is no official package. ag-grid.com names React, Angular, Vue and JavaScript and points Svelte users to community-built integrations, so in practice you call the JavaScript API from onMount and manage the DOM yourself. SvGrid is the inverse: a Svelte 5 component with runes and snippets, and a headless core underneath it.\n\n## Looking for a AG Grid alternative for Svelte?\n\nThe usual reason to look is that AG Grid on Svelte means the JavaScript API inside onMount plus a wrapper you do not control. SvGrid gives you a component that speaks runes natively and an MIT core with no row cap and no licence key. What you give up is breadth: AG Grid has more Enterprise modules, more integrations and a far larger body of examples, and if you need one grid across three frameworks it is still the right answer.\n\n## What they have in common\n\n- A full grid with sorting, filtering, grouping, virtualization, editing and selection.\n- Documentation with a runnable example per feature.\n- TypeScript-first APIs with an imperative grid API for code outside the component.\n- An MIT core plus a paid tier with support.\n- An official MCP server so AI assistants read the real docs instead of guessing.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native: runes for state, snippets for cells, no wrapper layer and no DOM imperatives.\n- A smaller bundle on a Svelte page; the At a glance table above carries both measured numbers and the method.\n- Set-style Excel filters, cell-range selection with clipboard, master/detail, tree data, row grouping with aggregation, integrated charts, the column tool panel and the context menu are in the MIT core. AG Grid lists each of these under Enterprise. Flat server-side data (paging, infinite block scroll) is free in both; the server-side row model with lazy grouping, tree, pivot, transactions and selection across unloaded rows is a paid module in both.\n- In-grid AI helpers (natural-language filter, smart fill, summarise, classify, anomalies) ship free in @svgrid/grid with your own model provider.\n- @svgrid/mcp validates props and imports against the real API surface and scaffolds a project, on top of docs and examples.\n- @svgrid/enterprise costs $599 per developer per year for the enterprise grid, unlimited applications; AG Grid Enterprise's per-developer price is in the pricing line above.\n\n## Where AG Grid (community + enterprise) is stronger\n\n- A longer production record across very large enterprise deployments, and the largest body of third-party examples and answers of any grid.\n- The viewport row model, where the server pushes the visible window over a socket; SvGrid has no equivalent.\n- AG Charts, a separately licensed charting product with far more chart types than SvGridChart.\n- One grid API across React, Angular and Vue teams.\n- Enterprise support through Zendesk with one year of updates on the licence.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | AG Grid (community + enterprise) |\n| --- | --- | --- |\n| Svelte 5 native | Yes - runes and snippets | No - JavaScript build; Svelte is pointed to community-built integrations |\n| Sorting and filtering | Yes | Yes |\n| Excel-style set filter | Yes - MIT core | Paid tier - the Set Filter page is marked Enterprise |\n| Row and column virtualization | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Cell-range selection and clipboard | Yes - MIT core, with a fill handle | Paid tier - Range Selection and Clipboard are Enterprise |\n| Master/detail | Yes - MIT core | Paid tier - Enterprise |\n| Tree data | Yes - MIT core | Paid tier - the Tree Data page is marked Enterprise |\n| Row grouping with aggregation | Yes - MIT core | Paid tier - Enterprise |\n| Pivot tables | Paid tier - @svgrid/enterprise | Paid tier - Enterprise |\n| Integrated charts | Yes - SvGridChart in the MIT core | Paid tier - Enterprise, through AG Charts |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes - MIT core: createServerDataSource, page or infinite block scroll | Yes - Infinite Row Model, Community |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise: createServerRowModel | Paid tier - Server-Side Row Model, Enterprise |\n| Global search over server-side data | Yes - filterModel.global goes to the server | No - the Quick Filter is not supported by the Infinite or Server-Side row models |\n| Viewport row model (server pushes the visible window) | No - not built; real-time deltas merge into loaded rows instead | Paid tier - Viewport Row Model, Enterprise |\n| CSV export | Yes - MIT core | Yes - Community, through the API |\n| Excel export | Paid tier - @svgrid/enterprise | Paid tier - Enterprise |\n| Column tool panel | Yes - MIT core | Paid tier - Tool Panels are Enterprise |\n| Context menu | Yes - MIT core | Paid tier - Enterprise |\n| MCP server for AI assistants | Yes - @svgrid/mcp, MIT: docs, examples, code check, scaffold, preview | Yes - ag-mcp, MIT: docs search, version detection, upgrade prompts |\n| In-grid AI helpers (natural-language filter, smart fill) | Yes - MIT core, bring your own model | No - not in the feature list |\n| Paid support | Yes - with @svgrid/enterprise, per developer per year | Yes - Enterprise licence, Zendesk |\n| Core licence | Yes - MIT | Yes - MIT (Community) |\n\n## Measured performance\n\nMeasured 12 Sep 2026 with the harness in the repository (pnpm bench:compare): 100,000 rows, fastest of 7 samples per operation, each grid in a fresh page, Chromium through Playwright, headless, on win32 10.0.26200 x64, Intel(R) Core(TM) Ultra 7 255U; a developer workstation, not a dedicated bench rig. Versions: @svgrid/grid 3.0.3, ag-grid-community 36.1.0. Lower is better.\n\n| Operation | SvGrid | AG Grid (community + enterprise) |\n| --- | --- | --- |\n| Mount | 75.5 ms | 51.4 ms |\n| Sort, text column | 149 ms | 282.8 ms |\n| Sort, numeric column | 115.7 ms | 270 ms |\n| Filter, one column (indicative only) | 99.6 ms | 170.4 ms |\n| Scroll, p95 frame | 34.6 ms | 35.9 ms |\n| Rows kept in the DOM (virtualization on) | 27 | 35 |\n\nThe filter row is not like for like: each grid is driven through its own single-column filter API, and the amount of work differs. The comparison guide explains the method, what is left out and why.\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a grid shaped by Svelte idioms rather than a wrapper around a JavaScript build.\n- You want the set filter, master/detail, tree data, range selection, grouping and flat server-side infinite scroll without an Enterprise licence.\n- You want a paid support tier priced per developer per year at $599.\n- You want an assistant that can check the code it writes against the real API, not only read the docs.\n\n## When to choose AG Grid (community + enterprise)\n\n- You depend on a specific AG Grid Enterprise module, the viewport row model or server-side pivoting.\n- You run the same grid across React, Angular and Vue teams and want one library.\n- Your procurement already covers AG Grid Enterprise, or you need AG Charts.\n- You want the largest possible pool of existing examples, answers and contractors.\n\n## Migration effort\n\nEstimated effort: 1-3 hours per grid.\n\nWhat you give up:\n\n- AG Charts as a separately licensed charting product with far more chart types than SvGridChart.\n- The viewport row model; SvGrid's server-side row model covers sort, filter, grouping, tree, pivot, transactions and select-all across unloaded rows, but the server cannot push the visible window.\n- One grid API across React, Angular and Vue teams.\n- The largest body of third-party examples, Stack Overflow answers and contractors of any grid.\n\nMigration guide: moving from AG Grid (community + enterprise) to SvGrid: https://svgrid.com/docs/help/migrating-from-ag-grid/\n\n## Live example\n\nMigration From Ag Grid: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/139-migration-from-ag-grid/\n\n## The bottom line\n\nAG Grid is the safer pick for a multi-framework organisation, or when you need its deepest Enterprise modules, AG Charts or the viewport row model. For a Svelte-first team, SvGrid covers the Enterprise surface most teams actually buy AG Grid for, in the MIT core: master/detail, tree data, range selection, grouping, flat server-side infinite scroll and integrated charts, with pivot tables, the server-side row model and Excel, PDF and print output in the @svgrid/enterprise pack. The bundle and benchmark numbers on this page are measured on the dates shown, so read them rather than either vendor's adjectives.\n\n## Frequently asked questions\n\n### Does AG Grid support Svelte?\n\nNot with an official package. ag-grid.com names React, Angular, Vue and JavaScript, and points Svelte, Solid and Python users to community-built integrations. In practice you create the grid from the JavaScript API inside onMount and keep its state in sync with your Svelte state by hand.\n\n### Which AG Grid Enterprise features does SvGrid include in its MIT core?\n\nThe set-style Excel filter, cell-range selection with clipboard, master/detail, tree data, row grouping with aggregation, integrated charts, the column tool panel and the context menu. AG Grid's own pages list each of these under Enterprise. Pivot tables, the server-side row model (grouping, tree, pivot, transactions, selection) and Excel, PDF and print output are in @svgrid/enterprise, as they are in AG Grid Enterprise; flat server-side infinite scroll is free in both.\n\n### What does SvGrid not have that AG Grid Enterprise has?\n\nThe viewport row model, AG Charts as a full charting product, and the breadth of niche Enterprise modules that come from a decade of enterprise customers. SvGrid's server-side row model handles sort, filter, grouping, tree, pivot, transactions and selection across unloaded rows; if your requirement is the viewport model, AG Grid Enterprise is the better fit.\n\n### Does AG Grid have an MCP server too?\n\nYes. ag-mcp (MIT) gives an assistant AG Grid's docs, examples and version-specific upgrade prompts. @svgrid/mcp covers the same ground for SvGrid and adds a code checker that validates props and imports against the real API surface, a scaffold tool and a preview. Neither is an in-grid feature; SvGrid's natural-language filter, smart fill and summarise helpers are, and they ship free in @svgrid/grid with your own model provider.\n\n### How much does AG Grid Enterprise cost compared with SvGrid?\n\nAG Grid Enterprise is sold per developer with one year of updates; the price as ag-grid.com listed it on the date we read it is in the pricing line at the top of this page. SvGrid's core is MIT and @svgrid/enterprise is $599 per developer per year for the enterprise grid or $999 with the spreadsheet and Studio, both for unlimited applications. Compare what each paid tier adds before comparing prices: most of what AG Grid sells as Enterprise is in SvGrid's free core.\n\n### How long does a migration from AG Grid to SvGrid take?\n\nThe migration guide budgets one to three hours per grid. Column definitions map almost one to one, the imperative API has equivalents on SvGridApi, and most of the time goes into moving cell renderers to snippets. The guide also lists what does not map, so you can decide before you start.\n\n### Is SvGrid a good AG Grid alternative for Svelte?\n\nThe usual reason to look is that AG Grid on Svelte means the JavaScript API inside onMount plus a wrapper you do not control. SvGrid gives you a component that speaks runes natively and an MIT core with no row cap and no licence key. What you give up is breadth: AG Grid has more Enterprise modules, more integrations and a far larger body of examples, and if you need one grid across three frameworks it is still the right answer.\n\n## Related comparisons and docs\n\n- [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/)\n- [SvGrid vs Handsontable](https://svgrid.com/compare/handsontable/)\n- [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Performance benchmarks](https://svgrid.com/docs/help/benchmarks/)\n- [Server-side data](https://svgrid.com/docs/help/server-side-data/)\n- [MCP server](https://svgrid.com/docs/help/mcp-server/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- ag-pricing: Enterprise is per developer at $999 USD with one year of updates and Zendesk support; the Enterprise Bundle is $1,498 USD; Community is free under MIT (checked 12 Sep 2026) https://www.ag-grid.com/license-pricing/\n- ag-community-vs-enterprise: Lists Range Selection, Clipboard, Master/Detail, Row Grouping, Pivot Tables and Aggregations, Integrated Charts, Excel export, Server-Side Row Model, Tool Panels and Context Menu under Enterprise Features; no AI feature in either list (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/community-vs-enterprise/\n- ag-set-filter: The Set Filter page is marked enterprise (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/filter-set/\n- ag-tree-data: The Tree Data page is marked enterprise (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/tree-data/\n- ag-csv-export: CSV export is available in Community through the API; the context-menu export and Excel export are Enterprise (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/csv-export/\n- ag-mcp: Official MCP server installed with npx ag-mcp: search_docs, detect_version, set_version and list_versions tools, quick-start and upgrade-grid prompts, docs and examples as resources; described as help for integrating and maintaining grid code, not an in-grid feature. The ag-mcp package on npm is MIT (checked 12 Sep 2026) https://www.ag-grid.com/javascript-data-grid/mcp-server/\n- ag-home: Names React, Angular, Vue and JavaScript; says Svelte, Solid and Python users can use community-built integrations; the 36.1.0 release notes list an AI Coding Skill (checked 12 Sep 2026) https://www.ag-grid.com/\n- ag-row-models: The row-models feature table lists the Infinite Row Model as Community and the Server-Side and Viewport row models as Enterprise; the Quick Filter row is marked unsupported for the Infinite, Server-Side and Viewport models (checked 15 Sep 2026) https://www.ag-grid.com/javascript-data-grid/row-models/\n"
|
|
6901
6901
|
},
|
|
6902
6902
|
{
|
|
6903
6903
|
"slug": "compare/devextreme-datagrid",
|
|
6904
6904
|
"path": "docs/_data/comparisons/devextreme-datagrid.json",
|
|
6905
6905
|
"title": "SvGrid vs DevExtreme DataGrid (DevExpress)",
|
|
6906
6906
|
"section": "Comparisons",
|
|
6907
|
-
"markdown": "# SvGrid vs DevExtreme DataGrid (DevExpress)\n\nCanonical URL: https://svgrid.com/compare/devextreme-datagrid/\nFacts verified: 2026-09-12\nCompetitor package: devextreme\nCompetitor site: https://js.devexpress.com/Documentation/Guide/UI_Components/DataGrid/\n\nDevExtreme DataGrid is the commercial enterprise grid from DevExpress, for jQuery, React, Vue, and Angular.\n\n## Verdict\n\nDevExtreme is a deep, commercial multi-framework grid with strong vendor support. SvGrid is Svelte-5-native with an MIT core and a far lower-cost paid tier.\n\nMigration guide: moving from DevExtreme DataGrid (DevExpress) to SvGrid: https://svgrid.com/docs/help/migrating-from-devextreme/\n\n## At a glance\n\n| Fact | SvGrid | DevExtreme DataGrid (DevExpress) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 26.1.4 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 7 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript, React, Angular, Vue) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 1,180,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript, React, Angular, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6907
|
+
"markdown": "# SvGrid vs DevExtreme DataGrid (DevExpress)\n\nCanonical URL: https://svgrid.com/compare/devextreme-datagrid/\nFacts verified: 2026-09-12\nCompetitor package: devextreme\nCompetitor site: https://js.devexpress.com/Documentation/Guide/UI_Components/DataGrid/\n\nDevExtreme DataGrid is the commercial enterprise grid from DevExpress, for jQuery, React, Vue, and Angular.\n\n## Verdict\n\nDevExtreme is a deep, commercial multi-framework grid with strong vendor support. SvGrid is Svelte-5-native with an MIT core and a far lower-cost paid tier.\n\nMigration guide: moving from DevExtreme DataGrid (DevExpress) to SvGrid: https://svgrid.com/docs/help/migrating-from-devextreme/\n\n## At a glance\n\n| Fact | SvGrid | DevExtreme DataGrid (DevExpress) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 26.1.4 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 7 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript, React, Angular, Vue) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 1,180,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript, React, Angular, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | js.devexpress.com lists DevExtreme Complete at $899.99 per developer for a 12-month subscription with updates and support, renewing at $449.99; no free or non-commercial tier is shown | 12 Sep 2026 |\n\n## Overview\n\nDevExtreme DataGrid is a heavyweight commercial grid from DevExpress, available across jQuery, React, Vue, and Angular, with a very deep feature set (master/detail, grouping, summaries, export, state persistence) and professional support.\n\nSvGrid covers the common ground - sorting, Excel-style filters, grouping, virtualization, editing, master/detail, tree - as a Svelte-5-native grid with an MIT core, and adds a Enterprise pack for export / import / pivot / AI.\n\n## Looking for a DevExtreme DataGrid alternative for Svelte?\n\nDevExtreme is a broad commercial suite with no Svelte target, so this is a framework decision first. SvGrid covers the grid with a free MIT core and a paid pack for export, pivot and the board and scheduler views. If you use the DevExtreme charts, schedulers and form widgets together, replacing the grid alone leaves the rest of that suite behind.\n\n## What they have in common\n\n- Deep feature set with master/detail, grouping, and summaries.\n- Inline and batch editing.\n- Export (in SvGrid via the Enterprise pack).\n- Paid support available.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native rather than a multi-framework commercial library.\n- MIT-licensed community core.\n- Headless engine + imperative API + @svgrid/mcp.\n- Much lower-cost paid tier.\n\n## Where DevExtreme DataGrid (DevExpress) is stronger\n\n- Larger feature surface and a full component suite.\n- Multi-framework parity (jQuery / React / Vue / Angular).\n- Enterprise vendor support and long track record.\n- Built-in state persistence and a wide export feature set.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | DevExtreme DataGrid (DevExpress) |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - JavaScript core with React, Angular and Vue packages |\n| License | Yes - MIT core | Paid tier - per developer, 12-month subscription |\n| Grouping + summaries | Yes | Yes |\n| Master/detail | Yes | Yes |\n| Inline / batch editing | Yes | Yes |\n| Export | Yes - @svgrid/enterprise | Yes - Built in |\n| Headless engine | Yes | No |\n| AI / MCP integration | Yes | No |\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a native grid.\n- You want an MIT core and a lower-cost paid tier.\n- You want a headless engine and an MCP server.\n\n## When to choose DevExtreme DataGrid (DevExpress)\n\n- You need the full DevExpress suite across several frameworks.\n- You depend on its built-in state persistence and export breadth.\n- Enterprise procurement requires the DevExpress vendor relationship.\n\n## Migration effort\n\nEstimated effort: 3-6 hours per grid.\n\nWhat you give up:\n\n- The rest of the DevExtreme suite and the DevExpress .NET server-side pieces under one subscription.\n- Vendor support with a 12-month term priced into the licence.\n\nMigration guide: moving from DevExtreme DataGrid (DevExpress) to SvGrid: https://svgrid.com/docs/help/migrating-from-devextreme/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\nDevExtreme is a deep, commercial multi-framework grid with built-ins like state storing and broad export. SvGrid trades that breadth for a Svelte-native grid with an MIT core and a far lower-cost paid tier.\n\n## Frequently asked questions\n\n### SvGrid vs DevExtreme DataGrid - which for Svelte?\n\nSvGrid is the native fit for Svelte and far cheaper; DevExtreme is a commercial multi-framework suite with a larger built-in feature set.\n\n### Is SvGrid cheaper than DevExtreme?\n\nYes - MIT core and a lower-cost Enterprise tier. You give up the multi-framework reach of DevExtreme and some built-ins like stateStoring, which becomes a saved-views pattern.\n\n### Does SvGrid export like DevExtreme?\n\nYes, via @svgrid/enterprise: Excel, PDF, CSV, TSV, and HTML plus a printable view.\n\n### Is SvGrid a good DevExtreme DataGrid alternative for Svelte?\n\nDevExtreme is a broad commercial suite with no Svelte target, so this is a framework decision first. SvGrid covers the grid with a free MIT core and a paid pack for export, pivot and the board and scheduler views. If you use the DevExtreme charts, schedulers and form widgets together, replacing the grid alone leaves the rest of that suite behind.\n\n## Related comparisons and docs\n\n- [SvGrid vs Kendo UI Grid (Telerik)](https://svgrid.com/compare/kendo-ui-grid/)\n- [SvGrid vs Syncfusion Grid](https://svgrid.com/compare/syncfusion-grid/)\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Server-side data](https://svgrid.com/docs/help/server-side-data/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- dx-pricing: DevExtreme Complete $899.99 per developer, 12 months of updates and support, renewal $449.99; all pricing in US dollars; no free tier shown (checked 12 Sep 2026) https://js.devexpress.com/Buy/\n"
|
|
6908
6908
|
},
|
|
6909
6909
|
{
|
|
6910
6910
|
"slug": "compare/glide-data-grid",
|
|
6911
6911
|
"path": "docs/_data/comparisons/glide-data-grid.json",
|
|
6912
6912
|
"title": "SvGrid vs Glide Data Grid",
|
|
6913
6913
|
"section": "Comparisons",
|
|
6914
|
-
"markdown": "# SvGrid vs Glide Data Grid\n\nCanonical URL: https://svgrid.com/compare/glide-data-grid/\nFacts verified: 2026-09-12\nCompetitor package: @glideapps/glide-data-grid\nCompetitor site: https://grid.glideapps.com/\n\nGlide Data Grid is a canvas-rendered React data grid built for extreme scroll performance on very large datasets.\n\n## Verdict\n\nGlide wins on raw canvas FPS for hundreds of thousands of visible cells. SvGrid renders accessible, selectable DOM with virtualization and is Svelte-5-native - the right call for most apps.\n\nMigration guide: moving from Glide Data Grid to SvGrid: https://svgrid.com/docs/help/migrating-from-glide/\n\n## At a glance\n\n| Fact | SvGrid | Glide Data Grid | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 6.0.3 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 3 Feb 2024 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (React) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 1,180,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 71.1 KB JS + 0.2 KB CSS, lodash + marked + react + react-dom + react-responsive-carousel external | 12 Sep 2026 |\n| Frameworks | Svelte 5 | React | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6914
|
+
"markdown": "# SvGrid vs Glide Data Grid\n\nCanonical URL: https://svgrid.com/compare/glide-data-grid/\nFacts verified: 2026-09-12\nCompetitor package: @glideapps/glide-data-grid\nCompetitor site: https://grid.glideapps.com/\n\nGlide Data Grid is a canvas-rendered React data grid built for extreme scroll performance on very large datasets.\n\n## Verdict\n\nGlide wins on raw canvas FPS for hundreds of thousands of visible cells. SvGrid renders accessible, selectable DOM with virtualization and is Svelte-5-native - the right call for most apps.\n\nMigration guide: moving from Glide Data Grid to SvGrid: https://svgrid.com/docs/help/migrating-from-glide/\n\n## At a glance\n\n| Fact | SvGrid | Glide Data Grid | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 6.0.3 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 3 Feb 2024 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (React) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 1,180,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 71.1 KB JS + 0.2 KB CSS, lodash + marked + react + react-dom + react-responsive-carousel external | 12 Sep 2026 |\n| Frameworks | Svelte 5 | React | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | Glide Data Grid is MIT and, in its own words, fully free and open source; no licence is sold for the grid | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; @glideapps/glide-data-grid 6.0.3 entry `DataEditor component` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nGlide Data Grid renders to a <canvas> instead of DOM, which gives it exceptional performance on very wide, very tall datasets at the cost of standard HTML semantics. It is React-only and MIT-licensed.\n\nSvGrid renders virtualized DOM: real table semantics, WAI-ARIA roles, keyboard navigation, and selectable / indexable text. For the vast majority of apps the performance gap is invisible, and you keep accessibility and SEO-friendly markup.\n\n## Looking for a Glide Data Grid alternative for Svelte?\n\nGlide renders to canvas, which is why it is fast and also why text selection, accessibility and custom cells work differently there. SvGrid renders real DOM with virtualization, so a screen reader and browser find behave normally and a cell can be any Svelte snippet. If your bar is a million-row canvas scroll inside React, Glide is still the specialist.\n\n## What they have in common\n\n- MIT-licensed.\n- Virtualized rendering for large datasets.\n- Cell editing and custom cell content.\n- TypeScript-first.\n\n## Where SvGrid is stronger\n\n- Renders real DOM - WAI-ARIA, keyboard nav, screen-reader support, selectable text.\n- Svelte 5 native rather than React-only.\n- Excel-style filter menu, headless engine, and the imperative API out of the box.\n- @svgrid/mcp MCP server for AI assistants.\n\n## Where Glide Data Grid is stronger\n\n- Peak canvas rendering performance on hundreds of thousands of visible cells.\n- Per-pixel custom cell drawing.\n- Proven inside Glide's own product at scale.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Glide Data Grid |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - React only |\n| Rendering | Yes - Accessible DOM | Partial - canvas |\n| WAI-ARIA + keyboard | Yes | Partial - Limited (canvas) |\n| Selectable / indexable text | Yes | No - Canvas pixels |\n| Peak FPS on 200k+ visible cells | Partial - Good | Yes - Best |\n| Virtualization | Yes | Yes |\n| Excel-style filters | Yes | No - BYO |\n| AI / MCP integration | Yes | No |\n\n## When to choose SvGrid\n\n- You need accessibility, keyboard support, or selectable text.\n- You are on Svelte 5 and want a native grid.\n- You want filters, editing, and an imperative API without building them.\n\n## When to choose Glide Data Grid\n\n- You have measured a need for peak canvas FPS on 200k+ simultaneously visible cells.\n- You require per-pixel custom cell drawing.\n- Your app is React and accessibility is not a requirement.\n\n## Migration effort\n\nEstimated effort: 3-6 hours per grid.\n\nWhat you give up:\n\n- Canvas rendering throughput on very wide, very dense sheets.\n- The React ecosystem around it, including Glide Data Editor.\n\nMigration guide: moving from Glide Data Grid to SvGrid: https://svgrid.com/docs/help/migrating-from-glide/\n\n## Live example\n\nHeadless Virtual: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/187-headless-virtual/\n\n## The bottom line\n\nGlide is the right tool when you have measured a need for canvas-level FPS on hundreds of thousands of visible cells. For everyone else - and especially when accessibility, selectable text, or Svelte matter - the virtualized DOM in SvGrid is the better default.\n\n## Frequently asked questions\n\n### SvGrid vs Glide Data Grid - which should I use?\n\nUse SvGrid unless you have a measured need for canvas rendering at extreme scale. SvGrid renders accessible DOM and is Svelte-native; Glide is React-only and canvas-based.\n\n### Is Glide faster than SvGrid?\n\nAt hundreds of thousands of simultaneously visible cells, canvas rendering gives Glide higher peak FPS. For typical datasets the difference is invisible, and SvGrid virtualizes comfortably to 100k+ rows.\n\n### Does SvGrid handle accessibility better than Glide?\n\nYes. SvGrid renders real DOM with WAI-ARIA roles, keyboard navigation, and selectable text; a canvas grid like Glide cannot offer those natively.\n\n### Is SvGrid a good Glide Data Grid alternative for Svelte?\n\nGlide renders to canvas, which is why it is fast and also why text selection, accessibility and custom cells work differently there. SvGrid renders real DOM with virtualization, so a screen reader and browser find behave normally and a cell can be any Svelte snippet. If your bar is a million-row canvas scroll inside React, Glide is still the specialist.\n\n## Related comparisons and docs\n\n- [SvGrid vs React Data Grid (adazzle)](https://svgrid.com/compare/react-data-grid/)\n- [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/)\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Headless virtualization](https://svgrid.com/docs/help/headless/virtualization/)\n- [Accessibility](https://svgrid.com/docs/help/accessibility/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- glide-site: MIT, fully free and open source; a React data grid that scales to millions of rows with lazy cell rendering and native scrolling (checked 12 Sep 2026) https://grid.glideapps.com/\n- glide-readme: README explains why the grid renders on an HTML canvas; supports React 16 and later (checked 12 Sep 2026) https://github.com/glideapps/glide-data-grid\n"
|
|
6915
6915
|
},
|
|
6916
6916
|
{
|
|
6917
6917
|
"slug": "compare/gridjs",
|
|
6918
6918
|
"path": "docs/_data/comparisons/gridjs.json",
|
|
6919
6919
|
"title": "SvGrid vs Grid.js",
|
|
6920
6920
|
"section": "Comparisons",
|
|
6921
|
-
"markdown": "# SvGrid vs Grid.js\n\nCanonical URL: https://svgrid.com/compare/gridjs/\nFacts verified: 2026-09-12\nCompetitor package: gridjs\nCompetitor site: https://gridjs.io/\n\nGrid.js is a small, elegant, framework-agnostic table library focused on the essentials, MIT-licensed.\n\n## Verdict\n\nGrid.js is a lovely lightweight pick for search / sort / paginate. SvGrid is the fuller, Svelte-native grid when you need virtualization, editing, grouping, or large datasets.\n\nMigration guide: moving from Grid.js to SvGrid: https://svgrid.com/docs/help/migrating-from-gridjs/\n\n## At a glance\n\n| Fact | SvGrid | Grid.js | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 6.2.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 3 Mar 2024 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 161,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 17.8 KB JS + 2.4 KB CSS | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6921
|
+
"markdown": "# SvGrid vs Grid.js\n\nCanonical URL: https://svgrid.com/compare/gridjs/\nFacts verified: 2026-09-12\nCompetitor package: gridjs\nCompetitor site: https://gridjs.io/\n\nGrid.js is a small, elegant, framework-agnostic table library focused on the essentials, MIT-licensed.\n\n## Verdict\n\nGrid.js is a lovely lightweight pick for search / sort / paginate. SvGrid is the fuller, Svelte-native grid when you need virtualization, editing, grouping, or large datasets.\n\nMigration guide: moving from Grid.js to SvGrid: https://svgrid.com/docs/help/migrating-from-gridjs/\n\n## At a glance\n\n| Fact | SvGrid | Grid.js | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 6.2.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 3 Mar 2024 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 161,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 17.8 KB JS + 2.4 KB CSS | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | Grid.js is MIT, free and open source; no licence is sold | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; gridjs 6.2.0 entry `Grid` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nGrid.js keeps a deliberately small surface: search, sort, pagination, and basic server-side data, rendered through a tiny vanilla-JS core with framework wrappers. It is MIT-licensed and easy to learn.\n\nSvGrid trades that minimalism for depth: a Svelte-5-native render component with virtualization, an Excel-style filter menu, inline editing, grouping, tree data, and an imperative API.\n\n## Looking for a Grid.js alternative for Svelte?\n\nGrid.js is deliberately small and covers the essentials well. People outgrow it at the same points every time: virtualization for large datasets, inline editing, row grouping and server-side data. SvGrid has those, and keeps a headless core so a simple table does not have to carry the weight of the full component.\n\n## What they have in common\n\n- MIT-licensed.\n- Search, sort, and pagination out of the box.\n- Server-side data support.\n- Small, approachable API.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native instead of a vanilla core + wrapper.\n- Row + column virtualization for large datasets.\n- Excel-style filters, inline editing, grouping, tree, master/detail.\n- Headless engine + imperative API + @svgrid/mcp.\n\n## Where Grid.js is stronger\n\n- Tiny footprint if all you need is search / sort / paginate.\n- Framework-agnostic core.\n- Very fast to learn for a simple table.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Grid.js |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - vanilla JavaScript with React, Angular and Vue wrappers |\n| Search / sort / paginate | Yes | Yes |\n| Excel-style filters | Yes | No |\n| Inline editing | Yes | No |\n| Virtualization | Yes | No |\n| Grouping / tree / master-detail | Yes | No |\n| Footprint for a simple table | Partial - Larger | Yes - Tiny |\n| AI / MCP integration | Yes | No |\n\n## When to choose SvGrid\n\n- You need virtualization, editing, grouping, or tree data.\n- You are on Svelte 5 and want a native component.\n- You expect the table to grow beyond search / sort / paginate.\n\n## When to choose Grid.js\n\n- You only need search / sort / paginate over a modest dataset.\n- You want the smallest possible footprint.\n- You want a framework-agnostic drop-in.\n\n## Migration effort\n\nEstimated effort: 30 minutes to 1 hour per table.\n\nWhat you give up:\n\n- A very small library for a simple table on any page.\n- Wrappers for React, Angular and Vue.\n\nMigration guide: moving from Grid.js to SvGrid: https://svgrid.com/docs/help/migrating-from-gridjs/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\nGrid.js is a lovely minimalist table for search, sort, and paginate. When you outgrow that - virtualization, editing, grouping, tree - SvGrid is the Svelte-native grid that already covers it.\n\n## Frequently asked questions\n\n### SvGrid vs Grid.js - which should I choose?\n\nGrid.js for a small table that only needs search, sort, and paginate; SvGrid when you need virtualization, editing, Excel-style filters, or grouping.\n\n### Is SvGrid heavier than Grid.js?\n\nYes, because it does much more. For a trivial table Grid.js is lighter; for a real data grid SvGrid pays for itself.\n\n### Does SvGrid support server-side data like Grid.js?\n\nYes - externalSort and externalFilter, plus the onSortingChange and onFiltersChange events.\n\n### Is SvGrid a good Grid.js alternative for Svelte?\n\nGrid.js is deliberately small and covers the essentials well. People outgrow it at the same points every time: virtualization for large datasets, inline editing, row grouping and server-side data. SvGrid has those, and keeps a headless core so a simple table does not have to carry the weight of the full component.\n\n## Related comparisons and docs\n\n- [SvGrid vs Tabulator](https://svgrid.com/compare/tabulator/)\n- [SvGrid vs @vincjo/datatables](https://svgrid.com/compare/vincjo-datatables/)\n- [SvGrid vs Flowbite / Skeleton / shadcn-svelte tables](https://svgrid.com/compare/svelte-ui-kit-tables/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Getting started with SvGrid](https://svgrid.com/docs/getting-started/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- gridjs-site: Free and open source under MIT; works with React, Angular, Vue and vanilla JavaScript; an extensible data pipeline (checked 12 Sep 2026) https://gridjs.io/\n"
|
|
6922
6922
|
},
|
|
6923
6923
|
{
|
|
6924
6924
|
"slug": "compare/handsontable",
|
|
6925
6925
|
"path": "docs/_data/comparisons/handsontable.json",
|
|
6926
6926
|
"title": "SvGrid vs Handsontable",
|
|
6927
6927
|
"section": "Comparisons",
|
|
6928
|
-
"markdown": "# SvGrid vs Handsontable\n\nCanonical URL: https://svgrid.com/compare/handsontable/\nFacts verified: 2026-09-12\nCompetitor package: handsontable\nCompetitor site: https://handsontable.com/\n\nHandsontable is a spreadsheet-style JavaScript data grid with the HyperFormula engine, sold under a commercial licence with React, Angular and Vue wrappers.\n\n## Verdict\n\nHandsontable is the spreadsheet-in-a-page with the deepest formula engine, licensed commercially and without a Svelte build. SvGrid is MIT, Svelte-5-native, and covers the spreadsheet surface most teams need: cell ranges, a fill handle, clipboard, frozen panes, cell spans and formulas, with HyperFormula as an option when you need its function library.\n\nMigration guide: moving from Handsontable to SvGrid: https://svgrid.com/docs/help/migrating-from-handsontable/\n\n## At a glance\n\n| Fact | SvGrid | Handsontable | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 18.1.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 1 Sep 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript, React, Angular, Vue) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 1,190,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript, React, Angular, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $599 per developer per year | Handsontable's Hobby licence is free for personal, exploratory projects and cannot be used in commercial settings; handsontable.com lists Standard from $999 per developer and Priority from $1,299 per developer, with Enterprise on custom terms | 12 Sep 2026 |\n\n## Overview\n\nHandsontable models a grid as a live spreadsheet: every cell editable, copy and paste with the OS clipboard, frozen rows and columns, merged cells, nested rows, and the HyperFormula engine with roughly four hundred functions. It ships a JavaScript core with official React, Angular and Vue wrappers; handsontable.com names no Svelte package.\n\nSvGrid is Svelte-5-native and MIT. Its spreadsheet surface is built on the ordinary grid: cell-range selection, a fill handle, clipboard, freeze panes through column pinning and pinned rows, colSpan and rowSpan callbacks for merged cells, and a dependency-free formula engine for the common functions. When you need HyperFormula's library, the spreadsheet demos show it wired underneath SvGrid, so the choice of engine stays yours.\n\n## Looking for a Handsontable alternative for Svelte?\n\nIf you came for the spreadsheet behaviour, the part that matters is that cell ranges, the fill handle, clipboard round-trips, freeze panes and a formula engine are all in the free MIT package here, and the gallery has a run of spreadsheet demos built on the plain grid. Handsontable is still the deeper spreadsheet, with HyperFormula's function library and years of edge cases handled. The licence is the other half of the decision: handsontable.com's free Hobby licence excludes commercial use.\n\n## What they have in common\n\n- Editing on every cell, range selection, a fill handle and OS clipboard round-trips that keep formats and formulas.\n- Formulas with cell references, ranges and functions.\n- Frozen rows and columns, merged cells and nested (tree) rows.\n- Excel-style filters, sorting, undo and redo, a context menu.\n- Cell comments, data validation, conditional formatting and cell protection on the spreadsheet surface.\n- Virtualization on both axes, keyboard navigation and WAI-ARIA markup.\n\n## Where SvGrid is stronger\n\n- MIT core: no commercial licence, no licence key and no watermark in production.\n- Svelte 5 native, with snippets for cells and runes for state, rather than a JavaScript core behind a framework wrapper.\n- A headless engine under the component, so the same row models drive a plain table or a custom layout.\n- Row grouping with aggregation, master/detail, flat server-side data and integrated charts in the same MIT package; grouping, tree, pivot and transactions on the server are in @svgrid/enterprise.\n- In-grid AI helpers (natural-language filter, smart fill, summarise) free in @svgrid/grid, and @svgrid/mcp for assistants that write code against it.\n\n## Where Handsontable is stronger\n\n- HyperFormula: the most complete formula surface in the category, with cross-sheet references and named expressions.\n- Years of spreadsheet edge cases handled: nested headers, threaded comments, Input Messages on validation, Filter by Color.\n- Official React, Angular and Vue wrappers for a multi-framework shop.\n- Paid support with code review and a dedicated success manager on the higher plans.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Handsontable |\n| --- | --- | --- |\n| Svelte 5 native | Yes - runes and snippets | No - JavaScript core; wrappers for React, Angular and Vue only |\n| Licence for commercial use | Yes - MIT | Paid tier - the free Hobby licence excludes commercial use |\n| Inline editing on every cell | Yes | Yes |\n| Cell-range selection, fill handle, clipboard | Yes - MIT core | Yes |\n| Formulas | Partial - built-in engine for the common functions; HyperFormula optional | Yes - HyperFormula, about four hundred functions |\n| Virtualization on both axes | Yes | Yes |\n| Excel-style filters and sorting | Yes | Yes |\n| Merged cells | Yes - mergedCells prop on the grid; Merge & Center, Merge Across and Unmerge on the spreadsheet shell's ribbon | Yes |\n| Cell comments | Yes - notes prop on the grid; Review tab, Shift+F2 and the cell menu on the spreadsheet shell, one note per cell | Yes - the Comments plugin |\n| Data validation | Yes - valueParser on a column; Excel's Data Validation dialog, Stop and Warning alerts and in-cell lists on the spreadsheet shell | Yes - per-cell validators |\n| Conditional formatting | Yes - value-driven rules by column on the grid; Highlight Cells, Top/Bottom, Data Bars, Color Scales and Icon Sets over computed values on the spreadsheet shell | Partial - through custom renderers |\n| AutoFilter menus on the header row | Yes - Excel's arrows, value lists and Text or Number Filters on the spreadsheet shell | Yes - the Filters and Dropdown Menu plugins |\n| Cell protection | Yes - editable per column on the grid; Format Cells > Protection and Protect Sheet on the spreadsheet shell, no password | Yes - readOnly cell meta |\n| Excel and Sheets clipboard with formats and formulas | Yes - the spreadsheet shell reads and writes the HTML flavour Excel and Google Sheets use | Yes |\n| Frozen rows and columns | Yes - column pinning left and right, pinned top and bottom rows | Yes |\n| Nested (tree) rows | Yes | Yes |\n| Row grouping with aggregation | Yes - MIT core | No - nested rows only; no group rows with aggregates in the feature list |\n| Master/detail | Yes - MIT core | No - not in the feature list |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes - MIT core | No - not in the feature list; data is loaded by the app |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise | No - not in the feature list; data is loaded by the app |\n| CSV export | Yes - MIT core | Yes |\n| Excel export | Paid tier - @svgrid/enterprise | Yes - through the asynchronous export method |\n| Integrated charts | Yes - SvGridChart in the MIT core | No - not in the feature list |\n| Undo and redo | Yes | Yes |\n| Right-to-left layout | Yes | Yes |\n| WAI-ARIA and keyboard navigation | Yes | Yes - WCAG 2.1 AA stated |\n| In-grid AI helpers and MCP server | Yes - helpers free in @svgrid/grid; @svgrid/mcp, MIT | No - not mentioned on the site |\n\n## When to choose SvGrid\n\n- You want a spreadsheet-like grid under MIT, with no licence key.\n- You are on Svelte 5 and want a native component, not a wrapped JavaScript core.\n- The built-in formula functions cover your sheet, or you are happy to add HyperFormula yourself for the rest.\n- You also need grid features a spreadsheet does not have: grouping with aggregation, master/detail, server-side data, charts.\n\n## When to choose Handsontable\n\n- You depend on HyperFormula's full function library, cross-sheet references or named expressions as a supported feature.\n- You need the deepest merged-cell and nested-header editing and the spreadsheet edge cases that come with it.\n- You ship the same grid across React, Angular and Vue with vendor wrappers.\n- You want a paid plan with code review and a success manager.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid for typical spreadsheet workflows.\n\nWhat you give up:\n\n- HyperFormula as a first-party, supported engine; SvGrid's built-in engine covers the common functions and HyperFormula is an optional add-on you wire yourself.\n- Nested headers, threaded comments and Input Messages on validation.\n- Official React, Angular and Vue wrappers.\n- Built-in Excel export without a paid pack; SvGrid's is in @svgrid/enterprise.\n\nMigration guide: moving from Handsontable to SvGrid: https://svgrid.com/docs/help/migrating-from-handsontable/\n\n## Live example\n\nBlank Sheet: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/207-blank-sheet/\n\n## The bottom line\n\nWhen you need HyperFormula's full function library as a supported feature, or the deepest spreadsheet editing edge cases, Handsontable is hard to beat and its licence is the price of that. If you want a spreadsheet-like grid in Svelte under MIT, SvGrid covers the surface most teams use, with ranges, a fill handle, clipboard, freeze panes, merged cells and formulas, and lets you add HyperFormula when the built-in functions run out.\n\n## Frequently asked questions\n\n### Is SvGrid a free alternative to Handsontable?\n\nYes. The community core is MIT and free for commercial use with no licence key. handsontable.com's free Hobby licence is for personal, exploratory projects and cannot be used in commercial settings; the commercial plans are priced per developer and the pricing line at the top of this page quotes them as read on that date.\n\n### Does SvGrid support spreadsheet formulas like Handsontable?\n\nIt has a dependency-free formula engine for cell references, ranges, arithmetic, comparison and the common functions (SUM, AVERAGE, MIN, MAX, COUNT, COUNTIF, IF, AND, OR, ROUND, text functions, TODAY) with cycle detection. Handsontable's HyperFormula library is far deeper. When you need it, the spreadsheet demos show HyperFormula running underneath SvGrid; HyperFormula's own licence applies to that use.\n\n### Does Handsontable work with Svelte?\n\nIts JavaScript core can be created inside onMount, but handsontable.com names React, Angular and Vue as the supported frameworks and ships no Svelte wrapper. SvGrid is a Svelte 5 component.\n\n### Can SvGrid do freeze panes and merged cells?\n\nYes. Freeze panes are column pinning plus pinned top rows; merged cells come from colSpan and rowSpan callbacks on a column definition. The freeze-panes demo and the blank-sheet demo on this page are both built on the plain grid.\n\n### Which grid exports to Excel?\n\nBoth, on different terms. Handsontable's export plugin writes CSV synchronously and XLSX through its asynchronous method under the commercial licence. SvGrid exports CSV, TSV and JSON in the MIT core; Excel, PDF and styled HTML export and printing are in @svgrid/enterprise.\n\n### How long does a Handsontable to SvGrid migration take?\n\nThe migration guide budgets two to four hours per grid for typical spreadsheet workflows, plus more if the sheet leans on HyperFormula functions the built-in engine does not have. Column settings, cell types and validators map directly; the plugin hooks become props and events.\n\n### Is SvGrid a good Handsontable alternative for Svelte?\n\nIf you came for the spreadsheet behaviour, the part that matters is that cell ranges, the fill handle, clipboard round-trips, freeze panes and a formula engine are all in the free MIT package here, and the gallery has a run of spreadsheet demos built on the plain grid. Handsontable is still the deeper spreadsheet, with HyperFormula's function library and years of edge cases handled. The licence is the other half of the decision: handsontable.com's free Hobby licence excludes commercial use.\n\n## Related comparisons and docs\n\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/)\n- [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Spreadsheet formulas](https://svgrid.com/docs/help/spreadsheet-formulas/)\n- [Cell text selection](https://svgrid.com/docs/help/cells/cell-text-selection/)\n- [Data export and printing](https://svgrid.com/docs/help/export/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- hot-pricing: Hobby licence is free for personal, exploratory projects and cannot be used in commercial settings; Standard from $999 per developer, Priority from $1299 per developer, Enterprise on custom terms (checked 12 Sep 2026) https://handsontable.com/pricing\n- hot-home: Works with React, Angular and Vue, no Svelte; highlights an Excel experience with over 400 formulas, sorting, filtering, grouping, freezing, inline editing, copy and paste, undo/redo, validation, WCAG 2.1 AA, RTL and virtualization on both axes; no charts, master/detail, server-side row model, AI or MCP mentioned (checked 12 Sep 2026) https://handsontable.com/\n- hot-formulas: The formula engine is HyperFormula with about 400 built-in functions, cross-sheet references and named expressions; using HyperFormula outside a Handsontable instance needs a dedicated HyperFormula licence key (checked 12 Sep 2026) https://handsontable.com/docs/javascript-data-grid/formula-calculation/\n- hot-export: The export plugin writes CSV synchronously and XLSX through the asynchronous download method (checked 12 Sep 2026) https://handsontable.com/docs/javascript-data-grid/export-to-csv/\n"
|
|
6928
|
+
"markdown": "# SvGrid vs Handsontable\n\nCanonical URL: https://svgrid.com/compare/handsontable/\nFacts verified: 2026-09-12\nCompetitor package: handsontable\nCompetitor site: https://handsontable.com/\n\nHandsontable is a spreadsheet-style JavaScript data grid with the HyperFormula engine, sold under a commercial licence with React, Angular and Vue wrappers.\n\n## Verdict\n\nHandsontable is the spreadsheet-in-a-page with the deepest formula engine, licensed commercially and without a Svelte build. SvGrid is MIT, Svelte-5-native, and covers the spreadsheet surface most teams need: cell ranges, a fill handle, clipboard, frozen panes, cell spans and formulas, with HyperFormula as an option when you need its function library.\n\nMigration guide: moving from Handsontable to SvGrid: https://svgrid.com/docs/help/migrating-from-handsontable/\n\n## At a glance\n\n| Fact | SvGrid | Handsontable | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 18.1.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 1 Sep 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript, React, Angular, Vue) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 1,190,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript, React, Angular, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | Handsontable's Hobby licence is free for personal, exploratory projects and cannot be used in commercial settings; handsontable.com lists Standard from $999 per developer and Priority from $1,299 per developer, with Enterprise on custom terms | 12 Sep 2026 |\n\n## Overview\n\nHandsontable models a grid as a live spreadsheet: every cell editable, copy and paste with the OS clipboard, frozen rows and columns, merged cells, nested rows, and the HyperFormula engine with roughly four hundred functions. It ships a JavaScript core with official React, Angular and Vue wrappers; handsontable.com names no Svelte package.\n\nSvGrid is Svelte-5-native and MIT. Its spreadsheet surface is built on the ordinary grid: cell-range selection, a fill handle, clipboard, freeze panes through column pinning and pinned rows, colSpan and rowSpan callbacks for merged cells, and a dependency-free formula engine for the common functions. When you need HyperFormula's library, the spreadsheet demos show it wired underneath SvGrid, so the choice of engine stays yours.\n\n## Looking for a Handsontable alternative for Svelte?\n\nIf you came for the spreadsheet behaviour, the part that matters is that cell ranges, the fill handle, clipboard round-trips, freeze panes and a formula engine are all in the free MIT package here, and the gallery has a run of spreadsheet demos built on the plain grid. Handsontable is still the deeper spreadsheet, with HyperFormula's function library and years of edge cases handled. The licence is the other half of the decision: handsontable.com's free Hobby licence excludes commercial use.\n\n## What they have in common\n\n- Editing on every cell, range selection, a fill handle and OS clipboard round-trips that keep formats and formulas.\n- Formulas with cell references, ranges and functions.\n- Frozen rows and columns, merged cells and nested (tree) rows.\n- Excel-style filters, sorting, undo and redo, a context menu.\n- Cell comments, data validation, conditional formatting and cell protection on the spreadsheet surface.\n- Virtualization on both axes, keyboard navigation and WAI-ARIA markup.\n\n## Where SvGrid is stronger\n\n- MIT core: no commercial licence, no licence key and no watermark in production.\n- Svelte 5 native, with snippets for cells and runes for state, rather than a JavaScript core behind a framework wrapper.\n- A headless engine under the component, so the same row models drive a plain table or a custom layout.\n- Row grouping with aggregation, master/detail, flat server-side data and integrated charts in the same MIT package; grouping, tree, pivot and transactions on the server are in @svgrid/enterprise.\n- In-grid AI helpers (natural-language filter, smart fill, summarise) free in @svgrid/grid, and @svgrid/mcp for assistants that write code against it.\n\n## Where Handsontable is stronger\n\n- HyperFormula: the most complete formula surface in the category, with cross-sheet references and named expressions.\n- Years of spreadsheet edge cases handled: nested headers, threaded comments, Input Messages on validation, Filter by Color.\n- Official React, Angular and Vue wrappers for a multi-framework shop.\n- Paid support with code review and a dedicated success manager on the higher plans.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Handsontable |\n| --- | --- | --- |\n| Svelte 5 native | Yes - runes and snippets | No - JavaScript core; wrappers for React, Angular and Vue only |\n| Licence for commercial use | Yes - MIT | Paid tier - the free Hobby licence excludes commercial use |\n| Inline editing on every cell | Yes | Yes |\n| Cell-range selection, fill handle, clipboard | Yes - MIT core | Yes |\n| Formulas | Partial - built-in engine for the common functions; HyperFormula optional | Yes - HyperFormula, about four hundred functions |\n| Virtualization on both axes | Yes | Yes |\n| Excel-style filters and sorting | Yes | Yes |\n| Merged cells | Yes - mergedCells prop on the grid; Merge & Center, Merge Across and Unmerge on the spreadsheet shell's ribbon | Yes |\n| Cell comments | Yes - notes prop on the grid; Review tab, Shift+F2 and the cell menu on the spreadsheet shell, one note per cell | Yes - the Comments plugin |\n| Data validation | Yes - valueParser on a column; Excel's Data Validation dialog, Stop and Warning alerts and in-cell lists on the spreadsheet shell | Yes - per-cell validators |\n| Conditional formatting | Yes - value-driven rules by column on the grid; Highlight Cells, Top/Bottom, Data Bars, Color Scales and Icon Sets over computed values on the spreadsheet shell | Partial - through custom renderers |\n| AutoFilter menus on the header row | Yes - Excel's arrows, value lists and Text or Number Filters on the spreadsheet shell | Yes - the Filters and Dropdown Menu plugins |\n| Cell protection | Yes - editable per column on the grid; Format Cells > Protection and Protect Sheet on the spreadsheet shell, no password | Yes - readOnly cell meta |\n| Excel and Sheets clipboard with formats and formulas | Yes - the spreadsheet shell reads and writes the HTML flavour Excel and Google Sheets use | Yes |\n| Frozen rows and columns | Yes - column pinning left and right, pinned top and bottom rows | Yes |\n| Nested (tree) rows | Yes | Yes |\n| Row grouping with aggregation | Yes - MIT core | No - nested rows only; no group rows with aggregates in the feature list |\n| Master/detail | Yes - MIT core | No - not in the feature list |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes - MIT core | No - not in the feature list; data is loaded by the app |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise | No - not in the feature list; data is loaded by the app |\n| CSV export | Yes - MIT core | Yes |\n| Excel export | Paid tier - @svgrid/enterprise | Yes - through the asynchronous export method |\n| Integrated charts | Yes - SvGridChart in the MIT core | No - not in the feature list |\n| Undo and redo | Yes | Yes |\n| Right-to-left layout | Yes | Yes |\n| WAI-ARIA and keyboard navigation | Yes | Yes - WCAG 2.1 AA stated |\n| In-grid AI helpers and MCP server | Yes - helpers free in @svgrid/grid; @svgrid/mcp, MIT | No - not mentioned on the site |\n\n## When to choose SvGrid\n\n- You want a spreadsheet-like grid under MIT, with no licence key.\n- You are on Svelte 5 and want a native component, not a wrapped JavaScript core.\n- The built-in formula functions cover your sheet, or you are happy to add HyperFormula yourself for the rest.\n- You also need grid features a spreadsheet does not have: grouping with aggregation, master/detail, server-side data, charts.\n\n## When to choose Handsontable\n\n- You depend on HyperFormula's full function library, cross-sheet references or named expressions as a supported feature.\n- You need the deepest merged-cell and nested-header editing and the spreadsheet edge cases that come with it.\n- You ship the same grid across React, Angular and Vue with vendor wrappers.\n- You want a paid plan with code review and a success manager.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid for typical spreadsheet workflows.\n\nWhat you give up:\n\n- HyperFormula as a first-party, supported engine; SvGrid's built-in engine covers the common functions and HyperFormula is an optional add-on you wire yourself.\n- Nested headers, threaded comments and Input Messages on validation.\n- Official React, Angular and Vue wrappers.\n- Built-in Excel export without a paid pack; SvGrid's is in @svgrid/enterprise.\n\nMigration guide: moving from Handsontable to SvGrid: https://svgrid.com/docs/help/migrating-from-handsontable/\n\n## Live example\n\nBlank Sheet: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/207-blank-sheet/\n\n## The bottom line\n\nWhen you need HyperFormula's full function library as a supported feature, or the deepest spreadsheet editing edge cases, Handsontable is hard to beat and its licence is the price of that. If you want a spreadsheet-like grid in Svelte under MIT, SvGrid covers the surface most teams use, with ranges, a fill handle, clipboard, freeze panes, merged cells and formulas, and lets you add HyperFormula when the built-in functions run out.\n\n## Frequently asked questions\n\n### Is SvGrid a free alternative to Handsontable?\n\nYes. The community core is MIT and free for commercial use with no licence key. handsontable.com's free Hobby licence is for personal, exploratory projects and cannot be used in commercial settings; the commercial plans are priced per developer and the pricing line at the top of this page quotes them as read on that date.\n\n### Does SvGrid support spreadsheet formulas like Handsontable?\n\nIt has a dependency-free formula engine for cell references, ranges, arithmetic, comparison and the common functions (SUM, AVERAGE, MIN, MAX, COUNT, COUNTIF, IF, AND, OR, ROUND, text functions, TODAY) with cycle detection. Handsontable's HyperFormula library is far deeper. When you need it, the spreadsheet demos show HyperFormula running underneath SvGrid; HyperFormula's own licence applies to that use.\n\n### Does Handsontable work with Svelte?\n\nIts JavaScript core can be created inside onMount, but handsontable.com names React, Angular and Vue as the supported frameworks and ships no Svelte wrapper. SvGrid is a Svelte 5 component.\n\n### Can SvGrid do freeze panes and merged cells?\n\nYes. Freeze panes are column pinning plus pinned top rows; merged cells come from colSpan and rowSpan callbacks on a column definition. The freeze-panes demo and the blank-sheet demo on this page are both built on the plain grid.\n\n### Which grid exports to Excel?\n\nBoth, on different terms. Handsontable's export plugin writes CSV synchronously and XLSX through its asynchronous method under the commercial licence. SvGrid exports CSV, TSV and JSON in the MIT core; Excel, PDF and styled HTML export and printing are in @svgrid/enterprise.\n\n### How long does a Handsontable to SvGrid migration take?\n\nThe migration guide budgets two to four hours per grid for typical spreadsheet workflows, plus more if the sheet leans on HyperFormula functions the built-in engine does not have. Column settings, cell types and validators map directly; the plugin hooks become props and events.\n\n### Is SvGrid a good Handsontable alternative for Svelte?\n\nIf you came for the spreadsheet behaviour, the part that matters is that cell ranges, the fill handle, clipboard round-trips, freeze panes and a formula engine are all in the free MIT package here, and the gallery has a run of spreadsheet demos built on the plain grid. Handsontable is still the deeper spreadsheet, with HyperFormula's function library and years of edge cases handled. The licence is the other half of the decision: handsontable.com's free Hobby licence excludes commercial use.\n\n## Related comparisons and docs\n\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/)\n- [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Spreadsheet formulas](https://svgrid.com/docs/help/spreadsheet-formulas/)\n- [Cell text selection](https://svgrid.com/docs/help/cells/cell-text-selection/)\n- [Data export and printing](https://svgrid.com/docs/help/export/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- hot-pricing: Hobby licence is free for personal, exploratory projects and cannot be used in commercial settings; Standard from $999 per developer, Priority from $1299 per developer, Enterprise on custom terms (checked 12 Sep 2026) https://handsontable.com/pricing\n- hot-home: Works with React, Angular and Vue, no Svelte; highlights an Excel experience with over 400 formulas, sorting, filtering, grouping, freezing, inline editing, copy and paste, undo/redo, validation, WCAG 2.1 AA, RTL and virtualization on both axes; no charts, master/detail, server-side row model, AI or MCP mentioned (checked 12 Sep 2026) https://handsontable.com/\n- hot-formulas: The formula engine is HyperFormula with about 400 built-in functions, cross-sheet references and named expressions; using HyperFormula outside a Handsontable instance needs a dedicated HyperFormula licence key (checked 12 Sep 2026) https://handsontable.com/docs/javascript-data-grid/formula-calculation/\n- hot-export: The export plugin writes CSV synchronously and XLSX through the asynchronous download method (checked 12 Sep 2026) https://handsontable.com/docs/javascript-data-grid/export-to-csv/\n"
|
|
6929
6929
|
},
|
|
6930
6930
|
{
|
|
6931
6931
|
"slug": "compare/jqxgrid",
|
|
6932
6932
|
"path": "docs/_data/comparisons/jqxgrid.json",
|
|
6933
6933
|
"title": "SvGrid vs jqxGrid (jQWidgets)",
|
|
6934
6934
|
"section": "Comparisons",
|
|
6935
|
-
"markdown": "# SvGrid vs jqxGrid (jQWidgets)\n\nCanonical URL: https://svgrid.com/compare/jqxgrid/\nFacts verified: 2026-09-12\nCompetitor package: jqwidgets-scripts\nCompetitor site: https://www.jqwidgets.com/\n\njqxGrid is jQWidgets' mature, feature-complete grid for jQuery, Angular, React, and Vue - from the team that builds SvGrid.\n\n## Verdict\n\nSame team, same engineering DNA. Choose jqxGrid for jQuery / Angular / React / Vue or a multi-framework codebase; choose SvGrid for a Svelte-5-native stack with an MIT community core.\n\nMigration guide: moving from jqxGrid (jQWidgets) to SvGrid: https://svgrid.com/docs/help/migrating-from-jqxgrid/\n\n## At a glance\n\n| Fact | SvGrid | jqxGrid (jQWidgets) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 26.0.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | https://www.jqwidgets.com/license/ | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 9 Jul 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (jQuery, React, Angular, Vue) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 41,900 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | jQuery, React, Angular, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6935
|
+
"markdown": "# SvGrid vs jqxGrid (jQWidgets)\n\nCanonical URL: https://svgrid.com/compare/jqxgrid/\nFacts verified: 2026-09-12\nCompetitor package: jqwidgets-scripts\nCompetitor site: https://www.jqwidgets.com/\n\njqxGrid is jQWidgets' mature, feature-complete grid for jQuery, Angular, React, and Vue - from the team that builds SvGrid.\n\n## Verdict\n\nSame team, same engineering DNA. Choose jqxGrid for jQuery / Angular / React / Vue or a multi-framework codebase; choose SvGrid for a Svelte-5-native stack with an MIT community core.\n\nMigration guide: moving from jqxGrid (jQWidgets) to SvGrid: https://svgrid.com/docs/help/migrating-from-jqxgrid/\n\n## At a glance\n\n| Fact | SvGrid | jqxGrid (jQWidgets) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 26.0.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | https://www.jqwidgets.com/license/ | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 9 Jul 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (jQuery, React, Angular, Vue) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 41,900 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | jQuery, React, Angular, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | jqwidgets.com lists the Developer License at $499 (on sale at $399) per developer, perpetual and royalty-free with one year of updates and support, and the Team License at $1,499 for five or more developers; the free Community License excludes the Grid | 12 Sep 2026 |\n\n## Overview\n\njqxGrid is the flagship grid from jQWidgets - a deeply featured, battle-tested component used in production by 5,000+ companies including Samsung, Boeing, NVIDIA, Microsoft, Nokia, and Intel. It runs on a jQuery core with Angular, React, Vue, and Web Component integrations.\n\nSvGrid is built by the same team, specifically for Svelte 5. It inherits the engineering lineage but is rebuilt around runes and snippets, with an MIT community core - the Svelte-native member of the family rather than a competitor.\n\n## Looking for a jqxGrid alternative for Svelte?\n\nSame team, different era: jqxGrid is the jQuery-generation grid, and SvGrid is what that experience looks like rebuilt for Svelte 5 runes. Column definitions and the feature vocabulary will feel familiar, which makes the port shorter than most. jqxGrid remains the answer for jQuery, Angular and React codebases; SvGrid is the Svelte one.\n\n## What they have in common\n\n- Shared engineering lineage and feature philosophy.\n- Enterprise feature set: sorting, filtering, grouping, editing, virtualization.\n- Paid support available.\n- Long production track record behind the team.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native - runes and snippets, not a jQuery core with integrations.\n- MIT-licensed community core (jqxGrid is commercially licensed).\n- Reactive data binding and Svelte component cells.\n- A headless engine in addition to the render component.\n\n## Where jqxGrid (jQWidgets) is stronger\n\n- Multi-framework: jQuery, Angular, React, Vue from one codebase.\n- Many years of maturity and a very broad feature set.\n- A large widget library beyond the grid (charts, scheduler, inputs).\n- Established commercial support and a long enterprise track record.\n- Ships its own MCP server for AI assistants, like SvGrid.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | jqxGrid (jQWidgets) |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - jQuery core + integrations |\n| License | Yes - MIT core | Paid tier - perpetual per-developer licence; the free Community License excludes the Grid |\n| Reactive data binding | Yes - $state | Partial - Imperative source/API |\n| Sort / filter / group | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Virtualization | Yes | Yes |\n| Multi-framework | No - Svelte only | Yes - jQuery / Angular / React / Vue |\n| Headless engine | Yes | No |\n| AI / MCP server | Yes - @svgrid/mcp | Yes - jqxGrid MCP |\n\n## When to choose SvGrid\n\n- Your stack is Svelte 5 and you want an idiomatic, runes-native grid.\n- You want an MIT community core rather than a commercial license.\n- You want a headless engine and an MCP server for AI tooling.\n\n## When to choose jqxGrid (jQWidgets)\n\n- You are on jQuery, Angular, React, or Vue - or several at once.\n- You want the wider jQWidgets widget library beyond the grid.\n- You want the longest production track record from the team.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid.\n\nWhat you give up:\n\n- The jQWidgets suite for jQuery, React, Angular and Vue under one perpetual licence.\n- A perpetual licence model; @svgrid/enterprise is per developer per year.\n\nMigration guide: moving from jqxGrid (jQWidgets) to SvGrid: https://svgrid.com/docs/help/migrating-from-jqxgrid/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\njqxGrid and SvGrid come from the same team. If your stack is jQuery, Angular, React, or Vue, jqxGrid is the proven choice with a decade-plus track record. If you are building on Svelte 5, SvGrid is the native option in the family, with an MIT core and the same engineering behind it.\n\n## Frequently asked questions\n\n### Is SvGrid made by the jqxGrid team?\n\nYes - SvGrid is built by jQWidgets, the makers of jqxGrid, specifically for Svelte 5 with an MIT community core.\n\n### Should I migrate my jqxGrid app to SvGrid?\n\nOnly if you are moving it to Svelte 5. On jQuery, Angular, React, or Vue, jqxGrid remains the right tool; SvGrid is the native choice once you are on Svelte.\n\n### Do both jqxGrid and SvGrid have an MCP server?\n\nYes - both ship MCP servers so AI assistants can answer accurately about each grid.\n\n### Is SvGrid a good jqxGrid alternative for Svelte?\n\nSame team, different era: jqxGrid is the jQuery-generation grid, and SvGrid is what that experience looks like rebuilt for Svelte 5 runes. Column definitions and the feature vocabulary will feel familiar, which makes the port shorter than most. jqxGrid remains the answer for jQuery, Angular and React codebases; SvGrid is the Svelte one.\n\n## Related comparisons and docs\n\n- [SvGrid vs Smart.Grid (Smart Web Components)](https://svgrid.com/compare/smart-grid/)\n- [SvGrid vs Kendo UI Grid (Telerik)](https://svgrid.com/compare/kendo-ui-grid/)\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [MCP server](https://svgrid.com/docs/help/mcp-server/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- jqx-license: Community License free but excludes Grid, TreeGrid, PivotGrid, Scheduler, DataTable, Chart, Gantt, Editor and Kanban; Developer License $499 (sale $399) per developer, perpetual, one year of updates; Team License $1,499 for 5+ developers (checked 12 Sep 2026) https://www.jqwidgets.com/license/\n"
|
|
6936
6936
|
},
|
|
6937
6937
|
{
|
|
6938
6938
|
"slug": "compare/kendo-ui-grid",
|
|
6939
6939
|
"path": "docs/_data/comparisons/kendo-ui-grid.json",
|
|
6940
6940
|
"title": "SvGrid vs Kendo UI Grid (Telerik)",
|
|
6941
6941
|
"section": "Comparisons",
|
|
6942
|
-
"markdown": "# SvGrid vs Kendo UI Grid (Telerik)\n\nCanonical URL: https://svgrid.com/compare/kendo-ui-grid/\nFacts verified: 2026-09-12\nCompetitor package: @progress/kendo-react-grid\nCompetitor site: https://www.telerik.com/kendo-ui\n\nKendo UI Grid is the polished, commercial enterprise grid from Telerik / Progress, for jQuery, React, Vue, and Angular.\n\n## Verdict\n\nKendo is a polished enterprise suite with full vendor support - and a commercial license to match. SvGrid is Svelte-5-native with an MIT core and a paid tier at a fraction of the cost.\n\nMigration guide: moving from Kendo UI Grid (Telerik) to SvGrid: https://svgrid.com/docs/help/migrating-from-kendo-grid/\n\n## At a glance\n\n| Fact | SvGrid | Kendo UI Grid (Telerik) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 16.1.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 8 Sep 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (React, Angular, Vue, jQuery) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 385,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | React, Angular, Vue, jQuery | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6942
|
+
"markdown": "# SvGrid vs Kendo UI Grid (Telerik)\n\nCanonical URL: https://svgrid.com/compare/kendo-ui-grid/\nFacts verified: 2026-09-12\nCompetitor package: @progress/kendo-react-grid\nCompetitor site: https://www.telerik.com/kendo-ui\n\nKendo UI Grid is the polished, commercial enterprise grid from Telerik / Progress, for jQuery, React, Vue, and Angular.\n\n## Verdict\n\nKendo is a polished enterprise suite with full vendor support - and a commercial license to match. SvGrid is Svelte-5-native with an MIT core and a paid tier at a fraction of the cost.\n\nMigration guide: moving from Kendo UI Grid (Telerik) to SvGrid: https://svgrid.com/docs/help/migrating-from-kendo-grid/\n\n## At a glance\n\n| Fact | SvGrid | Kendo UI Grid (Telerik) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 16.1.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 8 Sep 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (React, Angular, Vue, jQuery) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 385,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | React, Angular, Vue, jQuery | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | telerik.com lists the Kendo UI bundle at $799, $849 or $1,299 per developer per year depending on the support tier, and KendoReact alone from $649 per developer per year; no free tier for the grid | 12 Sep 2026 |\n\n## Overview\n\nKendo UI Grid is part of the Telerik / Progress suite: a comprehensive, well-supported enterprise grid available for jQuery, React, Vue, and Angular under a commercial license, with professional support and a large component library.\n\nSvGrid targets the Svelte 5 stack with an MIT community core that already covers sorting, Excel-style filters, grouping, virtualization, editing, master/detail, and tree data - plus a paid Enterprise + support tier at a fraction of enterprise-suite pricing.\n\n## Looking for a Kendo UI Grid alternative for Svelte?\n\nKendo is a polished commercial suite with support contracts behind it, and it has no Svelte target. Teams move for the licence shape as much as the framework: an MIT core with no row cap and no key, and a paid pack only for export, pivot and the board and scheduler views. Kendo still ships far more components and a much longer support track record.\n\n## What they have in common\n\n- Full enterprise feature set: sort, filter, group, edit, virtualize.\n- Paid support tier available.\n- Mature documentation and examples.\n- TypeScript support.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native rather than a multi-framework commercial suite.\n- MIT-licensed community core - no per-developer license for the grid itself.\n- Headless engine + imperative API + @svgrid/mcp.\n- Paid support at a fraction of enterprise-suite pricing.\n- No design-system lock-in - theme via --sg-* tokens.\n\n## Where Kendo UI Grid (Telerik) is stronger\n\n- Massive component suite beyond the grid (charts, scheduler, editor).\n- Decades of enterprise track record and dedicated vendor support.\n- Parity across jQuery, React, Vue, and Angular.\n- Compliance / accessibility certifications for procurement.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Kendo UI Grid (Telerik) |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - jQuery, React, Vue and Angular packages |\n| License | Yes - MIT core | Paid tier - per developer per year, no free tier for the grid |\n| Sort / filter / group | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Virtualization | Yes | Yes |\n| Headless engine | Yes | No |\n| Paid support | Yes - $599/dev/yr | Yes - support tiers priced into the licence |\n| AI / MCP integration | Yes | No |\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a native grid.\n- You want an MIT core and a far cheaper paid support tier.\n- You do not need an entire commercial component suite.\n\n## When to choose Kendo UI Grid (Telerik)\n\n- You need the full Telerik suite across multiple frameworks.\n- Procurement requires a large vendor with certifications and SLAs.\n- You want decades of enterprise track record behind the grid.\n\n## Migration effort\n\nEstimated effort: 3-6 hours per grid.\n\nWhat you give up:\n\n- The rest of the Kendo suite in one licence: charts, schedulers, editors and the theme builder across jQuery, React, Vue and Angular.\n- Telerik support tiers with response-time commitments priced into the licence.\n\nMigration guide: moving from Kendo UI Grid (Telerik) to SvGrid: https://svgrid.com/docs/help/migrating-from-kendo-grid/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\nKendo is a polished enterprise suite with deep multi-framework support and a price to match. For a Svelte team that needs the grid - not the whole suite - SvGrid delivers the common enterprise features under an MIT core, with paid support at a fraction of the cost.\n\n## Frequently asked questions\n\n### Is SvGrid a cheaper Kendo UI Grid alternative?\n\nFor a Svelte stack, yes - the core is MIT and the paid tier is a fraction of enterprise component-suite pricing.\n\n### SvGrid vs Kendo Grid - what is the trade-off?\n\nSvGrid is Svelte-native with an MIT core; Kendo offers a huge multi-framework component suite and decades of vendor support. Choose based on whether you need the grid or the whole suite.\n\n### Does SvGrid match the Kendo grid feature set?\n\nIt covers the common enterprise surface - sorting, Excel-style filters, grouping, virtualization, editing, master/detail, tree. The Kendo edge is the wider suite and framework parity.\n\n### Is SvGrid a good Kendo UI Grid alternative for Svelte?\n\nKendo is a polished commercial suite with support contracts behind it, and it has no Svelte target. Teams move for the licence shape as much as the framework: an MIT core with no row cap and no key, and a paid pack only for export, pivot and the board and scheduler views. Kendo still ships far more components and a much longer support track record.\n\n## Related comparisons and docs\n\n- [SvGrid vs DevExtreme DataGrid (DevExpress)](https://svgrid.com/compare/devextreme-datagrid/)\n- [SvGrid vs Syncfusion Grid](https://svgrid.com/compare/syncfusion-grid/)\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Server-side data](https://svgrid.com/docs/help/server-side-data/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- kendo-pricing: Kendo UI: $799, $849 or $1,299 per developer per year by support tier, 450+ components across Angular, React, jQuery and Vue; KendoReact from $649 per developer per year; DevCraft bundles from $1,149 per developer per year (checked 12 Sep 2026) https://www.telerik.com/purchase.aspx\n"
|
|
6943
6943
|
},
|
|
6944
6944
|
{
|
|
6945
6945
|
"slug": "compare/mui-x-datagrid",
|
|
6946
6946
|
"path": "docs/_data/comparisons/mui-x-datagrid.json",
|
|
6947
6947
|
"title": "SvGrid vs MUI X DataGrid",
|
|
6948
6948
|
"section": "Comparisons",
|
|
6949
|
-
"markdown": "# SvGrid vs MUI X DataGrid\n\nCanonical URL: https://svgrid.com/compare/mui-x-datagrid/\nFacts verified: 2026-09-12\nCompetitor package: @mui/x-data-grid\nCompetitor site: https://mui.com/x/react-data-grid/\n\nMUI X DataGrid is the data grid of the Material UI ecosystem on React, split into a free Community tier and paid Pro and Premium tiers.\n\n## Verdict\n\nMUI X is the obvious pick if you are already on Material UI and React. SvGrid is Svelte-5-native, ships more in its MIT core (pinning, master/detail, tree data, grouping and cell selection are not Pro or Premium features), and carries no Material Design opinion.\n\nMigration guide: moving from MUI X DataGrid to SvGrid: https://svgrid.com/docs/help/migrating-from-mui-x/\n\n## At a glance\n\n| Fact | SvGrid | MUI X DataGrid | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 9.13.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 4 Sep 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (React) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 11,800,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 155.0 KB JS, no separate stylesheet, @emotion/react + @emotion/styled + @mui/material + @mui/system + react + react-dom external | 12 Sep 2026 |\n| Frameworks | Svelte 5 | React | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $599 per developer per year | MUI X Community is free under MIT. mui.com lists Pro at $299 per year per developer, Premium at $599 per year per developer and Enterprise at $1,399 per year per developer, with perpetual and annual licence models | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; @mui/x-data-grid 9.13.0 entry `DataGrid component` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nMUI X DataGrid is what most React teams on Material UI reach for. The Community edition is MIT and covers sorting, filtering, pagination, CSV export and row virtualization. Column pinning, column virtualization, row reordering, tree data and master/detail are Pro; row grouping, aggregation, cell selection, Excel export, pivoting and the AI assistant are Premium. Both paid tiers are sold per developer per year, and the sources below link to the pages that mark each feature.\n\nSvGrid is the inverse trade: one Svelte-5-native grid whose MIT core already includes pinning, master/detail, tree data, grouping with aggregation, cell-range selection with a fill handle, integrated charts and in-grid AI helpers you point at your own model, plus an optional @svgrid/enterprise pack for Excel, PDF and print output, import and pivot tables.\n\n## Looking for a MUI X DataGrid alternative for Svelte?\n\nMUI X DataGrid is React-only, so this is less an alternative than a port. The concepts carry over almost one to one: column definitions, a free tier and a paid tier, server-side rows, an imperative API. What does not carry over is Material Design: SvGrid is themed through CSS custom properties, so you bring your own look, and Emotion and Material UI stay out of the bundle.\n\n## What they have in common\n\n- A Community / paid split with an MIT free tier.\n- Sorting, filtering, pagination, virtualization and inline editing.\n- Server-side data through a row model the app feeds.\n- TypeScript-first with an imperative API for code outside the component.\n- An official MCP server so AI assistants read the real docs.\n- An in-grid AI assistant driven by natural language.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native: runes and snippets, not a React component behind a wrapper.\n- Column pinning, master/detail, tree data, row grouping with aggregation and cell-range selection are in the MIT core; MUI X sells them as Pro or Premium.\n- The in-grid AI helpers (natural-language filter, smart fill, summarise, classify) are free in @svgrid/grid and run against a provider you register; MUI X's AI assistant is Premium and routes prompts through MUI's hosted service unless you build your own.\n- No Material Design opinion: theme through --sg-* tokens, with no Emotion or Material UI in the bundle. The At a glance table has the measured sizes.\n- Integrated charts in the MIT core, without a separate charts package.\n\n## Where MUI X DataGrid is stronger\n\n- First-class fit if the app is already built on Material UI and React: theming, date pickers and charts share one design system.\n- Pro and Premium features are vendor-supported with priority support and guaranteed response times on the Enterprise plan.\n- A very large React community and years of production use.\n- The Premium AI assistant comes with a hosted prompt service and starter credits, so there is nothing to run yourself.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | MUI X DataGrid |\n| --- | --- | --- |\n| Svelte 5 native | Yes - runes and snippets | No - React only |\n| Sorting, filtering, pagination | Yes | Yes - Community |\n| Row virtualization | Yes | Yes - Community |\n| Column virtualization | Yes | Paid tier - Pro |\n| Column pinning | Yes - MIT core, left and right | Paid tier - Pro |\n| Row reordering by drag | Yes - MIT core | Paid tier - Pro |\n| Master/detail | Yes - MIT core | Paid tier - Pro |\n| Tree data | Yes - MIT core | Paid tier - Pro |\n| Row grouping with aggregation | Yes - MIT core | Paid tier - Premium |\n| Cell-range selection and clipboard | Yes - MIT core, with a fill handle | Paid tier - Premium |\n| CSV export | Yes - MIT core | Yes - Community |\n| Excel export | Paid tier - @svgrid/enterprise | Paid tier - Premium |\n| Pivot tables | Paid tier - @svgrid/enterprise | Paid tier - Premium |\n| Integrated charts | Yes - SvGridChart in the MIT core | Partial - MUI X Charts is a separate package |\n| In-grid AI assistant | Yes - MIT core, bring your own model | Paid tier - Premium, through MUI's hosted service or your own proxy |\n| MCP server for AI assistants | Yes - @svgrid/mcp, MIT: docs, examples, code check, scaffold, preview | Yes - @mui/mcp, free: docs and examples |\n| Inline editing | Yes | Yes - Community |\n| Design-system independence | Yes - --sg-* tokens, no UI framework dependency | Partial - Material UI, Emotion and the MUI system are peer dependencies |\n| Core licence | Yes - MIT | Yes - MIT (Community) |\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a grid shaped by runes, not a React component.\n- You want pinning, master/detail, tree data, grouping and cell selection without buying Pro or Premium.\n- You do not want Material Design, Emotion or the MUI system in your bundle.\n- You want the in-grid AI helpers to talk to a model you choose and host.\n\n## When to choose MUI X DataGrid\n\n- Your app is already built on Material UI and React.\n- You need Premium grouping, aggregation, pivoting or Excel export as vendor-supported features with a support contract.\n- You want one grid that matches React teammates across the MUI X suite, including date pickers and charts.\n- You want a hosted AI assistant with nothing to run yourself.\n\n## Migration effort\n\nEstimated effort: 1-3 hours per grid.\n\nWhat you give up:\n\n- Material Design out of the box; SvGrid ships neutral tokens and you theme it.\n- The rest of MUI X in the same design system: date pickers, charts and the tree view.\n- A hosted AI assistant with starter credits; SvGrid's helpers need a model provider you register.\n- React-specific patterns such as slots and hooks; SvGrid uses snippets and props.\n\nMigration guide: moving from MUI X DataGrid to SvGrid: https://svgrid.com/docs/help/migrating-from-mui-x/\n\n## Live example\n\nTree And Master Detail: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/08-tree-and-master-detail/\n\n## The bottom line\n\nIf your app already lives in Material UI and React, MUI X is the path of least resistance, and its Premium tier now includes a hosted AI assistant. On Svelte 5, SvGrid is the better fit: it puts pinning, master/detail, tree data, grouping and cell selection in the MIT core that MUI X reserves for Pro and Premium, keeps Material UI and Emotion out of the bundle, and runs its AI helpers against a model you choose.\n\n## Frequently asked questions\n\n### SvGrid vs MUI X DataGrid: which one for Svelte?\n\nSvGrid, if your stack is Svelte. MUI X is React-only and depends on Material UI, Emotion and the MUI system as peer dependencies; SvGrid is Svelte-5-native with no design-system dependency.\n\n### Which MUI X Pro and Premium features are free in SvGrid?\n\nColumn pinning, column virtualization, row reordering, master/detail and tree data (Pro in MUI X), and row grouping, aggregation and cell-range selection (Premium in MUI X) ship in the MIT core of SvGrid. Excel export and pivoting are paid on both sides: Premium in MUI X, @svgrid/enterprise in SvGrid.\n\n### Does MUI X have an AI assistant like SvGrid?\n\nYes, in Premium. mui.com describes a natural-language assistant (sort by name, show amounts larger than a value) that sends prompts through a proxy to MUI's hosted service with an API key, with starter credits included and the option to build your own processing service. SvGrid's natural-language filter, smart fill, summarise and classify helpers are free in @svgrid/grid and only run against a model provider you register, so nothing leaves your infrastructure unless you route it there.\n\n### Does MUI ship an MCP server?\n\nYes. @mui/mcp gives an AI client the official docs and code examples for Material UI and MUI X, including the Data Grid. @svgrid/mcp does the same for SvGrid and adds a code checker that validates props and imports against the real API surface, a scaffold tool and a preview.\n\n### Is SvGrid cheaper than MUI X Pro or Premium?\n\nThe prices mui.com listed on the date we read them are in the pricing line at the top of this page, per developer per year for Pro and Premium. SvGrid's core is MIT and @svgrid/enterprise is $599 per developer per year for the enterprise grid or $999 with the spreadsheet and Studio, both for unlimited applications. The difference is what the free tier holds: most features MUI X sells in Pro and Premium are in SvGrid's MIT core, so many teams never need the paid pack.\n\n### How long does a MUI X to SvGrid migration take?\n\nThe migration guide budgets one to three hours per grid. Column definitions and the row model map directly; the time goes into replacing React slots and renderCell functions with Svelte snippets and re-theming away from Material Design.\n\n### Is SvGrid a good MUI X DataGrid alternative for Svelte?\n\nMUI X DataGrid is React-only, so this is less an alternative than a port. The concepts carry over almost one to one: column definitions, a free tier and a paid tier, server-side rows, an imperative API. What does not carry over is Material Design: SvGrid is themed through CSS custom properties, so you bring your own look, and Emotion and Material UI stay out of the bundle.\n\n## Related comparisons and docs\n\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [SvGrid vs React Data Grid (adazzle)](https://svgrid.com/compare/react-data-grid/)\n- [SvGrid vs Glide Data Grid](https://svgrid.com/compare/glide-data-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [AI assistant](https://svgrid.com/docs/help/ai/)\n- [Column pinning](https://svgrid.com/docs/help/columns/column-pinning/)\n- [Master / detail (nested grids)](https://svgrid.com/docs/help/rows/master-detail/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- mui-overview: Feature list with plan badges: CSV export, cell editing and row virtualization in Community; column pinning, column reordering, row reordering, tree data and column virtualization Pro; row grouping, aggregation, Excel export and pivoting Premium; React package with Material UI peer dependencies (checked 12 Sep 2026) https://mui.com/x/react-data-grid/\n- mui-master-detail: Master-detail row panels carry the Pro plan badge (checked 12 Sep 2026) https://mui.com/x/react-data-grid/master-detail/\n- mui-cell-selection: Cell selection carries the Premium plan badge: with the Data Grid Premium, you can apply the cellSelection prop (checked 12 Sep 2026) https://mui.com/x/react-data-grid/cell-selection/\n- mui-ai-assistant: AI Assistant is Premium: natural-language prompts such as sort by name or show amounts larger than 1000, sent through a server-side proxy to MUI's hosted service with an API key from MUI Console; Premium licence holders get starter credits; a self-built prompt service is optional (checked 12 Sep 2026) https://mui.com/x/react-data-grid/ai-assistant/\n- mui-mcp: Official MCP server (@mui/mcp) that quotes the official docs and code examples for MUI X components including the Data Grid; installed with npx, no payment (checked 12 Sep 2026) https://mui.com/x/introduction/mcp/\n- mui-pricing: Community free forever under MIT; Pro $299 per year per dev; Premium $599 per year per dev; Enterprise $1,399 per year per dev; perpetual and annual models both allow perpetual production use (checked 12 Sep 2026) https://mui.com/pricing/\n"
|
|
6949
|
+
"markdown": "# SvGrid vs MUI X DataGrid\n\nCanonical URL: https://svgrid.com/compare/mui-x-datagrid/\nFacts verified: 2026-09-12\nCompetitor package: @mui/x-data-grid\nCompetitor site: https://mui.com/x/react-data-grid/\n\nMUI X DataGrid is the data grid of the Material UI ecosystem on React, split into a free Community tier and paid Pro and Premium tiers.\n\n## Verdict\n\nMUI X is the obvious pick if you are already on Material UI and React. SvGrid is Svelte-5-native, ships more in its MIT core (pinning, master/detail, tree data, grouping and cell selection are not Pro or Premium features), and carries no Material Design opinion.\n\nMigration guide: moving from MUI X DataGrid to SvGrid: https://svgrid.com/docs/help/migrating-from-mui-x/\n\n## At a glance\n\n| Fact | SvGrid | MUI X DataGrid | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 9.13.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 4 Sep 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (React) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 11,800,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 155.0 KB JS, no separate stylesheet, @emotion/react + @emotion/styled + @mui/material + @mui/system + react + react-dom external | 12 Sep 2026 |\n| Frameworks | Svelte 5 | React | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | MUI X Community is free under MIT. mui.com lists Pro at $299 per year per developer, Premium at $599 per year per developer and Enterprise at $1,399 per year per developer, with perpetual and annual licence models | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; @mui/x-data-grid 9.13.0 entry `DataGrid component` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nMUI X DataGrid is what most React teams on Material UI reach for. The Community edition is MIT and covers sorting, filtering, pagination, CSV export and row virtualization. Column pinning, column virtualization, row reordering, tree data and master/detail are Pro; row grouping, aggregation, cell selection, Excel export, pivoting and the AI assistant are Premium. Both paid tiers are sold per developer per year, and the sources below link to the pages that mark each feature.\n\nSvGrid is the inverse trade: one Svelte-5-native grid whose MIT core already includes pinning, master/detail, tree data, grouping with aggregation, cell-range selection with a fill handle, integrated charts and in-grid AI helpers you point at your own model, plus an optional @svgrid/enterprise pack for Excel, PDF and print output, import and pivot tables.\n\n## Looking for a MUI X DataGrid alternative for Svelte?\n\nMUI X DataGrid is React-only, so this is less an alternative than a port. The concepts carry over almost one to one: column definitions, a free tier and a paid tier, server-side rows, an imperative API. What does not carry over is Material Design: SvGrid is themed through CSS custom properties, so you bring your own look, and Emotion and Material UI stay out of the bundle.\n\n## What they have in common\n\n- A Community / paid split with an MIT free tier.\n- Sorting, filtering, pagination, virtualization and inline editing.\n- Server-side data through a row model the app feeds.\n- TypeScript-first with an imperative API for code outside the component.\n- An official MCP server so AI assistants read the real docs.\n- An in-grid AI assistant driven by natural language.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native: runes and snippets, not a React component behind a wrapper.\n- Column pinning, master/detail, tree data, row grouping with aggregation and cell-range selection are in the MIT core; MUI X sells them as Pro or Premium.\n- The in-grid AI helpers (natural-language filter, smart fill, summarise, classify) are free in @svgrid/grid and run against a provider you register; MUI X's AI assistant is Premium and routes prompts through MUI's hosted service unless you build your own.\n- No Material Design opinion: theme through --sg-* tokens, with no Emotion or Material UI in the bundle. The At a glance table has the measured sizes.\n- Integrated charts in the MIT core, without a separate charts package.\n\n## Where MUI X DataGrid is stronger\n\n- First-class fit if the app is already built on Material UI and React: theming, date pickers and charts share one design system.\n- Pro and Premium features are vendor-supported with priority support and guaranteed response times on the Enterprise plan.\n- A very large React community and years of production use.\n- The Premium AI assistant comes with a hosted prompt service and starter credits, so there is nothing to run yourself.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | MUI X DataGrid |\n| --- | --- | --- |\n| Svelte 5 native | Yes - runes and snippets | No - React only |\n| Sorting, filtering, pagination | Yes | Yes - Community |\n| Row virtualization | Yes | Yes - Community |\n| Column virtualization | Yes | Paid tier - Pro |\n| Column pinning | Yes - MIT core, left and right | Paid tier - Pro |\n| Row reordering by drag | Yes - MIT core | Paid tier - Pro |\n| Master/detail | Yes - MIT core | Paid tier - Pro |\n| Tree data | Yes - MIT core | Paid tier - Pro |\n| Row grouping with aggregation | Yes - MIT core | Paid tier - Premium |\n| Cell-range selection and clipboard | Yes - MIT core, with a fill handle | Paid tier - Premium |\n| CSV export | Yes - MIT core | Yes - Community |\n| Excel export | Paid tier - @svgrid/enterprise | Paid tier - Premium |\n| Pivot tables | Paid tier - @svgrid/enterprise | Paid tier - Premium |\n| Integrated charts | Yes - SvGridChart in the MIT core | Partial - MUI X Charts is a separate package |\n| In-grid AI assistant | Yes - MIT core, bring your own model | Paid tier - Premium, through MUI's hosted service or your own proxy |\n| MCP server for AI assistants | Yes - @svgrid/mcp, MIT: docs, examples, code check, scaffold, preview | Yes - @mui/mcp, free: docs and examples |\n| Inline editing | Yes | Yes - Community |\n| Design-system independence | Yes - --sg-* tokens, no UI framework dependency | Partial - Material UI, Emotion and the MUI system are peer dependencies |\n| Core licence | Yes - MIT | Yes - MIT (Community) |\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a grid shaped by runes, not a React component.\n- You want pinning, master/detail, tree data, grouping and cell selection without buying Pro or Premium.\n- You do not want Material Design, Emotion or the MUI system in your bundle.\n- You want the in-grid AI helpers to talk to a model you choose and host.\n\n## When to choose MUI X DataGrid\n\n- Your app is already built on Material UI and React.\n- You need Premium grouping, aggregation, pivoting or Excel export as vendor-supported features with a support contract.\n- You want one grid that matches React teammates across the MUI X suite, including date pickers and charts.\n- You want a hosted AI assistant with nothing to run yourself.\n\n## Migration effort\n\nEstimated effort: 1-3 hours per grid.\n\nWhat you give up:\n\n- Material Design out of the box; SvGrid ships neutral tokens and you theme it.\n- The rest of MUI X in the same design system: date pickers, charts and the tree view.\n- A hosted AI assistant with starter credits; SvGrid's helpers need a model provider you register.\n- React-specific patterns such as slots and hooks; SvGrid uses snippets and props.\n\nMigration guide: moving from MUI X DataGrid to SvGrid: https://svgrid.com/docs/help/migrating-from-mui-x/\n\n## Live example\n\nTree And Master Detail: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/08-tree-and-master-detail/\n\n## The bottom line\n\nIf your app already lives in Material UI and React, MUI X is the path of least resistance, and its Premium tier now includes a hosted AI assistant. On Svelte 5, SvGrid is the better fit: it puts pinning, master/detail, tree data, grouping and cell selection in the MIT core that MUI X reserves for Pro and Premium, keeps Material UI and Emotion out of the bundle, and runs its AI helpers against a model you choose.\n\n## Frequently asked questions\n\n### SvGrid vs MUI X DataGrid: which one for Svelte?\n\nSvGrid, if your stack is Svelte. MUI X is React-only and depends on Material UI, Emotion and the MUI system as peer dependencies; SvGrid is Svelte-5-native with no design-system dependency.\n\n### Which MUI X Pro and Premium features are free in SvGrid?\n\nColumn pinning, column virtualization, row reordering, master/detail and tree data (Pro in MUI X), and row grouping, aggregation and cell-range selection (Premium in MUI X) ship in the MIT core of SvGrid. Excel export and pivoting are paid on both sides: Premium in MUI X, @svgrid/enterprise in SvGrid.\n\n### Does MUI X have an AI assistant like SvGrid?\n\nYes, in Premium. mui.com describes a natural-language assistant (sort by name, show amounts larger than a value) that sends prompts through a proxy to MUI's hosted service with an API key, with starter credits included and the option to build your own processing service. SvGrid's natural-language filter, smart fill, summarise and classify helpers are free in @svgrid/grid and only run against a model provider you register, so nothing leaves your infrastructure unless you route it there.\n\n### Does MUI ship an MCP server?\n\nYes. @mui/mcp gives an AI client the official docs and code examples for Material UI and MUI X, including the Data Grid. @svgrid/mcp does the same for SvGrid and adds a code checker that validates props and imports against the real API surface, a scaffold tool and a preview.\n\n### Is SvGrid cheaper than MUI X Pro or Premium?\n\nThe prices mui.com listed on the date we read them are in the pricing line at the top of this page, per developer per year for Pro and Premium. SvGrid's core is MIT and @svgrid/enterprise is $599 per developer per year for the enterprise grid or $999 with the spreadsheet and Studio, both for unlimited applications. The difference is what the free tier holds: most features MUI X sells in Pro and Premium are in SvGrid's MIT core, so many teams never need the paid pack.\n\n### How long does a MUI X to SvGrid migration take?\n\nThe migration guide budgets one to three hours per grid. Column definitions and the row model map directly; the time goes into replacing React slots and renderCell functions with Svelte snippets and re-theming away from Material Design.\n\n### Is SvGrid a good MUI X DataGrid alternative for Svelte?\n\nMUI X DataGrid is React-only, so this is less an alternative than a port. The concepts carry over almost one to one: column definitions, a free tier and a paid tier, server-side rows, an imperative API. What does not carry over is Material Design: SvGrid is themed through CSS custom properties, so you bring your own look, and Emotion and Material UI stay out of the bundle.\n\n## Related comparisons and docs\n\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [SvGrid vs React Data Grid (adazzle)](https://svgrid.com/compare/react-data-grid/)\n- [SvGrid vs Glide Data Grid](https://svgrid.com/compare/glide-data-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [AI assistant](https://svgrid.com/docs/help/ai/)\n- [Column pinning](https://svgrid.com/docs/help/columns/column-pinning/)\n- [Master / detail (nested grids)](https://svgrid.com/docs/help/rows/master-detail/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- mui-overview: Feature list with plan badges: CSV export, cell editing and row virtualization in Community; column pinning, column reordering, row reordering, tree data and column virtualization Pro; row grouping, aggregation, Excel export and pivoting Premium; React package with Material UI peer dependencies (checked 12 Sep 2026) https://mui.com/x/react-data-grid/\n- mui-master-detail: Master-detail row panels carry the Pro plan badge (checked 12 Sep 2026) https://mui.com/x/react-data-grid/master-detail/\n- mui-cell-selection: Cell selection carries the Premium plan badge: with the Data Grid Premium, you can apply the cellSelection prop (checked 12 Sep 2026) https://mui.com/x/react-data-grid/cell-selection/\n- mui-ai-assistant: AI Assistant is Premium: natural-language prompts such as sort by name or show amounts larger than 1000, sent through a server-side proxy to MUI's hosted service with an API key from MUI Console; Premium licence holders get starter credits; a self-built prompt service is optional (checked 12 Sep 2026) https://mui.com/x/react-data-grid/ai-assistant/\n- mui-mcp: Official MCP server (@mui/mcp) that quotes the official docs and code examples for MUI X components including the Data Grid; installed with npx, no payment (checked 12 Sep 2026) https://mui.com/x/introduction/mcp/\n- mui-pricing: Community free forever under MIT; Pro $299 per year per dev; Premium $599 per year per dev; Enterprise $1,399 per year per dev; perpetual and annual models both allow perpetual production use (checked 12 Sep 2026) https://mui.com/pricing/\n"
|
|
6950
6950
|
},
|
|
6951
6951
|
{
|
|
6952
6952
|
"slug": "compare/primevue-datatable",
|
|
6953
6953
|
"path": "docs/_data/comparisons/primevue-datatable.json",
|
|
6954
6954
|
"title": "SvGrid vs PrimeVue / PrimeNG / PrimeReact DataTable",
|
|
6955
6955
|
"section": "Comparisons",
|
|
6956
|
-
"markdown": "# SvGrid vs PrimeVue / PrimeNG / PrimeReact DataTable\n\nCanonical URL: https://svgrid.com/compare/primevue-datatable/\nFacts verified: 2026-09-12\nCompetitor package: primevue\nCompetitor site: https://primevue.dev/datatable/\n\nThe Prime DataTable is the grid in the PrimeUI suites for Vue, Angular and React; since PrimeVue 5 it ships under the PrimeUI licence, free only for small organisations.\n\n## Verdict\n\nPrime DataTable is the natural pick inside the Prime suites for Vue, Angular and React, and since PrimeVue 5 it is a commercial product with a conditional free tier. SvGrid is the Svelte-native alternative with an MIT core, a headless engine and an MCP server.\n\nMigration guide: moving from PrimeVue / PrimeNG / PrimeReact DataTable to SvGrid: https://svgrid.com/docs/help/migrating-from-primevue-datatable/\n\n## At a glance\n\n| Fact | SvGrid | PrimeVue / PrimeNG / PrimeReact DataTable | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 5.0.1 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 13 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (Vue, Angular, React) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 3,010,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | Vue, Angular, React | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6956
|
+
"markdown": "# SvGrid vs PrimeVue / PrimeNG / PrimeReact DataTable\n\nCanonical URL: https://svgrid.com/compare/primevue-datatable/\nFacts verified: 2026-09-12\nCompetitor package: primevue\nCompetitor site: https://primevue.dev/datatable/\n\nThe Prime DataTable is the grid in the PrimeUI suites for Vue, Angular and React; since PrimeVue 5 it ships under the PrimeUI licence, free only for small organisations.\n\n## Verdict\n\nPrime DataTable is the natural pick inside the Prime suites for Vue, Angular and React, and since PrimeVue 5 it is a commercial product with a conditional free tier. SvGrid is the Svelte-native alternative with an MIT core, a headless engine and an MCP server.\n\nMigration guide: moving from PrimeVue / PrimeNG / PrimeReact DataTable to SvGrid: https://svgrid.com/docs/help/migrating-from-primevue-datatable/\n\n## At a glance\n\n| Fact | SvGrid | PrimeVue / PrimeNG / PrimeReact DataTable | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 5.0.1 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 13 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (Vue, Angular, React) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 3,010,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | Vue, Angular, React | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | primeui.dev lists the Commercial Suite at a launch price of $599 per developer (standard $799) as a perpetual licence with one year of updates, renewable at $399 per developer per year; the Community License is free for individuals, non-profits and organisations under $1M revenue, fewer than five developers, fewer than ten employees and under $3M in venture funding | 12 Sep 2026 |\n\n## Overview\n\nThe Prime DataTable (PrimeVue, PrimeNG, PrimeReact) is a deeply featured grid - sorting, filtering, grouping, row and column expansion, editing, lazy load, frozen columns, CSV export - shipped as part of the Prime component suites. The primevue package on npm now carries the PrimeUI licence: a free Community License for individuals and organisations under the revenue, headcount and funding limits stated in the licence file, and a per-developer Commercial License with a licence key for everyone else. The version and licence field in the At a glance table are read from npm.\n\nSvGrid brings a comparable grid to Svelte 5: an MIT core with no licence key, a render component plus a headless engine, Excel-style filters, editing, tree and master/detail, themed entirely through --sg-* tokens.\n\n## Looking for a PrimeVue / PrimeNG / PrimeReact DataTable alternative for Svelte?\n\nThe Prime DataTable ships as part of a UI suite for Vue, Angular and React, so on Svelte the real question is what replaces the whole suite. SvGrid answers the grid half and ships a Svelte component kit for much of the rest. If you lean on the full Prime suite and its themes, this is a bigger migration than a grid swap.\n\n## What they have in common\n\n- Sorting, filtering, grouping, expansion, editing and lazy or server-side data.\n- Frozen columns, row selection modes and a context menu.\n- Themeable through CSS variables.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native, not Vue, Angular or React.\n- MIT core with no licence key or eligibility conditions; @svgrid/enterprise is the only paid part.\n- A headless engine in addition to the component.\n- No design-system lock-in: theme through --sg-* tokens or Tailwind.\n- In-grid AI helpers and the @svgrid/mcp server for AI assistants.\n\n## Where PrimeVue / PrimeNG / PrimeReact DataTable is stronger\n\n- First-class fit inside the Prime suite for Vue, Angular or React.\n- A very large component library beyond the grid, plus PrimeBlocks and the theme designer in the commercial suite.\n- A very large community across three frameworks.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | PrimeVue / PrimeNG / PrimeReact DataTable |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - Vue / Angular / React |\n| License (grid core) | Yes - MIT, no licence key | Paid tier - PrimeUI licence: free Community License under revenue and headcount limits, otherwise per developer with a licence key |\n| Sort / filter / group | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Virtualization | Yes | Yes |\n| Headless engine | Yes | No - Component-only |\n| Design-system lock-in | Yes - None (--sg-*) | Partial - Prime theming |\n| AI / MCP integration | Yes | No - not on the DataTable page |\n\n## When to choose SvGrid\n\n- You are on Svelte 5, not Vue / Angular / React.\n- You want an MIT core with no design-system lock-in.\n- You want a headless engine and an MCP server.\n\n## When to choose PrimeVue / PrimeNG / PrimeReact DataTable\n\n- You already use the Prime suite for Vue, Angular or React and qualify for its Community License or have bought the Commercial Suite.\n- You want a large matching component library beyond the grid.\n- You want Prime themes, templates and blocks.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid.\n\nWhat you give up:\n\n- The Prime suite around the grid for Vue, Angular and React, with PrimeBlocks and the theme designer in the commercial tier.\n- A large community across three frameworks.\n\nMigration guide: moving from PrimeVue / PrimeNG / PrimeReact DataTable to SvGrid: https://svgrid.com/docs/help/migrating-from-primevue-datatable/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\nInside the Prime ecosystem for Vue, Angular or React, the Prime DataTable is the obvious choice, with the PrimeUI licence terms now part of the decision. For Svelte 5, SvGrid is the native fit, with an MIT core, a headless engine and no Prime-theme dependency.\n\n## Frequently asked questions\n\n### SvGrid vs PrimeVue DataTable - which for Svelte?\n\nSvGrid. Prime DataTable targets Vue, Angular, and React; SvGrid is Svelte-5-native with no design-system lock-in.\n\n### Is SvGrid open-source like the Prime grid?\n\nYes - MIT, like the Prime component cores. The difference is the framework and the theming model.\n\n### How do Prime Column definitions map to SvGrid?\n\nEach Column with field and header becomes a { field, header } object, and #body slots become renderSnippet cells. See the migration guide.\n\n### Is PrimeVue still MIT?\n\nNot from PrimeVue 5. The package on npm ships the PrimeUI licence: free for individuals, non-profits and organisations under the revenue, developer and employee limits in the licence file, and a per-developer commercial licence with a key for everyone else. The At a glance table reads the licence field from npm on the date shown; SvGrid's core is MIT with no key.\n\n### Is SvGrid a good PrimeVue / PrimeNG / PrimeReact DataTable alternative for Svelte?\n\nThe Prime DataTable ships as part of a UI suite for Vue, Angular and React, so on Svelte the real question is what replaces the whole suite. SvGrid answers the grid half and ships a Svelte component kit for much of the rest. If you lean on the full Prime suite and its themes, this is a bigger migration than a grid swap.\n\n## Related comparisons and docs\n\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [SvGrid vs Kendo UI Grid (Telerik)](https://svgrid.com/compare/kendo-ui-grid/)\n- [SvGrid vs Tabulator](https://svgrid.com/compare/tabulator/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Grouping & aggregation](https://svgrid.com/docs/help/grouping-aggregation/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- primeui-license: The primevue package ships the PrimeUI License: a free Community License for organisations under $1,000,000 revenue, fewer than 5 developers, fewer than 10 employees and under $3,000,000 outside funding, and a per-developer perpetual Commercial License with one year of updates; a licence key is required (checked 12 Sep 2026) https://unpkg.com/primevue@5.0.1/LICENSE.md\n- primeui-pricing: Commercial per developer $599 launch price (ends Dec 31, 2026) against $799 standard; update renewal $399 per developer; Community License eligibility as in the licence file (checked 12 Sep 2026) https://primeui.dev/pricing\n- primevue-datatable: DataTable page lists sorting, filtering, pagination, virtual scroll, row expansion, row grouping, frozen columns, editing, export CSV, lazy loading, selection, context menu, reorder and responsive modes; a PRO Suite with Charts, Scheduler, Task Board and Text Editor (checked 12 Sep 2026) https://primevue.dev/datatable/\n"
|
|
6957
6957
|
},
|
|
6958
6958
|
{
|
|
6959
6959
|
"slug": "compare/react-data-grid",
|
|
6960
6960
|
"path": "docs/_data/comparisons/react-data-grid.json",
|
|
6961
6961
|
"title": "SvGrid vs React Data Grid (adazzle)",
|
|
6962
6962
|
"section": "Comparisons",
|
|
6963
|
-
"markdown": "# SvGrid vs React Data Grid (adazzle)\n\nCanonical URL: https://svgrid.com/compare/react-data-grid/\nFacts verified: 2026-09-12\nCompetitor package: react-data-grid\nCompetitor site: https://github.com/adazzle/react-data-grid\n\nreact-data-grid is a fast, Excel-like data grid for React, MIT-licensed.\n\n## Verdict\n\nreact-data-grid is a strong, lightweight React grid with great editing. SvGrid is the Svelte-5-native equivalent, with a similar feature set and no React dependency.\n\nMigration guide: moving from React Data Grid (adazzle) to SvGrid: https://svgrid.com/docs/help/migrating-from-react-data-grid/\n\n## At a glance\n\n| Fact | SvGrid | React Data Grid (adazzle) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 7.0.0-beta.61 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 14 Jul 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (React) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 2,180,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 15.7 KB JS + 2.1 KB CSS, react + react-dom external | 12 Sep 2026 |\n| Frameworks | Svelte 5 | React | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6963
|
+
"markdown": "# SvGrid vs React Data Grid (adazzle)\n\nCanonical URL: https://svgrid.com/compare/react-data-grid/\nFacts verified: 2026-09-12\nCompetitor package: react-data-grid\nCompetitor site: https://github.com/adazzle/react-data-grid\n\nreact-data-grid is a fast, Excel-like data grid for React, MIT-licensed.\n\n## Verdict\n\nreact-data-grid is a strong, lightweight React grid with great editing. SvGrid is the Svelte-5-native equivalent, with a similar feature set and no React dependency.\n\nMigration guide: moving from React Data Grid (adazzle) to SvGrid: https://svgrid.com/docs/help/migrating-from-react-data-grid/\n\n## At a glance\n\n| Fact | SvGrid | React Data Grid (adazzle) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 7.0.0-beta.61 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 14 Jul 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (React) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 2,180,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 15.7 KB JS + 2.1 KB CSS, react + react-dom external | 12 Sep 2026 |\n| Frameworks | Svelte 5 | React | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | react-data-grid is MIT on npm and free; no licence is sold | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; react-data-grid 7.0.0-beta.61 entry `DataGrid component` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nreact-data-grid (the adazzle project) is a focused, performant React grid known for spreadsheet-style editing, virtualization, and a clean column API. It is MIT-licensed and React-only.\n\nSvGrid offers the same shape - virtualized DOM, typed columns, inline editing, custom cells - built on Svelte 5 runes and snippets rather than React components.\n\n## Looking for a React Data Grid alternative for Svelte?\n\nreact-data-grid is React-only, so this is a port rather than a swap, and the shapes line up well: both are Excel-like, both MIT, both driven by column definitions. Cell renderers become Svelte snippets and hooks become runes. If you are staying on React, there is no reason to move.\n\n## What they have in common\n\n- MIT-licensed.\n- Virtualized rows and columns.\n- Spreadsheet-style inline editing.\n- Typed column definitions.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native - runes and snippets, not React.\n- Built-in Excel-style filter menu and the imperative API.\n- Grouping, tree data, and master/detail in the core.\n- @svgrid/mcp MCP server + optional Enterprise pack.\n\n## Where React Data Grid (adazzle) is stronger\n\n- First-class fit for a React codebase.\n- Mature, focused, and battle-tested in React apps.\n- Large React community.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | React Data Grid (adazzle) |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - React only |\n| Virtualization | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Excel-style filter menu | Yes | Partial - BYO filter UI |\n| Grouping / tree | Yes | Yes - row grouping and a TreeDataGrid |\n| Master/detail | Yes | Partial - bring your own detail row |\n| Headless engine | Yes | No |\n| AI / MCP integration | Yes | No |\n| Fill handle and copy/paste | Yes | Yes - cell copy, paste and value dragging |\n\n## When to choose SvGrid\n\n- You are on Svelte 5 rather than React.\n- You want filters, grouping, and master/detail without building them.\n- You want a headless engine option and an MCP server.\n\n## When to choose React Data Grid (adazzle)\n\n- Your app is React and you want a focused, proven grid.\n- You want the React community and ecosystem around it.\n- You only need the feature set react-data-grid already covers.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid.\n\nWhat you give up:\n\n- A very small React grid with the spreadsheet basics built in.\n- React 19 features such as the use hook in cell renderers.\n\nMigration guide: moving from React Data Grid (adazzle) to SvGrid: https://svgrid.com/docs/help/migrating-from-react-data-grid/\n\n## Live example\n\nFill Handle: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/95-fill-handle/\n\n## The bottom line\n\nreact-data-grid is a strong, focused choice in React. On Svelte 5, SvGrid is the equivalent - similar editing and virtualization - plus a built-in filter menu, grouping, and a headless core, with no React dependency.\n\n## Frequently asked questions\n\n### SvGrid vs react-data-grid - which for Svelte?\n\nSvGrid - it is Svelte-5-native, while react-data-grid is React-only. They share a similar editing and virtualization model.\n\n### Does SvGrid have built-in filtering unlike react-data-grid?\n\nYes - SvGrid ships an Excel-style filter menu and a global filter; react-data-grid leaves the filter UI to you.\n\n### Is SvGrid free like react-data-grid?\n\nYes, the core is MIT. SvGrid adds an optional Enterprise pack for export, import, pivot, and AI.\n\n### Is SvGrid a good React Data Grid alternative for Svelte?\n\nreact-data-grid is React-only, so this is a port rather than a swap, and the shapes line up well: both are Excel-like, both MIT, both driven by column definitions. Cell renderers become Svelte snippets and hooks become runes. If you are staying on React, there is no reason to move.\n\n## Related comparisons and docs\n\n- [SvGrid vs Glide Data Grid](https://svgrid.com/compare/glide-data-grid/)\n- [SvGrid vs MUI X DataGrid](https://svgrid.com/compare/mui-x-datagrid/)\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Cell text selection](https://svgrid.com/docs/help/cells/cell-text-selection/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- rdg-readme: React 19.2+; virtualization of rows and columns, multi-column sorting, cell editing, row grouping and a TreeDataGrid, frozen columns, cell copy and paste, cell value dragging; light and dark mode through color-scheme (checked 12 Sep 2026) https://github.com/adazzle/react-data-grid\n- rdg-npm: The latest tag is a 7.0 beta line; licence MIT (checked 12 Sep 2026) https://www.npmjs.com/package/react-data-grid\n"
|
|
6964
6964
|
},
|
|
6965
6965
|
{
|
|
6966
6966
|
"slug": "compare/smart-grid",
|
|
6967
6967
|
"path": "docs/_data/comparisons/smart-grid.json",
|
|
6968
6968
|
"title": "SvGrid vs Smart.Grid (Smart Web Components)",
|
|
6969
6969
|
"section": "Comparisons",
|
|
6970
|
-
"markdown": "# SvGrid vs Smart.Grid (Smart Web Components)\n\nCanonical URL: https://svgrid.com/compare/smart-grid/\nFacts verified: 2026-09-12\nCompetitor package: smart-webcomponents\nCompetitor site: https://www.htmlelements.com/\n\nSmart.Grid is the htmlelements.com web-component grid - framework-agnostic custom elements from the team that builds SvGrid.\n\n## Verdict\n\nSame team again. Smart.Grid is a great framework-agnostic web component that even works inside Svelte; SvGrid is the runes-native option, with Svelte snippets for cells and an MIT community core.\n\nMigration guide: moving from Smart.Grid (Smart Web Components) to SvGrid: https://svgrid.com/docs/help/migrating-from-smart-grid/\n\n## At a glance\n\n| Fact | SvGrid | Smart.Grid (Smart Web Components) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 27.0.1 | 12 Sep 2026 |\n| Licence field on npm | MIT | ISC | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 13 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Custom element, works in Svelte with a wrapper | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 6,620 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | Web Components | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6970
|
+
"markdown": "# SvGrid vs Smart.Grid (Smart Web Components)\n\nCanonical URL: https://svgrid.com/compare/smart-grid/\nFacts verified: 2026-09-12\nCompetitor package: smart-webcomponents\nCompetitor site: https://www.htmlelements.com/\n\nSmart.Grid is the htmlelements.com web-component grid - framework-agnostic custom elements from the team that builds SvGrid.\n\n## Verdict\n\nSame team again. Smart.Grid is a great framework-agnostic web component that even works inside Svelte; SvGrid is the runes-native option, with Svelte snippets for cells and an MIT community core.\n\nMigration guide: moving from Smart.Grid (Smart Web Components) to SvGrid: https://svgrid.com/docs/help/migrating-from-smart-grid/\n\n## At a glance\n\n| Fact | SvGrid | Smart.Grid (Smart Web Components) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 27.0.1 | 12 Sep 2026 |\n| Licence field on npm | MIT | ISC | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 13 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Custom element, works in Svelte with a wrapper | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 6,620 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | Web Components | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | htmlelements.com lists the Developer License at $499 (on sale at $399) per developer, perpetual, or $39 per month, and the Team License at $1,499 per five developers; the free Community License covers the core components but not the Grid | 12 Sep 2026 |\n\n## Overview\n\nSmart.Grid (part of Smart Web Components / htmlelements.com) is a high-performance grid built as a standard custom element, so it drops into any framework - Angular, React, Vue, Svelte, or vanilla. It comes from the same team behind jQWidgets and SvGrid, with the same enterprise pedigree.\n\nSvGrid covers the same job for Svelte 5 specifically: where Smart.Grid is a custom element you bind to through attributes and events, SvGrid is reactive Svelte - `$state` data, snippet cells, and an MIT community core.\n\n## Looking for a Smart.Grid alternative for Svelte?\n\nSmart.Grid and SvGrid come from the same team, so this is a question about how you want to ship rather than who to trust. Smart.Grid is web components, which work anywhere including Svelte; SvGrid is a native Svelte 5 component with runes, snippets and SSR. If you need one grid across several frameworks, the web-component route is the deliberate choice, and @svgrid/grid-wc offers the same for SvGrid.\n\n## What they have in common\n\n- Same engineering team and enterprise pedigree.\n- High-performance grid with virtualization.\n- Sorting, filtering, grouping, editing.\n- Works inside a Svelte app.\n\n## Where SvGrid is stronger\n\n- Reactive Svelte 5 - runes + snippets, not a custom element bound via attributes.\n- MIT-licensed community core.\n- Svelte component / snippet cells instead of element templates.\n- A headless engine in addition to the render component.\n\n## Where Smart.Grid (Smart Web Components) is stronger\n\n- Truly framework-agnostic - one component across Angular, React, Vue, Svelte, vanilla.\n- Part of a large Smart Web Components library beyond the grid.\n- Mature, with the team's long enterprise track record.\n- Reuse the same grid if your shop spans several frameworks.\n- Ships its own MCP server for AI assistants, like SvGrid.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Smart.Grid (Smart Web Components) |\n| --- | --- | --- |\n| Svelte 5 reactive-native | Yes - Runes + snippets | Partial - Custom element in Svelte |\n| License | Yes - MIT core | Paid tier - perpetual per-developer licence; the free Community License excludes the Grid |\n| Custom cells | Yes - Snippets / components | Partial - Element templates |\n| Sort / filter / group | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Virtualization | Yes | Yes |\n| Framework-agnostic | No - Svelte only | Yes - Web component everywhere |\n| Headless engine | Yes | No |\n| AI / MCP server | Yes - @svgrid/mcp | Yes - Smart MCP |\n\n## When to choose SvGrid\n\n- Your stack is Svelte 5 and you want reactive runes, not attribute binding.\n- You want Svelte snippets / components for custom cells.\n- You want an MIT community core and an MCP server.\n\n## When to choose Smart.Grid (Smart Web Components)\n\n- You need one grid across Angular, React, Vue, Svelte, and vanilla.\n- You already use the Smart Web Components library.\n- A standard custom element fits your architecture better than a Svelte component.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid.\n\nWhat you give up:\n\n- One custom element that runs in every framework.\n- A perpetual licence model and the wider Smart UI suite.\n\nMigration guide: moving from Smart.Grid (Smart Web Components) to SvGrid: https://svgrid.com/docs/help/migrating-from-smart-grid/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\nSmart.Grid is a strong framework-agnostic web component from the same team, and it works in Svelte today. Choose SvGrid when you want idiomatic Svelte - runes and snippets - and an MIT core; choose Smart.Grid when you need one grid across every framework.\n\n## Frequently asked questions\n\n### Is Smart.Grid from the SvGrid team?\n\nYes - Smart Web Components (htmlelements.com) and SvGrid are built by the same team. SvGrid is the Svelte-native option with an MIT core.\n\n### Can I use Smart.Grid in Svelte instead of SvGrid?\n\nYes - Smart.Grid is a web component and runs in Svelte. Pick SvGrid for an idiomatic Svelte component (runes plus snippets) rather than a custom element.\n\n### Do both Smart.Grid and SvGrid have an MCP server?\n\nYes - both ship MCP servers for AI assistants.\n\n### Is SvGrid a good Smart.Grid alternative for Svelte?\n\nSmart.Grid and SvGrid come from the same team, so this is a question about how you want to ship rather than who to trust. Smart.Grid is web components, which work anywhere including Svelte; SvGrid is a native Svelte 5 component with runes, snippets and SSR. If you need one grid across several frameworks, the web-component route is the deliberate choice, and @svgrid/grid-wc offers the same for SvGrid.\n\n## Related comparisons and docs\n\n- [SvGrid vs jqxGrid (jQWidgets)](https://svgrid.com/compare/jqxgrid/)\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [SvGrid vs Tabulator](https://svgrid.com/compare/tabulator/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [MCP server](https://svgrid.com/docs/help/mcp-server/)\n- [Web Components & Custom Elements](https://svgrid.com/docs/help/web-components/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- smart-license: Developer License $499 (sale $399) per developer, perpetual, or $39 per month; Team License $1,499 per 5 developers; Unlimited $2,999; Community License covers 40+ core components, advanced components such as Grid, Scheduler and Charts need a Commercial License (checked 12 Sep 2026) https://www.htmlelements.com/license/\n"
|
|
6971
6971
|
},
|
|
6972
6972
|
{
|
|
6973
6973
|
"slug": "compare/svar-svelte-datagrid",
|
|
6974
6974
|
"path": "docs/_data/comparisons/svar-svelte-datagrid.json",
|
|
6975
6975
|
"title": "SvGrid vs SVAR Svelte DataGrid",
|
|
6976
6976
|
"section": "Comparisons",
|
|
6977
|
-
"markdown": "# SvGrid vs SVAR Svelte DataGrid\n\nCanonical URL: https://svgrid.com/compare/svar-svelte-datagrid/\nFacts verified: 2026-09-12\nCompetitor package: wx-svelte-grid\nCompetitor site: https://svar.dev/svelte/datagrid/\n\nSVAR Svelte DataGrid (wx-svelte-grid) is a Svelte-native, MIT-licensed data grid from XB Software, the team behind Webix, with React and Vue versions of the same grid.\n\n## Verdict\n\nSVAR is the closest genuinely Svelte-native rival: both grids are MIT and both target Svelte 5. SvGrid has the wider capability surface (grouping with aggregation, master/detail, Excel-style range editing with a fill handle, integrated charts, a headless core, in-grid AI helpers and an MCP server); SVAR is the smaller grid with print in the free package, React and Vue versions, and the Webix team behind it.\n\nMigration guide: moving from SVAR Svelte DataGrid to SvGrid: https://svgrid.com/docs/help/migrating-from-svar-svelte-datagrid/\n\n## At a glance\n\n| Fact | SvGrid | SVAR Svelte DataGrid | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 2.7.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 3 Jun 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Svelte package, no peer range declared | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 62,800 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 51.5 KB JS, no separate stylesheet, svelte external | 12 Sep 2026 |\n| Engine alone, minified + gzip | 2.7 KB JS, no separate stylesheet (`createSvGrid` from `@svgrid/grid/core`) | the row above; the package is the engine | 22 Sep 2026 |\n| Frameworks | Svelte 5 | Svelte, React, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $599 per developer per year | The DataGrid is MIT and free for commercial use with no paid tier; svar.dev sells PRO editions of its Gantt, Calendar and Kanban components and offers paid consulting and custom development, with no price list for the grid | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; wx-svelte-grid 2.7.0 entry `Grid component` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nSVAR DataGrid (npm: wx-svelte-grid) is part of the SVAR suite from XB Software, the makers of Webix, and is one of the few grids built for Svelte rather than wrapped from another framework. Its docs list in-cell editing, header and advanced filtering, single and multi-column sorting, tree data, virtual scrolling for rows and columns, columns pinned to the left, column and row spans in the header and footer, auto-sized rows, undo and redo, a context menu, row reordering, CSV export, a print API and a REST data provider, all under MIT.\n\nSvGrid overlaps on the Svelte-native angle and reaches further: row grouping with aggregation, master/detail, Excel-style cell-range selection with clipboard and a fill handle, pinned rows and left and right column pinning, integrated charts, a server-side row model, a headless engine, in-grid AI helpers and the @svgrid/mcp server, all in the MIT package. Excel, PDF and print output, import, pivot tables and the Kanban and Scheduler views of the grid live in the paid @svgrid/enterprise pack, whereas SVAR keeps its grid entirely free and sells PRO editions of its Gantt, Calendar and Kanban instead.\n\n## Looking for a SVAR Svelte DataGrid alternative for Svelte?\n\nThe closest comparison on this list, since both are Svelte-native and both are MIT, so licensing does not decide it. The differences are depth and direction: SvGrid ships a larger feature surface, a UI component suite, in-grid AI helpers and an MCP server, while SVAR spans Svelte, React and Vue and keeps a smaller core. The At a glance table above has both measured bundle sizes; if a compact MIT grid with sorting, filtering, editing, tree data and CSV export is all you need, SVAR is a perfectly good answer.\n\n## What they have in common\n\n- Purpose-built for Svelte 5, not a cross-framework wrapper.\n- MIT-licensed and free for commercial use.\n- Sorting, filtering, in-cell editing, virtualization on rows and columns, tree data.\n- Auto-sized row heights, undo and redo, a context menu and drag-and-drop row reordering.\n- Themeable through CSS variables with light and dark themes, localization, WAI-ARIA markup and keyboard navigation.\n\n## Where SvGrid is stronger\n\n- Row grouping with aggregation and a drag-and-drop group panel; SVAR's docs list neither.\n- Master/detail and expandable detail rows; SVAR offers tree data only.\n- Excel-style cell-range selection with clipboard copy and paste and a fill handle; SVAR selects rows.\n- Pinned top and bottom rows, and columns pinned left and right; SVAR pins columns to the left only.\n- Integrated charts with no dependency, plus a chart wizard.\n- A server-side row model with cursor pagination, GraphQL, websocket and optimistic updates, beyond a REST data provider.\n- A headless engine (createSvGrid) you can compose, in addition to the render component.\n- In-grid AI helpers free in @svgrid/grid, and @svgrid/mcp with llms.txt so assistants answer and write code accurately.\n- A paid pack with Excel, PDF and styled-HTML export, print, pivot tables, Excel and CSV import and support. CSV, TSV and JSON export are free in the grid.\n\n## Where SVAR Svelte DataGrid is stronger\n\n- The whole grid is free, print API included; SvGrid puts print and Excel and PDF export in the paid pack. Both export CSV for free.\n- The same grid for React and Vue as well as Svelte; SvGrid is Svelte-only by design.\n- A smaller bundle: the At a glance table has both measured numbers.\n- XB Software and Webix behind it, a team that has built data grids for a long time.\n- Part of the wider SVAR suite, with paid consulting and custom development on offer.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | SVAR Svelte DataGrid |\n| --- | --- | --- |\n| Svelte 5 native | Yes | Yes - Svelte 5 compatible |\n| Licence | Yes - MIT core, paid enterprise pack | Yes - MIT, the grid is entirely free |\n| Headless engine | Yes - createSvGrid | No - component only |\n| Excel-style filter menu | Yes - built in | Yes - header filters plus the SVAR Filter component |\n| Cell-range selection and clipboard | Yes - built in | No - single and multiple row selection |\n| Fill handle | Yes | No - not in the feature list |\n| Row grouping with aggregation | Yes - with a group panel | No - not in the feature list |\n| Master/detail rows | Yes | No - tree data only |\n| Tree data | Yes | Yes |\n| Pinned columns | Yes - left and right | Partial - to the left |\n| Pinned rows (top and bottom) | Yes | No - not in the feature list |\n| Header and footer column spans | Yes | Yes |\n| Auto-sized row height | Yes - autoRowHeight | Yes |\n| Virtualization (rows and columns) | Yes | Yes |\n| Undo and redo, context menu, row drag | Yes | Yes |\n| Integrated charts | Yes - no dependency, plus a chart wizard | No - not in the feature list |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes - createServerDataSource: page or infinite block scroll, cursor, GraphQL, websocket | Partial - RestDataProvider and dynamic loading while scrolling |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise | No - not in the feature list |\n| CSV export | Yes - free, with TSV and JSON | Yes - free |\n| Excel and PDF export | Paid tier - @svgrid/enterprise | No - CSV only in the feature list |\n| Print | Paid tier - @svgrid/enterprise | Yes - print API, free |\n| Pivot tables | Paid tier - @svgrid/enterprise | No - not in the SVAR Svelte product list |\n| React and Vue versions | No - Svelte only | Yes |\n| In-grid AI helpers and MCP server | Yes - helpers free in @svgrid/grid; @svgrid/mcp, MIT | No - not mentioned in the docs |\n| Paid support | Yes - with @svgrid/enterprise, per developer per year | Partial - paid consulting and custom development; no support plan for the grid listed |\n\n## Measured performance\n\nMeasured 12 Sep 2026 with the harness in the repository (pnpm bench:compare): 100,000 rows, fastest of 7 samples per operation, each grid in a fresh page, Chromium through Playwright, headless, on win32 10.0.26200 x64, Intel(R) Core(TM) Ultra 7 255U; a developer workstation, not a dedicated bench rig. Versions: @svgrid/grid 3.0.3, wx-svelte-grid 2.7.0. Lower is better.\n\n| Operation | SvGrid | SVAR Svelte DataGrid |\n| --- | --- | --- |\n| Mount | 75.5 ms | 11.4 ms |\n| Sort, text column | 149 ms | 187.2 ms |\n| Sort, numeric column | 115.7 ms | 165.1 ms |\n| Filter, one column (indicative only) | 99.6 ms | 32.6 ms |\n| Scroll, p95 frame | 34.6 ms | 34.8 ms |\n| Rows kept in the DOM (virtualization on) | 27 | 19 |\n\nThe filter row is not like for like: each grid is driven through its own single-column filter API, and the amount of work differs. The comparison guide explains the method, what is left out and why.\n\n## When to choose SvGrid\n\n- You need grouping with aggregation, master/detail, Excel-style range editing or pivot tables, which SVAR's docs do not list.\n- You want a headless engine plus a render component, not a component-only API.\n- You want integrated charts and a full server-side row model in one library.\n- You want in-grid AI helpers, an MCP server that checks generated code, and a paid support tier.\n\n## When to choose SVAR Svelte DataGrid\n\n- You want a fully free grid with print included and no paid tier at all.\n- You ship to React and Vue as well as Svelte and want one grid across them.\n- A smaller bundle matters more than the features above.\n- You are already adopting the wider SVAR suite: Gantt, Calendar, Kanban, File Manager.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid.\n\nWhat you give up:\n\n- Free printing: SVAR's print API is in the MIT grid, SvGrid's print view is in @svgrid/enterprise.\n- The React and Vue versions of the same grid.\n- A smaller bundle, by the measurements in the At a glance table.\n- The SVAR suite around the grid: Gantt, Calendar, Kanban and File Manager share its core.\n\nMigration guide: moving from SVAR Svelte DataGrid to SvGrid: https://svgrid.com/docs/help/migrating-from-svar-svelte-datagrid/\n\n## Live example\n\nGrouping Aggregation: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/07-grouping-aggregation/\n\n## The bottom line\n\nBoth grids are Svelte-5-native and MIT, so this is not a licensing call. On capability SvGrid is the more complete grid: grouping, master/detail, range editing with a fill handle, charts, a server-side row model, a headless core, AI helpers and an MCP server. SVAR is the smaller, fully free, multi-framework option from the Webix team, and it prints for free where SvGrid charges for print and Excel and PDF export. Choose SvGrid when you need the deeper feature set or support; choose SVAR when a compact free grid covers your needs or you also ship React and Vue.\n\n## Frequently asked questions\n\n### SvGrid vs SVAR Svelte DataGrid: what is the difference?\n\nBoth are MIT-licensed, Svelte-5-native grids. SvGrid is the broader product: row grouping with aggregation, master/detail, Excel-style range selection with a fill handle, integrated charts, a server-side row model, a headless core, in-grid AI helpers and an MCP server. SVAR is a smaller, fully free grid with React and Vue versions from XB Software, with CSV export and a print API included.\n\n### Are SvGrid and SVAR both free?\n\nBoth are free under MIT, including commercial use. SVAR keeps the whole grid free, CSV export and print included, and sells PRO editions of its Gantt, Calendar and Kanban. SvGrid's grid is free too, including CSV, TSV and JSON export, charts and the AI helpers; Excel, PDF and print output, import, pivot tables, the Kanban and Scheduler views and support are in @svgrid/enterprise at $599 per developer per year.\n\n### Are both built for Svelte 5?\n\nYes. SvGrid is written in Svelte 5 runes, and svar.dev states the DataGrid is Svelte 5 compatible. Neither is a cross-framework wrapper, although SVAR also ships React and Vue versions of its grid.\n\n### Which grid is smaller?\n\nSVAR, by the measurements in the At a glance table: both packages were built alone with Vite, minified and gzipped with Svelte external, on the dates shown. SvGrid's extra size buys grouping, master/detail, range editing, charts and the server-side row model; features you never import, such as the date editors, menus and charts, load as separate chunks.\n\n### Does SVAR have row grouping, master/detail or cell-range selection?\n\nNot according to its docs overview on the date we read it, which lists tree data, single and multiple row selection, header and advanced filters, sorting, in-cell editing, columns pinned to the left, CSV export and a print API. SvGrid has all three in the MIT core, and the demos on this page show them.\n\n### How long does a SVAR to SvGrid migration take?\n\nThe migration guide budgets two to four hours per grid: a prop and event rename pass, since both use array-of-object column definitions, plus re-theming through --sg-* tokens.\n\n### Is SvGrid a good SVAR Svelte DataGrid alternative for Svelte?\n\nThe closest comparison on this list, since both are Svelte-native and both are MIT, so licensing does not decide it. The differences are depth and direction: SvGrid ships a larger feature surface, a UI component suite, in-grid AI helpers and an MCP server, while SVAR spans Svelte, React and Vue and keeps a smaller core. The At a glance table above has both measured bundle sizes; if a compact MIT grid with sorting, filtering, editing, tree data and CSV export is all you need, SVAR is a perfectly good answer.\n\n## Related comparisons and docs\n\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/)\n- [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/)\n- [SvGrid vs @vincjo/datatables](https://svgrid.com/compare/vincjo-datatables/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Grouping & aggregation](https://svgrid.com/docs/help/grouping-aggregation/)\n- [Master / detail (nested grids)](https://svgrid.com/docs/help/rows/master-detail/)\n- [Build a table from scratch](https://svgrid.com/docs/help/headless/build-a-table/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- svar-datagrid: Licensed under MIT; Svelte 5 compatible; React and Vue versions available; lists multi-column sorting, header filters, in-cell editing, tree data, virtual scrolling, columns pinned to the left, context menu, row drag-and-drop, checkbox selection, pagination, hotkeys, WAI-ARIA, print, undo/redo (checked 12 Sep 2026) https://svar.dev/svelte/datagrid/\n- svar-overview: Feature list: in-cell editing, header and advanced filtering, sorting, single and multiple row selection, row reordering, context menu, undo/redo, tree data, pagination, colspans and rowspans in header and footer, collapsible column groups, pinned columns to the left, auto-sizing of rows and columns, localization, themes, export to CSV, print API, RestDataProvider, virtual scrolling for rows and columns, WAI-ARIA, keyboard navigation; no Excel export, row grouping, aggregation, master/detail, charts, AI or MCP (checked 12 Sep 2026) https://docs.svar.dev/svelte/grid/overview/\n- svar-svelte: DataGrid, Filter, Editor, File Manager and Core are MIT; Gantt, Calendar and Kanban have MIT cores with paid PRO editions; no pivot component in the list; no price list on the page (checked 12 Sep 2026) https://svar.dev/svelte/\n- svar-gantt: Offers paid consulting and custom development services; PRO edition pricing is on a separate page (checked 12 Sep 2026) https://svar.dev/svelte/gantt/\n"
|
|
6977
|
+
"markdown": "# SvGrid vs SVAR Svelte DataGrid\n\nCanonical URL: https://svgrid.com/compare/svar-svelte-datagrid/\nFacts verified: 2026-09-12\nCompetitor package: wx-svelte-grid\nCompetitor site: https://svar.dev/svelte/datagrid/\n\nSVAR Svelte DataGrid (wx-svelte-grid) is a Svelte-native, MIT-licensed data grid from XB Software, the team behind Webix, with React and Vue versions of the same grid.\n\n## Verdict\n\nSVAR is the closest genuinely Svelte-native rival: both grids are MIT and both target Svelte 5. SvGrid has the wider capability surface (grouping with aggregation, master/detail, Excel-style range editing with a fill handle, integrated charts, a headless core, in-grid AI helpers and an MCP server); SVAR is the smaller grid with print in the free package, React and Vue versions, and the Webix team behind it.\n\nMigration guide: moving from SVAR Svelte DataGrid to SvGrid: https://svgrid.com/docs/help/migrating-from-svar-svelte-datagrid/\n\n## At a glance\n\n| Fact | SvGrid | SVAR Svelte DataGrid | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 2.7.0 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 3 Jun 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Svelte package, no peer range declared | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 62,800 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 51.5 KB JS, no separate stylesheet, svelte external | 12 Sep 2026 |\n| Engine alone, minified + gzip | 2.7 KB JS, no separate stylesheet (`createSvGrid` from `@svgrid/grid/core`) | the row above; the package is the engine | 22 Sep 2026 |\n| Frameworks | Svelte 5 | Svelte, React, Vue | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | The DataGrid is MIT and free for commercial use with no paid tier; svar.dev sells PRO editions of its Gantt, Calendar and Kanban components and offers paid consulting and custom development, with no price list for the grid | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; wx-svelte-grid 2.7.0 entry `Grid component` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nSVAR DataGrid (npm: wx-svelte-grid) is part of the SVAR suite from XB Software, the makers of Webix, and is one of the few grids built for Svelte rather than wrapped from another framework. Its docs list in-cell editing, header and advanced filtering, single and multi-column sorting, tree data, virtual scrolling for rows and columns, columns pinned to the left, column and row spans in the header and footer, auto-sized rows, undo and redo, a context menu, row reordering, CSV export, a print API and a REST data provider, all under MIT.\n\nSvGrid overlaps on the Svelte-native angle and reaches further: row grouping with aggregation, master/detail, Excel-style cell-range selection with clipboard and a fill handle, pinned rows and left and right column pinning, integrated charts, a server-side row model, a headless engine, in-grid AI helpers and the @svgrid/mcp server, all in the MIT package. Excel, PDF and print output, import, pivot tables and the Kanban and Scheduler views of the grid live in the paid @svgrid/enterprise pack, whereas SVAR keeps its grid entirely free and sells PRO editions of its Gantt, Calendar and Kanban instead.\n\n## Looking for a SVAR Svelte DataGrid alternative for Svelte?\n\nThe closest comparison on this list, since both are Svelte-native and both are MIT, so licensing does not decide it. The differences are depth and direction: SvGrid ships a larger feature surface, a UI component suite, in-grid AI helpers and an MCP server, while SVAR spans Svelte, React and Vue and keeps a smaller core. The At a glance table above has both measured bundle sizes; if a compact MIT grid with sorting, filtering, editing, tree data and CSV export is all you need, SVAR is a perfectly good answer.\n\n## What they have in common\n\n- Purpose-built for Svelte 5, not a cross-framework wrapper.\n- MIT-licensed and free for commercial use.\n- Sorting, filtering, in-cell editing, virtualization on rows and columns, tree data.\n- Auto-sized row heights, undo and redo, a context menu and drag-and-drop row reordering.\n- Themeable through CSS variables with light and dark themes, localization, WAI-ARIA markup and keyboard navigation.\n\n## Where SvGrid is stronger\n\n- Row grouping with aggregation and a drag-and-drop group panel; SVAR's docs list neither.\n- Master/detail and expandable detail rows; SVAR offers tree data only.\n- Excel-style cell-range selection with clipboard copy and paste and a fill handle; SVAR selects rows.\n- Pinned top and bottom rows, and columns pinned left and right; SVAR pins columns to the left only.\n- Integrated charts with no dependency, plus a chart wizard.\n- A server-side row model with cursor pagination, GraphQL, websocket and optimistic updates, beyond a REST data provider.\n- A headless engine (createSvGrid) you can compose, in addition to the render component.\n- In-grid AI helpers free in @svgrid/grid, and @svgrid/mcp with llms.txt so assistants answer and write code accurately.\n- A paid pack with Excel, PDF and styled-HTML export, print, pivot tables, Excel and CSV import and support. CSV, TSV and JSON export are free in the grid.\n\n## Where SVAR Svelte DataGrid is stronger\n\n- The whole grid is free, print API included; SvGrid puts print and Excel and PDF export in the paid pack. Both export CSV for free.\n- The same grid for React and Vue as well as Svelte; SvGrid is Svelte-only by design.\n- A smaller bundle: the At a glance table has both measured numbers.\n- XB Software and Webix behind it, a team that has built data grids for a long time.\n- Part of the wider SVAR suite, with paid consulting and custom development on offer.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | SVAR Svelte DataGrid |\n| --- | --- | --- |\n| Svelte 5 native | Yes | Yes - Svelte 5 compatible |\n| Licence | Yes - MIT core, paid enterprise pack | Yes - MIT, the grid is entirely free |\n| Headless engine | Yes - createSvGrid | No - component only |\n| Excel-style filter menu | Yes - built in | Yes - header filters plus the SVAR Filter component |\n| Cell-range selection and clipboard | Yes - built in | No - single and multiple row selection |\n| Fill handle | Yes | No - not in the feature list |\n| Row grouping with aggregation | Yes - with a group panel | No - not in the feature list |\n| Master/detail rows | Yes | No - tree data only |\n| Tree data | Yes | Yes |\n| Pinned columns | Yes - left and right | Partial - to the left |\n| Pinned rows (top and bottom) | Yes | No - not in the feature list |\n| Header and footer column spans | Yes | Yes |\n| Auto-sized row height | Yes - autoRowHeight | Yes |\n| Virtualization (rows and columns) | Yes | Yes |\n| Undo and redo, context menu, row drag | Yes | Yes |\n| Integrated charts | Yes - no dependency, plus a chart wizard | No - not in the feature list |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes - createServerDataSource: page or infinite block scroll, cursor, GraphQL, websocket | Partial - RestDataProvider and dynamic loading while scrolling |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise | No - not in the feature list |\n| CSV export | Yes - free, with TSV and JSON | Yes - free |\n| Excel and PDF export | Paid tier - @svgrid/enterprise | No - CSV only in the feature list |\n| Print | Paid tier - @svgrid/enterprise | Yes - print API, free |\n| Pivot tables | Paid tier - @svgrid/enterprise | No - not in the SVAR Svelte product list |\n| React and Vue versions | No - Svelte only | Yes |\n| In-grid AI helpers and MCP server | Yes - helpers free in @svgrid/grid; @svgrid/mcp, MIT | No - not mentioned in the docs |\n| Paid support | Yes - with @svgrid/enterprise, per developer per year | Partial - paid consulting and custom development; no support plan for the grid listed |\n\n## Measured performance\n\nMeasured 12 Sep 2026 with the harness in the repository (pnpm bench:compare): 100,000 rows, fastest of 7 samples per operation, each grid in a fresh page, Chromium through Playwright, headless, on win32 10.0.26200 x64, Intel(R) Core(TM) Ultra 7 255U; a developer workstation, not a dedicated bench rig. Versions: @svgrid/grid 3.0.3, wx-svelte-grid 2.7.0. Lower is better.\n\n| Operation | SvGrid | SVAR Svelte DataGrid |\n| --- | --- | --- |\n| Mount | 75.5 ms | 11.4 ms |\n| Sort, text column | 149 ms | 187.2 ms |\n| Sort, numeric column | 115.7 ms | 165.1 ms |\n| Filter, one column (indicative only) | 99.6 ms | 32.6 ms |\n| Scroll, p95 frame | 34.6 ms | 34.8 ms |\n| Rows kept in the DOM (virtualization on) | 27 | 19 |\n\nThe filter row is not like for like: each grid is driven through its own single-column filter API, and the amount of work differs. The comparison guide explains the method, what is left out and why.\n\n## When to choose SvGrid\n\n- You need grouping with aggregation, master/detail, Excel-style range editing or pivot tables, which SVAR's docs do not list.\n- You want a headless engine plus a render component, not a component-only API.\n- You want integrated charts and a full server-side row model in one library.\n- You want in-grid AI helpers, an MCP server that checks generated code, and a paid support tier.\n\n## When to choose SVAR Svelte DataGrid\n\n- You want a fully free grid with print included and no paid tier at all.\n- You ship to React and Vue as well as Svelte and want one grid across them.\n- A smaller bundle matters more than the features above.\n- You are already adopting the wider SVAR suite: Gantt, Calendar, Kanban, File Manager.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid.\n\nWhat you give up:\n\n- Free printing: SVAR's print API is in the MIT grid, SvGrid's print view is in @svgrid/enterprise.\n- The React and Vue versions of the same grid.\n- A smaller bundle, by the measurements in the At a glance table.\n- The SVAR suite around the grid: Gantt, Calendar, Kanban and File Manager share its core.\n\nMigration guide: moving from SVAR Svelte DataGrid to SvGrid: https://svgrid.com/docs/help/migrating-from-svar-svelte-datagrid/\n\n## Live example\n\nGrouping Aggregation: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/07-grouping-aggregation/\n\n## The bottom line\n\nBoth grids are Svelte-5-native and MIT, so this is not a licensing call. On capability SvGrid is the more complete grid: grouping, master/detail, range editing with a fill handle, charts, a server-side row model, a headless core, AI helpers and an MCP server. SVAR is the smaller, fully free, multi-framework option from the Webix team, and it prints for free where SvGrid charges for print and Excel and PDF export. Choose SvGrid when you need the deeper feature set or support; choose SVAR when a compact free grid covers your needs or you also ship React and Vue.\n\n## Frequently asked questions\n\n### SvGrid vs SVAR Svelte DataGrid: what is the difference?\n\nBoth are MIT-licensed, Svelte-5-native grids. SvGrid is the broader product: row grouping with aggregation, master/detail, Excel-style range selection with a fill handle, integrated charts, a server-side row model, a headless core, in-grid AI helpers and an MCP server. SVAR is a smaller, fully free grid with React and Vue versions from XB Software, with CSV export and a print API included.\n\n### Are SvGrid and SVAR both free?\n\nBoth are free under MIT, including commercial use. SVAR keeps the whole grid free, CSV export and print included, and sells PRO editions of its Gantt, Calendar and Kanban. SvGrid's grid is free too, including CSV, TSV and JSON export, charts and the AI helpers; Excel, PDF and print output, import, pivot tables, the Kanban and Scheduler views and support are in @svgrid/enterprise at $599 per developer per year.\n\n### Are both built for Svelte 5?\n\nYes. SvGrid is written in Svelte 5 runes, and svar.dev states the DataGrid is Svelte 5 compatible. Neither is a cross-framework wrapper, although SVAR also ships React and Vue versions of its grid.\n\n### Which grid is smaller?\n\nSVAR, by the measurements in the At a glance table: both packages were built alone with Vite, minified and gzipped with Svelte external, on the dates shown. SvGrid's extra size buys grouping, master/detail, range editing, charts and the server-side row model; features you never import, such as the date editors, menus and charts, load as separate chunks.\n\n### Does SVAR have row grouping, master/detail or cell-range selection?\n\nNot according to its docs overview on the date we read it, which lists tree data, single and multiple row selection, header and advanced filters, sorting, in-cell editing, columns pinned to the left, CSV export and a print API. SvGrid has all three in the MIT core, and the demos on this page show them.\n\n### How long does a SVAR to SvGrid migration take?\n\nThe migration guide budgets two to four hours per grid: a prop and event rename pass, since both use array-of-object column definitions, plus re-theming through --sg-* tokens.\n\n### Is SvGrid a good SVAR Svelte DataGrid alternative for Svelte?\n\nThe closest comparison on this list, since both are Svelte-native and both are MIT, so licensing does not decide it. The differences are depth and direction: SvGrid ships a larger feature surface, a UI component suite, in-grid AI helpers and an MCP server, while SVAR spans Svelte, React and Vue and keeps a smaller core. The At a glance table above has both measured bundle sizes; if a compact MIT grid with sorting, filtering, editing, tree data and CSV export is all you need, SVAR is a perfectly good answer.\n\n## Related comparisons and docs\n\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/)\n- [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/)\n- [SvGrid vs @vincjo/datatables](https://svgrid.com/compare/vincjo-datatables/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Grouping & aggregation](https://svgrid.com/docs/help/grouping-aggregation/)\n- [Master / detail (nested grids)](https://svgrid.com/docs/help/rows/master-detail/)\n- [Build a table from scratch](https://svgrid.com/docs/help/headless/build-a-table/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- svar-datagrid: Licensed under MIT; Svelte 5 compatible; React and Vue versions available; lists multi-column sorting, header filters, in-cell editing, tree data, virtual scrolling, columns pinned to the left, context menu, row drag-and-drop, checkbox selection, pagination, hotkeys, WAI-ARIA, print, undo/redo (checked 12 Sep 2026) https://svar.dev/svelte/datagrid/\n- svar-overview: Feature list: in-cell editing, header and advanced filtering, sorting, single and multiple row selection, row reordering, context menu, undo/redo, tree data, pagination, colspans and rowspans in header and footer, collapsible column groups, pinned columns to the left, auto-sizing of rows and columns, localization, themes, export to CSV, print API, RestDataProvider, virtual scrolling for rows and columns, WAI-ARIA, keyboard navigation; no Excel export, row grouping, aggregation, master/detail, charts, AI or MCP (checked 12 Sep 2026) https://docs.svar.dev/svelte/grid/overview/\n- svar-svelte: DataGrid, Filter, Editor, File Manager and Core are MIT; Gantt, Calendar and Kanban have MIT cores with paid PRO editions; no pivot component in the list; no price list on the page (checked 12 Sep 2026) https://svar.dev/svelte/\n- svar-gantt: Offers paid consulting and custom development services; PRO edition pricing is on a separate page (checked 12 Sep 2026) https://svar.dev/svelte/gantt/\n"
|
|
6978
6978
|
},
|
|
6979
6979
|
{
|
|
6980
6980
|
"slug": "compare/svelte-headless-table",
|
|
6981
6981
|
"path": "docs/_data/comparisons/svelte-headless-table.json",
|
|
6982
6982
|
"title": "SvGrid vs svelte-headless-table",
|
|
6983
6983
|
"section": "Comparisons",
|
|
6984
|
-
"markdown": "# SvGrid vs svelte-headless-table\n\nCanonical URL: https://svgrid.com/compare/svelte-headless-table/\nFacts verified: 2026-09-12\nCompetitor package: svelte-headless-table\nCompetitor site: https://svelte-headless-table.bryanmylee.com/\n\nsvelte-headless-table is the Svelte-native headless table library by Bryan Lee, one of the earliest Svelte-specific table options, now deprecated on Svelte 4.\n\n## Verdict\n\nsvelte-headless-table popularised headless tables in Svelte and still works on Svelte 4. Its author states there are no plans for a Svelte 5 port, so a Svelte 5 upgrade forces the question. SvGrid keeps the headless approach on Svelte 5 runes, adds virtualization and a rendered grid, and the @humanspeak fork is the option if you want to stay headless with the same API.\n\nMigration guide: moving from svelte-headless-table to SvGrid: https://svgrid.com/docs/help/migrating-from-svelte-headless-table/\n\n## At a glance\n\n| Fact | SvGrid | svelte-headless-table | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 0.18.3 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 28 Oct 2024 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Svelte 4 range (peer svelte ^4.0.0) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 90,100 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 5.7 KB JS, no separate stylesheet, svelte external | 12 Sep 2026 |\n| Engine alone, minified + gzip | 2.7 KB JS, no separate stylesheet (`createSvGrid` from `@svgrid/grid/core`) | the row above; the package is the engine | 22 Sep 2026 |\n| Frameworks | Svelte 5 | Svelte | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $599 per developer per year | svelte-headless-table is MIT and free; no paid licence or support is offered, and the author states there are no plans for a Svelte 5 port | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; svelte-headless-table 0.18.3 entry `whole package` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nsvelte-headless-table exposes a createTable function with composable plugins for sorting, filtering, column ordering and hiding, pagination, row selection, expansion, grouping with aggregation and column resizing, and leaves the markup to you. The npm package's peer range is Svelte 4, and the repository README states there are no current plans for a Svelte 5 port. A community fork, @humanspeak/svelte-headless-table, carries the same API on Svelte 5 runes; the At a glance table shows the original's registry facts, and the migration guide has the fork's.\n\nSvGrid takes the same headless approach but is written in Svelte 5 runes, adds a production render component, and covers virtualization, Excel-style filters, cell-range selection with a fill handle, inline editing, master/detail, a server-side row model and integrated charts natively.\n\n## Looking for a svelte-headless-table alternative for Svelte?\n\nThis is the clearest migration case on the list: the original package's peer range is Svelte 4, its last release was in 2024 and the README says there are no plans for a Svelte 5 port nor a maintenance schedule for Svelte 3 and 4. SvGrid keeps the headless approach you already chose and adds runes, virtualization and a render component if you want one. If you would rather keep the plugin API, the maintained community fork @humanspeak/svelte-headless-table targets Svelte 5, and its facts are in the guide.\n\n## What they have in common\n\n- Svelte-specific, not a port from another framework.\n- Headless-first composition: plugins in svelte-headless-table, a features object in SvGrid.\n- Sorting, filtering, pagination, row selection, expansion and grouping with aggregation in the engine.\n- MIT-licensed with a strong TypeScript story.\n\n## Where SvGrid is stronger\n\n- Built on Svelte 5 runes and released continuously; the original package is Svelte 4 only and its author has stopped.\n- A bundled <SvGrid /> component, so nobody assembles headers, body and virtualization by hand.\n- Virtualization on rows and columns built in; svelte-headless-table leaves it to a virtual-list library.\n- Excel-style filter menu, cell-range selection with a fill handle, inline editing, master/detail, a server-side row model and charts in the MIT package.\n- In-grid AI helpers free in @svgrid/grid and @svgrid/mcp for assistants, plus a paid support tier.\n\n## Where svelte-headless-table is stronger\n\n- A smaller bundle if all you want is the engine; the At a glance table has both measured sizes.\n- A plugin API many Svelte 4 codebases already know, and a documentation site that still reads well.\n- The @humanspeak fork keeps that API on Svelte 5 without a rewrite.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | svelte-headless-table |\n| --- | --- | --- |\n| Svelte 5 runes | Yes - native | No - Svelte 4 stores; no Svelte 5 port planned by the author |\n| Maintained release line | Yes | Partial - original deprecated; the @humanspeak fork is maintained on Svelte 5 |\n| Render component | Yes - <SvGrid /> | No - bring your own markup |\n| Headless engine | Yes - createSvGrid and a features object | Yes - createTable and plugins |\n| Sorting and column filtering | Yes | Yes - engine only |\n| Excel-style filter menu | Yes - built in | No - bring your own UI |\n| Cell-range selection and clipboard | Yes - built in, with a fill handle | No - row selection only |\n| Inline editing | Yes - built in | No - not a plugin |\n| Virtualization | Yes - rows and columns, built in | Partial - pair with a virtual-list library |\n| Pagination | Yes | Yes |\n| Row grouping with aggregation | Yes - engine and rendered group rows | Yes - engine only |\n| Row expansion and tree | Yes | Yes - expansion plugin |\n| Column ordering, hiding, resizing | Yes | Yes |\n| Master/detail | Yes | No - not a plugin |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes | No - not a plugin |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise | No - not a plugin |\n| Integrated charts | Yes - SvGridChart | No - not part of a headless engine |\n| In-grid AI helpers and MCP server | Yes - helpers free in @svgrid/grid; @svgrid/mcp, MIT | No - not in the docs |\n| Paid support | Yes - with @svgrid/enterprise, per developer per year | No - none offered |\n\n## When to choose SvGrid\n\n- You are moving to Svelte 5 and want a maintained grid that keeps the headless approach.\n- You want virtualization, an Excel-style filter menu, editing and cell selection without building them.\n- You want a rendered component for the common case and a headless core for the rest.\n- You want a support tier behind the library.\n\n## When to choose svelte-headless-table\n\n- You are staying on Svelte 4 for now and the plugin set already covers you.\n- You want the smallest possible engine and will keep writing the markup yourself.\n- You want the same plugin API on Svelte 5 and are happy to move to the @humanspeak fork.\n\n## Migration effort\n\nEstimated effort: 1-3 hours per grid.\n\nWhat you give up:\n\n- The plugin API and its documentation site, if your team knows it well.\n- The smallest engine-only bundle; the At a glance table has both measured sizes.\n- Nothing in maintenance terms on the original package, which is where most migrations start.\n\nMigration guide: moving from svelte-headless-table to SvGrid: https://svgrid.com/docs/help/migrating-from-svelte-headless-table/\n\n## Live example\n\nHeadless Table: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/186-headless-table/\n\n## The bottom line\n\nFor a Svelte 4 codebase that is not moving, svelte-headless-table still works. For a Svelte 5 codebase, the original package is not an option and its author says so; the choice is between the @humanspeak fork, which keeps the plugin API, and SvGrid, which keeps the headless approach and adds virtualization, filters, editing, selection and a rendered grid in the same MIT package.\n\n## Frequently asked questions\n\n### Does svelte-headless-table work with Svelte 5?\n\nThe original package's peer range is Svelte 4 and its README states there are no current plans for a Svelte 5 port nor a maintenance schedule for Svelte 3 and 4. The community fork @humanspeak/svelte-headless-table targets Svelte 5 with runes; SvGrid is written in Svelte 5 from the first line.\n\n### Can I keep a headless table with SvGrid?\n\nYes. createSvGrid plus the row-model factories is a headless engine; you can drive your own markup as before and adopt the SvGrid component only where you want it. The headless demos on this page show a plain table and a virtualized one.\n\n### Is SvGrid heavier than svelte-headless-table?\n\nYes, by the measurements in the At a glance table, because it ships a rendered grid, a virtualizer, filter menus and editors that a headless engine leaves to you. If you only need the engine and will write the rest, the difference is what you would otherwise write.\n\n### How long does a migration take?\n\nThe migration guide budgets one to three hours per grid; most of the time goes into deleting the markup and plugins the rendered grid replaces. Column definitions and the plugin concepts (sort, filter, page, select, expand, group) map one to one onto SvGrid's features.\n\n### Should I move to the @humanspeak fork instead?\n\nIf you want the same plugin API on Svelte 5 and are happy to keep writing the markup, yes, and its registry facts are in the migration guide. If the upgrade is also a chance to stop maintaining a table layer, SvGrid gives you the rendered grid and keeps the headless core for the cases that need it.\n\n### Is SvGrid a good svelte-headless-table alternative for Svelte?\n\nThis is the clearest migration case on the list: the original package's peer range is Svelte 4, its last release was in 2024 and the README says there are no plans for a Svelte 5 port nor a maintenance schedule for Svelte 3 and 4. SvGrid keeps the headless approach you already chose and adds runes, virtualization and a render component if you want one. If you would rather keep the plugin API, the maintained community fork @humanspeak/svelte-headless-table targets Svelte 5, and its facts are in the guide.\n\n## Related comparisons and docs\n\n- [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/)\n- [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/)\n- [SvGrid vs @vincjo/datatables](https://svgrid.com/compare/vincjo-datatables/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Build a table from scratch](https://svgrid.com/docs/help/headless/build-a-table/)\n- [Headless virtualization](https://svgrid.com/docs/help/headless/virtualization/)\n- [Grouping & aggregation](https://svgrid.com/docs/help/grouping-aggregation/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- sht-github: README: there are no current plans to work on a Svelte 5 port of this project nor is there a maintenance schedule for Svelte 3/4; the project is flagged as deprecated and users are encouraged to seek alternatives or fork (checked 12 Sep 2026) https://github.com/bryanmylee/svelte-headless-table\n- sht-docs: Advertised plugins: multi-sorting, column filtering, global filtering, column reordering, hiding columns, pagination, row grouping and aggregation, row expansion, row selection, column resizing; headless, you write the markup (checked 12 Sep 2026) https://svelte-headless-table.bryanmylee.com/\n- sht-fork: MIT; part of the Humanspeak family of runes-native Svelte 5 packages; the npm package declares a Svelte 5 peer range (checked 12 Sep 2026) https://github.com/humanspeak/svelte-headless-table\n"
|
|
6984
|
+
"markdown": "# SvGrid vs svelte-headless-table\n\nCanonical URL: https://svgrid.com/compare/svelte-headless-table/\nFacts verified: 2026-09-12\nCompetitor package: svelte-headless-table\nCompetitor site: https://svelte-headless-table.bryanmylee.com/\n\nsvelte-headless-table is the Svelte-native headless table library by Bryan Lee, one of the earliest Svelte-specific table options, now deprecated on Svelte 4.\n\n## Verdict\n\nsvelte-headless-table popularised headless tables in Svelte and still works on Svelte 4. Its author states there are no plans for a Svelte 5 port, so a Svelte 5 upgrade forces the question. SvGrid keeps the headless approach on Svelte 5 runes, adds virtualization and a rendered grid, and the @humanspeak fork is the option if you want to stay headless with the same API.\n\nMigration guide: moving from svelte-headless-table to SvGrid: https://svgrid.com/docs/help/migrating-from-svelte-headless-table/\n\n## At a glance\n\n| Fact | SvGrid | svelte-headless-table | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 0.18.3 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 28 Oct 2024 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Svelte 4 range (peer svelte ^4.0.0) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 90,100 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 5.7 KB JS, no separate stylesheet, svelte external | 12 Sep 2026 |\n| Engine alone, minified + gzip | 2.7 KB JS, no separate stylesheet (`createSvGrid` from `@svgrid/grid/core`) | the row above; the package is the engine | 22 Sep 2026 |\n| Frameworks | Svelte 5 | Svelte | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | svelte-headless-table is MIT and free; no paid licence or support is offered, and the author states there are no plans for a Svelte 5 port | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; svelte-headless-table 0.18.3 entry `whole package` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nsvelte-headless-table exposes a createTable function with composable plugins for sorting, filtering, column ordering and hiding, pagination, row selection, expansion, grouping with aggregation and column resizing, and leaves the markup to you. The npm package's peer range is Svelte 4, and the repository README states there are no current plans for a Svelte 5 port. A community fork, @humanspeak/svelte-headless-table, carries the same API on Svelte 5 runes; the At a glance table shows the original's registry facts, and the migration guide has the fork's.\n\nSvGrid takes the same headless approach but is written in Svelte 5 runes, adds a production render component, and covers virtualization, Excel-style filters, cell-range selection with a fill handle, inline editing, master/detail, a server-side row model and integrated charts natively.\n\n## Looking for a svelte-headless-table alternative for Svelte?\n\nThis is the clearest migration case on the list: the original package's peer range is Svelte 4, its last release was in 2024 and the README says there are no plans for a Svelte 5 port nor a maintenance schedule for Svelte 3 and 4. SvGrid keeps the headless approach you already chose and adds runes, virtualization and a render component if you want one. If you would rather keep the plugin API, the maintained community fork @humanspeak/svelte-headless-table targets Svelte 5, and its facts are in the guide.\n\n## What they have in common\n\n- Svelte-specific, not a port from another framework.\n- Headless-first composition: plugins in svelte-headless-table, a features object in SvGrid.\n- Sorting, filtering, pagination, row selection, expansion and grouping with aggregation in the engine.\n- MIT-licensed with a strong TypeScript story.\n\n## Where SvGrid is stronger\n\n- Built on Svelte 5 runes and released continuously; the original package is Svelte 4 only and its author has stopped.\n- A bundled <SvGrid /> component, so nobody assembles headers, body and virtualization by hand.\n- Virtualization on rows and columns built in; svelte-headless-table leaves it to a virtual-list library.\n- Excel-style filter menu, cell-range selection with a fill handle, inline editing, master/detail, a server-side row model and charts in the MIT package.\n- In-grid AI helpers free in @svgrid/grid and @svgrid/mcp for assistants, plus a paid support tier.\n\n## Where svelte-headless-table is stronger\n\n- A smaller bundle if all you want is the engine; the At a glance table has both measured sizes.\n- A plugin API many Svelte 4 codebases already know, and a documentation site that still reads well.\n- The @humanspeak fork keeps that API on Svelte 5 without a rewrite.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | svelte-headless-table |\n| --- | --- | --- |\n| Svelte 5 runes | Yes - native | No - Svelte 4 stores; no Svelte 5 port planned by the author |\n| Maintained release line | Yes | Partial - original deprecated; the @humanspeak fork is maintained on Svelte 5 |\n| Render component | Yes - <SvGrid /> | No - bring your own markup |\n| Headless engine | Yes - createSvGrid and a features object | Yes - createTable and plugins |\n| Sorting and column filtering | Yes | Yes - engine only |\n| Excel-style filter menu | Yes - built in | No - bring your own UI |\n| Cell-range selection and clipboard | Yes - built in, with a fill handle | No - row selection only |\n| Inline editing | Yes - built in | No - not a plugin |\n| Virtualization | Yes - rows and columns, built in | Partial - pair with a virtual-list library |\n| Pagination | Yes | Yes |\n| Row grouping with aggregation | Yes - engine and rendered group rows | Yes - engine only |\n| Row expansion and tree | Yes | Yes - expansion plugin |\n| Column ordering, hiding, resizing | Yes | Yes |\n| Master/detail | Yes | No - not a plugin |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes | No - not a plugin |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise | No - not a plugin |\n| Integrated charts | Yes - SvGridChart | No - not part of a headless engine |\n| In-grid AI helpers and MCP server | Yes - helpers free in @svgrid/grid; @svgrid/mcp, MIT | No - not in the docs |\n| Paid support | Yes - with @svgrid/enterprise, per developer per year | No - none offered |\n\n## When to choose SvGrid\n\n- You are moving to Svelte 5 and want a maintained grid that keeps the headless approach.\n- You want virtualization, an Excel-style filter menu, editing and cell selection without building them.\n- You want a rendered component for the common case and a headless core for the rest.\n- You want a support tier behind the library.\n\n## When to choose svelte-headless-table\n\n- You are staying on Svelte 4 for now and the plugin set already covers you.\n- You want the smallest possible engine and will keep writing the markup yourself.\n- You want the same plugin API on Svelte 5 and are happy to move to the @humanspeak fork.\n\n## Migration effort\n\nEstimated effort: 1-3 hours per grid.\n\nWhat you give up:\n\n- The plugin API and its documentation site, if your team knows it well.\n- The smallest engine-only bundle; the At a glance table has both measured sizes.\n- Nothing in maintenance terms on the original package, which is where most migrations start.\n\nMigration guide: moving from svelte-headless-table to SvGrid: https://svgrid.com/docs/help/migrating-from-svelte-headless-table/\n\n## Live example\n\nHeadless Table: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/186-headless-table/\n\n## The bottom line\n\nFor a Svelte 4 codebase that is not moving, svelte-headless-table still works. For a Svelte 5 codebase, the original package is not an option and its author says so; the choice is between the @humanspeak fork, which keeps the plugin API, and SvGrid, which keeps the headless approach and adds virtualization, filters, editing, selection and a rendered grid in the same MIT package.\n\n## Frequently asked questions\n\n### Does svelte-headless-table work with Svelte 5?\n\nThe original package's peer range is Svelte 4 and its README states there are no current plans for a Svelte 5 port nor a maintenance schedule for Svelte 3 and 4. The community fork @humanspeak/svelte-headless-table targets Svelte 5 with runes; SvGrid is written in Svelte 5 from the first line.\n\n### Can I keep a headless table with SvGrid?\n\nYes. createSvGrid plus the row-model factories is a headless engine; you can drive your own markup as before and adopt the SvGrid component only where you want it. The headless demos on this page show a plain table and a virtualized one.\n\n### Is SvGrid heavier than svelte-headless-table?\n\nYes, by the measurements in the At a glance table, because it ships a rendered grid, a virtualizer, filter menus and editors that a headless engine leaves to you. If you only need the engine and will write the rest, the difference is what you would otherwise write.\n\n### How long does a migration take?\n\nThe migration guide budgets one to three hours per grid; most of the time goes into deleting the markup and plugins the rendered grid replaces. Column definitions and the plugin concepts (sort, filter, page, select, expand, group) map one to one onto SvGrid's features.\n\n### Should I move to the @humanspeak fork instead?\n\nIf you want the same plugin API on Svelte 5 and are happy to keep writing the markup, yes, and its registry facts are in the migration guide. If the upgrade is also a chance to stop maintaining a table layer, SvGrid gives you the rendered grid and keeps the headless core for the cases that need it.\n\n### Is SvGrid a good svelte-headless-table alternative for Svelte?\n\nThis is the clearest migration case on the list: the original package's peer range is Svelte 4, its last release was in 2024 and the README says there are no plans for a Svelte 5 port nor a maintenance schedule for Svelte 3 and 4. SvGrid keeps the headless approach you already chose and adds runes, virtualization and a render component if you want one. If you would rather keep the plugin API, the maintained community fork @humanspeak/svelte-headless-table targets Svelte 5, and its facts are in the guide.\n\n## Related comparisons and docs\n\n- [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/)\n- [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/)\n- [SvGrid vs @vincjo/datatables](https://svgrid.com/compare/vincjo-datatables/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Build a table from scratch](https://svgrid.com/docs/help/headless/build-a-table/)\n- [Headless virtualization](https://svgrid.com/docs/help/headless/virtualization/)\n- [Grouping & aggregation](https://svgrid.com/docs/help/grouping-aggregation/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- sht-github: README: there are no current plans to work on a Svelte 5 port of this project nor is there a maintenance schedule for Svelte 3/4; the project is flagged as deprecated and users are encouraged to seek alternatives or fork (checked 12 Sep 2026) https://github.com/bryanmylee/svelte-headless-table\n- sht-docs: Advertised plugins: multi-sorting, column filtering, global filtering, column reordering, hiding columns, pagination, row grouping and aggregation, row expansion, row selection, column resizing; headless, you write the markup (checked 12 Sep 2026) https://svelte-headless-table.bryanmylee.com/\n- sht-fork: MIT; part of the Humanspeak family of runes-native Svelte 5 packages; the npm package declares a Svelte 5 peer range (checked 12 Sep 2026) https://github.com/humanspeak/svelte-headless-table\n"
|
|
6985
6985
|
},
|
|
6986
6986
|
{
|
|
6987
6987
|
"slug": "compare/svelte-ui-kit-tables",
|
|
6988
6988
|
"path": "docs/_data/comparisons/svelte-ui-kit-tables.json",
|
|
6989
6989
|
"title": "SvGrid vs Flowbite / Skeleton / shadcn-svelte tables",
|
|
6990
6990
|
"section": "Comparisons",
|
|
6991
|
-
"markdown": "# SvGrid vs Flowbite / Skeleton / shadcn-svelte tables\n\nCanonical URL: https://svgrid.com/compare/svelte-ui-kit-tables/\nFacts verified: 2026-09-12\nCompetitor site: https://flowbite-svelte.com/docs/components/table\n\nFlowbite-Svelte, Skeleton, and shadcn-svelte ship styled table components - great for static tables, not data grids.\n\n## Verdict\n\nUI-kit tables are perfect for small, mostly-static tables that match your design system. Reach for SvGrid the moment you need sorting, filtering, virtualization, editing, or large datasets.\n\nMigration guide: moving from Flowbite / Skeleton / shadcn-svelte tables to SvGrid: https://svgrid.com/docs/help/migrating-from-ui-kit-tables/\n\n## At a glance\n\n| Fact | SvGrid | Flowbite / Skeleton / shadcn-svelte tables | Checked |\n| --- | --- | --- | --- |\n| Frameworks | Svelte 5 | Svelte | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6991
|
+
"markdown": "# SvGrid vs Flowbite / Skeleton / shadcn-svelte tables\n\nCanonical URL: https://svgrid.com/compare/svelte-ui-kit-tables/\nFacts verified: 2026-09-12\nCompetitor site: https://flowbite-svelte.com/docs/components/table\n\nFlowbite-Svelte, Skeleton, and shadcn-svelte ship styled table components - great for static tables, not data grids.\n\n## Verdict\n\nUI-kit tables are perfect for small, mostly-static tables that match your design system. Reach for SvGrid the moment you need sorting, filtering, virtualization, editing, or large datasets.\n\nMigration guide: moving from Flowbite / Skeleton / shadcn-svelte tables to SvGrid: https://svgrid.com/docs/help/migrating-from-ui-kit-tables/\n\n## At a glance\n\n| Fact | SvGrid | Flowbite / Skeleton / shadcn-svelte tables | Checked |\n| --- | --- | --- | --- |\n| Frameworks | Svelte 5 | Svelte | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | Flowbite Svelte, Skeleton and shadcn-svelte are MIT component libraries; their table components are free and no grid licence is sold | 12 Sep 2026 |\n\n## Overview\n\nFlowbite-Svelte, Skeleton, and shadcn-svelte all provide beautifully styled table components. They render the rows you pass in and match your design tokens, but they are presentation components - sorting, filtering, virtualization, and editing are yours to build.\n\nSvGrid is a data grid: the table behaviors (sort, Excel-style filter, group, virtualize, edit, select) are the product. Style it with your own tokens or Tailwind so it still fits the design system.\n\n## Looking for a Flowbite / Skeleton / shadcn-svelte tables alternative for Svelte?\n\nA styled table component and a data grid solve different problems. These kits give you markup that already matches your design system; they do not virtualize, edit in place, group rows or talk to a server. SvGrid does those and is themed through CSS custom properties, so it can be made to match the same design system rather than replacing it.\n\n## What they have in common\n\n- Render tabular data in Svelte.\n- MIT-licensed.\n- Themeable to match a design system.\n\n## Where SvGrid is stronger\n\n- Sorting, filtering, grouping, and pagination are built in, not hand-rolled.\n- Row + column virtualization for thousands of rows.\n- Inline editing, cell selection, and clipboard.\n- Headless engine + imperative API + @svgrid/mcp.\n- Still fully themeable via --sg-* tokens / Tailwind.\n\n## Where Flowbite / Skeleton / shadcn-svelte tables is stronger\n\n- Zero learning curve for a small, static table.\n- Pixel-perfect match with the rest of the UI kit out of the box.\n- Tiny footprint when you truly only need a styled table.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Flowbite / Skeleton / shadcn-svelte tables |\n| --- | --- | --- |\n| Built-in sorting | Yes | No - BYO |\n| Built-in filtering | Yes | No - BYO |\n| Virtualization (1000s of rows) | Yes | No |\n| Inline editing | Yes | No - BYO |\n| Grouping / tree / master-detail | Yes | No |\n| Cell selection + copy | Yes | No |\n| Design-system theming | Yes - --sg-* / Tailwind | Yes - Native to the kit |\n| Footprint for a static table | Partial - Larger | Yes - Tiny |\n\n## When to choose SvGrid\n\n- Your table needs sorting, filtering, or large-dataset virtualization.\n- You need inline editing, selection, grouping, or tree data.\n- The table is becoming the centre of the screen, not a layout detail.\n\n## When to choose Flowbite / Skeleton / shadcn-svelte tables\n\n- You render a small, static table that never sorts or filters.\n- You want a pixel-perfect match with your UI kit and nothing more.\n- Bundle size for a trivial table is the priority.\n\n## Migration effort\n\nEstimated effort: 30 minutes to 1 hour per table.\n\nWhat you give up:\n\n- A table that is exactly the kit's markup and nothing else.\n- The smallest possible footprint for a static table.\n\nMigration guide: moving from Flowbite / Skeleton / shadcn-svelte tables to SvGrid: https://svgrid.com/docs/help/migrating-from-ui-kit-tables/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\nA styled table from Flowbite, Skeleton, or shadcn-svelte is perfect until the behaviour becomes the work. Once you are hand-writing sort, filter, or virtualization, SvGrid replaces that code and still themes to match your design system.\n\n## Frequently asked questions\n\n### When should I replace a UI-kit table with SvGrid?\n\nWhen the table needs sorting, filtering, virtualization, editing, or large datasets. UI-kit tables are presentation components; SvGrid is a data grid.\n\n### Can SvGrid match my Flowbite or shadcn styling?\n\nYes - it themes through --sg-* CSS variables you can wire to your Tailwind or design-system tokens.\n\n### Is SvGrid overkill for a static table?\n\nFor a small static table, a styled table element is lighter and fine. Switch when behaviour, not just styling, becomes the work.\n\n### Is SvGrid a good Flowbite / Skeleton / shadcn-svelte tables alternative for Svelte?\n\nA styled table component and a data grid solve different problems. These kits give you markup that already matches your design system; they do not virtualize, edit in place, group rows or talk to a server. SvGrid does those and is themed through CSS custom properties, so it can be made to match the same design system rather than replacing it.\n\n## Related comparisons and docs\n\n- [SvGrid vs @vincjo/datatables](https://svgrid.com/compare/vincjo-datatables/)\n- [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/)\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [shadcn-svelte integration](https://svgrid.com/docs/help/shadcn/)\n- [Tailwind integration](https://svgrid.com/docs/help/tailwind/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- flowbite-readme: The official Flowbite UI component library for Svelte, MIT; a Table is one of its styled Tailwind components (checked 12 Sep 2026) https://github.com/themesberg/flowbite-svelte\n"
|
|
6992
6992
|
},
|
|
6993
6993
|
{
|
|
6994
6994
|
"slug": "compare/syncfusion-grid",
|
|
6995
6995
|
"path": "docs/_data/comparisons/syncfusion-grid.json",
|
|
6996
6996
|
"title": "SvGrid vs Syncfusion Grid",
|
|
6997
6997
|
"section": "Comparisons",
|
|
6998
|
-
"markdown": "# SvGrid vs Syncfusion Grid\n\nCanonical URL: https://svgrid.com/compare/syncfusion-grid/\nFacts verified: 2026-09-12\nCompetitor package: @syncfusion/ej2-grids\nCompetitor site: https://www.syncfusion.com/javascript-ui-controls/js-data-grid\n\nSyncfusion Grid is a comprehensive commercial grid available across JavaScript, React, Vue, Angular, and Blazor, with a community license.\n\n## Verdict\n\nSyncfusion is an enormous commercial suite with a free community license for small teams. SvGrid is Svelte-5-native with an MIT core and no revenue / headcount conditions.\n\nMigration guide: moving from Syncfusion Grid to SvGrid: https://svgrid.com/docs/help/migrating-from-syncfusion/\n\n## At a glance\n\n| Fact | SvGrid | Syncfusion Grid | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 34.2.7 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 8 Sep 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript, React, Angular, Vue, Blazor) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 711,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript, React, Angular, Vue, Blazor | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
6998
|
+
"markdown": "# SvGrid vs Syncfusion Grid\n\nCanonical URL: https://svgrid.com/compare/syncfusion-grid/\nFacts verified: 2026-09-12\nCompetitor package: @syncfusion/ej2-grids\nCompetitor site: https://www.syncfusion.com/javascript-ui-controls/js-data-grid\n\nSyncfusion Grid is a comprehensive commercial grid available across JavaScript, React, Vue, Angular, and Blazor, with a community license.\n\n## Verdict\n\nSyncfusion is an enormous commercial suite with a free community license for small teams. SvGrid is Svelte-5-native with an MIT core and no revenue / headcount conditions.\n\nMigration guide: moving from Syncfusion Grid to SvGrid: https://svgrid.com/docs/help/migrating-from-syncfusion/\n\n## At a glance\n\n| Fact | SvGrid | Syncfusion Grid | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 34.2.7 | 12 Sep 2026 |\n| Licence field on npm | MIT | Commercial (see licence file) | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 8 Sep 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript, React, Angular, Vue, Blazor) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 711,000 | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript, React, Angular, Vue, Blazor | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | syncfusion.com lists the Grid SDK at $959 per developer per year and the UI Component Suite at $1,199 per developer per year, minimum five developers; a free Community License applies to companies and individuals with under $1M annual revenue, up to five developers and no more than ten employees | 12 Sep 2026 |\n\n## Overview\n\nSyncfusion Grid is part of the Essential Studio suite - a very deep grid (grouping, aggregates, editing, export, filtering, virtualization) across JavaScript, React, Vue, Angular, and Blazor. It is commercially licensed, with a free community license for individuals and small companies under a revenue / headcount threshold.\n\nSvGrid focuses on Svelte 5 with an MIT community core - free for everyone, with no revenue or team-size conditions - plus an optional Enterprise pack for export / import / pivot / AI.\n\n## Looking for a Syncfusion Grid alternative for Svelte?\n\nSyncfusion is comprehensive, and its community licence carries revenue and headcount conditions, which is often what sends people looking. The SvGrid core is MIT with no such conditions. Syncfusion still ships far more components across far more platforms, Blazor included, and that breadth is the real trade you are making.\n\n## What they have in common\n\n- Very deep grid feature set.\n- Editing, grouping, aggregates, filtering, virtualization.\n- Export (SvGrid via the Enterprise pack).\n- Paid support available.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native rather than a multi-framework commercial suite.\n- MIT core - no revenue / headcount conditions like the community license.\n- Headless engine + imperative API + @svgrid/mcp.\n- No design-system lock-in.\n\n## Where Syncfusion Grid is stronger\n\n- One of the largest feature sets and component suites available.\n- Parity across JS / React / Vue / Angular / Blazor.\n- Free community license for qualifying small teams.\n- Enterprise support and long track record.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Syncfusion Grid |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - JavaScript, React, Vue, Angular and Blazor packages |\n| License | Yes - MIT (no conditions) | Paid tier - per developer per year; a conditional free Community License |\n| Grouping + aggregates | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Virtualization | Yes | Yes |\n| Export | Yes - @svgrid/enterprise | Yes - Built in |\n| Headless engine | Yes | No |\n| AI / MCP integration | Yes | No |\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a native grid.\n- You want an unconditional MIT license, not a revenue-gated community license.\n- You want a headless engine and an MCP server.\n\n## When to choose Syncfusion Grid\n\n- You need the breadth of the Syncfusion suite across many frameworks.\n- You qualify for and prefer the free community license.\n- You need Blazor or a single vendor across your whole stack.\n\n## Migration effort\n\nEstimated effort: 3-6 hours per grid.\n\nWhat you give up:\n\n- The Syncfusion suite across JavaScript, React, Vue, Angular and Blazor under one licence.\n- Vendor support and the conditional free Community License for small companies.\n\nMigration guide: moving from Syncfusion Grid to SvGrid: https://svgrid.com/docs/help/migrating-from-syncfusion/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\nSyncfusion offers one of the largest suites and a free community license for small teams - but with revenue and headcount conditions. The MIT core of SvGrid is free for everyone with no conditions, and is the native fit for Svelte 5.\n\n## Frequently asked questions\n\n### Is SvGrid free, unlike the Syncfusion commercial license?\n\nYes - @svgrid/grid is MIT with no revenue or team-size conditions. The Syncfusion community license is free only for qualifying small teams.\n\n### SvGrid vs Syncfusion Grid - which for Svelte?\n\nSvGrid is Svelte-5-native; Syncfusion is a multi-framework commercial suite. For a Svelte stack, SvGrid is the lighter, unconditional-MIT fit.\n\n### Does SvGrid support Blazor like Syncfusion?\n\nNo - SvGrid is Svelte 5 only. If you need Blazor, Syncfusion is the better fit.\n\n### Is SvGrid a good Syncfusion Grid alternative for Svelte?\n\nSyncfusion is comprehensive, and its community licence carries revenue and headcount conditions, which is often what sends people looking. The SvGrid core is MIT with no such conditions. Syncfusion still ships far more components across far more platforms, Blazor included, and that breadth is the real trade you are making.\n\n## Related comparisons and docs\n\n- [SvGrid vs Kendo UI Grid (Telerik)](https://svgrid.com/compare/kendo-ui-grid/)\n- [SvGrid vs DevExtreme DataGrid (DevExpress)](https://svgrid.com/compare/devextreme-datagrid/)\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Grouping & aggregation](https://svgrid.com/docs/help/grouping-aggregation/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- sf-pricing: Grid SDK $959 per developer per year; UI Component Suite $1,199 per developer per year; minimum 5 developers; Community License for under $1M revenue, up to 5 developers, no more than 10 employees, under $3M outside funding (checked 12 Sep 2026) https://www.syncfusion.com/sales/products\n"
|
|
6999
6999
|
},
|
|
7000
7000
|
{
|
|
7001
7001
|
"slug": "compare/tabulator",
|
|
7002
7002
|
"path": "docs/_data/comparisons/tabulator.json",
|
|
7003
7003
|
"title": "SvGrid vs Tabulator",
|
|
7004
7004
|
"section": "Comparisons",
|
|
7005
|
-
"markdown": "# SvGrid vs Tabulator\n\nCanonical URL: https://svgrid.com/compare/tabulator/\nFacts verified: 2026-09-12\nCompetitor package: tabulator-tables\nCompetitor site: https://tabulator.info/\n\nTabulator is a feature-rich, framework-agnostic vanilla-JS interactive table library, MIT-licensed.\n\n## Verdict\n\nTabulator is enormously capable and free, but it is vanilla JS you wire into Svelte imperatively. SvGrid delivers a similar feature surface as a Svelte-5-native component with reactive data binding.\n\nMigration guide: moving from Tabulator to SvGrid: https://svgrid.com/docs/help/migrating-from-tabulator/\n\n## At a glance\n\n| Fact | SvGrid | Tabulator | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 6.5.2 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 23 Jun 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 672,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 106.9 KB JS + 3.8 KB CSS | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
7005
|
+
"markdown": "# SvGrid vs Tabulator\n\nCanonical URL: https://svgrid.com/compare/tabulator/\nFacts verified: 2026-09-12\nCompetitor package: tabulator-tables\nCompetitor site: https://tabulator.info/\n\nTabulator is a feature-rich, framework-agnostic vanilla-JS interactive table library, MIT-licensed.\n\n## Verdict\n\nTabulator is enormously capable and free, but it is vanilla JS you wire into Svelte imperatively. SvGrid delivers a similar feature surface as a Svelte-5-native component with reactive data binding.\n\nMigration guide: moving from Tabulator to SvGrid: https://svgrid.com/docs/help/migrating-from-tabulator/\n\n## At a glance\n\n| Fact | SvGrid | Tabulator | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 6.5.2 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 23 Jun 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | No Svelte package (JavaScript) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 672,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 106.9 KB JS + 3.8 KB CSS | 12 Sep 2026 |\n| Frameworks | Svelte 5 | JavaScript | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | Tabulator is MIT and free; no licence or support plan is sold | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; tabulator-tables 6.5.2 entry `TabulatorFull` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nTabulator packs a huge feature set - sorting, filtering, grouping, editing, tree data, formatters, and more - into a framework-agnostic vanilla-JS library. You instantiate it against a DOM element and drive it through its imperative API.\n\nSvGrid covers the same ground but as a Svelte 5 component: data is a reactive `$state` array, cells are snippets, and the imperative API is there when you want it - no manual mount/teardown or DOM bridging.\n\n## Looking for a Tabulator alternative for Svelte?\n\nTabulator is mature, MIT and framework-agnostic, and the reason people move is usually reactivity: it owns its own DOM, so Svelte state and table state have to be kept in sync by hand. SvGrid is driven by your runes directly. Tabulator still wins on breadth of built-in features and on being usable from plain HTML with no build step.\n\n## What they have in common\n\n- Broad feature set: sort, filter, group, edit, tree, format.\n- MIT-licensed / free for commercial use.\n- Virtualized rendering for large datasets.\n- Rich, mature documentation.\n\n## Where SvGrid is stronger\n\n- Svelte 5 native - reactive data binding, no imperative mount/teardown.\n- Custom cells are Svelte snippets, not HTML-string formatters.\n- Headless engine available in addition to the component.\n- @svgrid/mcp MCP server for AI assistants.\n\n## Where Tabulator is stronger\n\n- Framework-agnostic - the same library across vanilla, React, Vue, Angular.\n- Very large built-in formatter / editor catalogue.\n- Long track record and a big community.\n- No build step required to drop into a plain HTML page.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | Tabulator |\n| --- | --- | --- |\n| Svelte 5 native | Yes | No - vanilla JavaScript |\n| Reactive data binding | Yes - $state | Partial - Imperative setData() |\n| Custom cells | Yes - Snippets / components | Partial - HTML-string formatters |\n| Sort / filter / group | Yes | Yes |\n| Inline editing | Yes | Yes |\n| Tree data | Yes | Yes |\n| Virtualization | Yes | Yes |\n| Headless engine | Yes | No |\n| AI / MCP integration | Yes | No |\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want reactive data, not imperative setData calls.\n- You want Svelte snippets for custom cells instead of HTML strings.\n- You want a headless engine option and an MCP server.\n\n## When to choose Tabulator\n\n- You need one table library across vanilla JS, React, Vue, and Angular.\n- You want a no-build-step drop-in for a plain HTML page.\n- You rely on a specific Tabulator formatter / module.\n\n## Migration effort\n\nEstimated effort: 2-4 hours per grid.\n\nWhat you give up:\n\n- One library for plain JavaScript pages as well as React, Angular and Vue.\n- Built-in download to CSV, XLSX and PDF without a paid pack; SvGrid has CSV free and Excel and PDF in @svgrid/enterprise.\n\nMigration guide: moving from Tabulator to SvGrid: https://svgrid.com/docs/help/migrating-from-tabulator/\n\n## Live example\n\nExcel Filters: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/03-excel-filters/\n\n## The bottom line\n\nTabulator is a free, feature-packed table that runs anywhere. If your app is Svelte 5, SvGrid gives you a comparable feature set with reactive data binding and snippet cells instead of imperative setData and HTML-string formatters.\n\n## Frequently asked questions\n\n### SvGrid vs Tabulator for Svelte - which is better?\n\nFor Svelte 5, SvGrid: reactive $state data and Svelte snippet cells, with no imperative mount or teardown. Tabulator wins if you need one library across vanilla JS, React, Vue, and Angular.\n\n### Is SvGrid free like Tabulator?\n\nYes - the core is MIT, like Tabulator. Only the optional @svgrid/enterprise pack is paid.\n\n### Can I reuse Tabulator formatters in SvGrid?\n\nYou re-create them as Svelte snippets via renderSnippet, which is more flexible than HTML-string formatters.\n\n### Is SvGrid a good Tabulator alternative for Svelte?\n\nTabulator is mature, MIT and framework-agnostic, and the reason people move is usually reactivity: it owns its own DOM, so Svelte state and table state have to be kept in sync by hand. SvGrid is driven by your runes directly. Tabulator still wins on breadth of built-in features and on being usable from plain HTML with no build step.\n\n## Related comparisons and docs\n\n- [SvGrid vs Grid.js](https://svgrid.com/compare/gridjs/)\n- [SvGrid vs Smart.Grid (Smart Web Components)](https://svgrid.com/compare/smart-grid/)\n- [SvGrid vs AG Grid (community + enterprise)](https://svgrid.com/compare/ag-grid/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Cell components](https://svgrid.com/docs/help/cells/cell-components/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- tabulator-readme: MIT; a vanilla JavaScript library that builds interactive tables from HTML tables, arrays or JSON, with support for React, Angular and Vue; installed as tabulator-tables (checked 12 Sep 2026) https://github.com/olifolkerd/tabulator\n"
|
|
7006
7006
|
},
|
|
7007
7007
|
{
|
|
7008
7008
|
"slug": "compare/tanstack-table",
|
|
7009
7009
|
"path": "docs/_data/comparisons/tanstack-table.json",
|
|
7010
7010
|
"title": "SvGrid vs TanStack Table (Svelte)",
|
|
7011
7011
|
"section": "Comparisons",
|
|
7012
|
-
"markdown": "# SvGrid vs TanStack Table (Svelte)\n\nCanonical URL: https://svgrid.com/compare/tanstack-table/\nFacts verified: 2026-09-12\nCompetitor package: @tanstack/svelte-table\nCompetitor site: https://tanstack.com/table/latest\n\nTanStack Table is the headless table engine with adapters for React, Vue, Svelte, Solid, Qwik and Lit; you bring the markup.\n\n## Verdict\n\nThe closest peer to SvGrid's headless core. SvGrid ships a rendered component on top of the same kind of engine, in Svelte 5 runes; TanStack stays framework-agnostic and asks you to build and maintain the DOM, the virtualizer, the filter menus and the editors yourself.\n\nMigration guide: moving from TanStack Table (Svelte) to SvGrid: https://svgrid.com/docs/help/migrating-from-tanstack-table/\n\n## At a glance\n\n| Fact | SvGrid | TanStack Table (Svelte) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 9.2.4 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 28 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Yes (peer svelte ^5.0.0) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 231,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 36.3 KB JS, no separate stylesheet, svelte external | 12 Sep 2026 |\n| Engine alone, minified + gzip | 2.7 KB JS, no separate stylesheet (`createSvGrid` from `@svgrid/grid/core`) | the row above; the package is the engine | 22 Sep 2026 |\n| Frameworks | Svelte 5 | Svelte, React, Vue, Solid, Qwik, Lit | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $599 per developer per year | TanStack Table is MIT and free; tanstack.com is sponsor-supported and offers Enterprise Support as private consulting and expert support, with no licence sold for the table | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; @tanstack/svelte-table 9.2.4 entry `whole package` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nTanStack Table is the canonical headless table library: it provides the data pipeline (filter, sort, group, expand, paginate, select) and leaves the markup to you. The v9 line ships a Svelte adapter, @tanstack/svelte-table, whose peer dependency range is Svelte 5, with createTable and getters for reactive data instead of the stores the v8 adapter used.\n\nSvGrid covers the same headless surface (createSvGrid, row models, a features object) and adds a full render component with virtualization, Excel-style filters, inline editing, cell-range selection with a fill handle, grouping with aggregation, master/detail, a server-side row model and integrated charts, all in the MIT package.\n\n## Looking for a TanStack Table alternative for Svelte?\n\nPeople arrive here wanting less glue code, and that is the trade: you keep a headless engine with row models and composable features, and you stop hand-building the DOM, the virtualizer, the filter menus and the editors. If you need one table engine across React and Svelte, stay where you are; that portability is exactly what SvGrid gives up.\n\n## What they have in common\n\n- Headless-first architecture with row-model factories and a features object.\n- Composable features: sorting, filtering, grouping, pagination, expansion, selection.\n- TypeScript-first, MIT-licensed, with paid support available from the maintainers.\n- A createTable / createSvGrid entry point that takes columns, data and features.\n- Svelte 5 in both: runes in SvGrid, a Svelte 5 peer range in the TanStack adapter.\n\n## Where SvGrid is stronger\n\n- Ships <SvGrid />: a production render component with virtualization, Excel-style filters, cell-range selection, inline editing, grouping, master/detail and pagination. With TanStack Table you build all of this.\n- The headless core is written in Svelte 5 runes; the TanStack adapter wraps a framework-agnostic core.\n- An imperative API (SvGridApi) for adding rows, setting filters and mutating columns from outside the component.\n- A gallery of runnable examples that covers every feature, and per-feature docs pages with embedded demos.\n- In-grid AI helpers free in @svgrid/grid, and @svgrid/mcp so assistants fetch real example sources and can check the code they write.\n- A paid pack with Excel, PDF and print output, import, pivot tables and support.\n\n## Where TanStack Table (Svelte) is stronger\n\n- A far larger community; the At a glance table has the download counts side by side.\n- Multi-framework parity: if your shop has React, Vue and Svelte apps, the API stays consistent.\n- A smaller bundle when all you want is the engine; the At a glance table has both measured sizes.\n- Framework-specific documentation for each adapter and years of production use in large companies.\n- Enterprise Support as private consulting, and sponsor perks such as priority issue requests.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | TanStack Table (Svelte) |\n| --- | --- | --- |\n| Headless engine | Yes - createSvGrid | Yes - createTable |\n| Render component (drop-in) | Yes - <SvGrid /> | No - bring your own markup |\n| Svelte 5 | Yes - runes throughout | Yes - the adapter's peer range is Svelte 5 |\n| Row virtualization | Yes - built in | Partial - pair with @tanstack/svelte-virtual |\n| Column virtualization | Yes - built in | Partial - pair with @tanstack/svelte-virtual |\n| Excel-style filter menu | Yes - built in | No - filtering logic only; the UI is yours |\n| Inline editing | Yes - enableInlineEditing | No - bring your own |\n| Cell-range selection and clipboard | Yes - enableCellSelection, fill handle | No - bring your own |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes - createServerDataSource: page or infinite block scroll | Yes - manual sorting, filtering and pagination flags |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise | No - the engine has no server row model; the app fetches per group |\n| Master/detail and tree | Yes | Yes - expansion and subRows |\n| Grouping with aggregation | Yes - engine and rendered group rows | Yes - engine only |\n| Integrated charts | Yes - SvGridChart | No - not part of a headless engine |\n| WAI-ARIA helpers | Yes - exported, and applied by <SvGrid /> | Partial - your markup, your ARIA |\n| In-grid AI helpers and MCP server | Yes - helpers free in @svgrid/grid; @svgrid/mcp, MIT | No - not in the docs |\n| Multi-framework support | No - Svelte only | Yes - React, Vue, Svelte, Solid, Qwik, Lit |\n| Paid support tier | Yes - with @svgrid/enterprise, per developer per year | Yes - Enterprise Support (private consulting) and sponsor perks such as priority issues |\n\n## Measured performance\n\nMeasured 12 Sep 2026 with the harness in the repository (pnpm bench:compare): 100,000 rows, fastest of 7 samples per operation, each grid in a fresh page, Chromium through Playwright, headless, on win32 10.0.26200 x64, Intel(R) Core(TM) Ultra 7 255U; a developer workstation, not a dedicated bench rig. Versions: @svgrid/grid 3.0.3, @tanstack/svelte-table 9.2.4. Lower is better.\n\n| Operation | SvGrid | TanStack Table (Svelte) |\n| --- | --- | --- |\n| Mount | 75.5 ms | 196 ms |\n| Sort, text column | 149 ms | 466 ms |\n| Sort, numeric column | 115.7 ms | 374.6 ms |\n| Filter, one column (indicative only) | 99.6 ms | 111.7 ms |\n| Scroll, p95 frame | 34.6 ms | 35.3 ms |\n| Rows kept in the DOM (virtualization on) | 27 | 27 |\n\nThe filter row is not like for like: each grid is driven through its own single-column filter API, and the amount of work differs. The comparison guide explains the method, what is left out and why.\n\nTanStack Table renders nothing, so its adapter draws the row model through a minimal fixed-height windowed table with no virtualizer library, filter UI or editors; the numbers are the engine plus that DOM.\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a grid that uses runes idiomatically, headless or rendered.\n- You want a drop-in <SvGrid /> with virtualization, filters, editing and selection working in one prop pass.\n- You want AI tools to give accurate answers about your grid through MCP, and to have their code checked.\n- You want paid support available without switching libraries later.\n\n## When to choose TanStack Table (Svelte)\n\n- You ship to multiple frameworks (React, Vue, Svelte) and want one API across them.\n- You explicitly want a headless library and intend to build your own render layer.\n- You want the smallest possible engine and the largest possible community.\n- A shadcn-svelte data table built on TanStack already does what you need.\n\n## Migration effort\n\nEstimated effort: About 30 minutes per read-only grid, 2-4 hours for editing-heavy grids.\n\nWhat you give up:\n\n- One table engine across React, Vue, Svelte, Solid, Qwik and Lit.\n- The smallest engine-only bundle; the At a glance table has both measured sizes.\n- The TanStack ecosystem around the table: Virtual, Query and the shadcn-svelte data table recipe.\n\nMigration guide: moving from TanStack Table (Svelte) to SvGrid: https://svgrid.com/docs/help/migrating-from-tanstack-table/\n\n## Live example\n\nHeadless Table: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/186-headless-table/\n\n## The bottom line\n\nIf you build across React, Vue and Svelte and want one headless API, TanStack Table is the safer bet. If you are committed to Svelte 5 and want virtualization, Excel-style filters, editing and selection out of the box, SvGrid gets you there with far less code, and you keep a headless core when you need it.\n\n## Frequently asked questions\n\n### Is SvGrid better than TanStack Table for Svelte?\n\nFor a Svelte 5 app, SvGrid is usually the faster path: it ships a virtualized render component with built-in filters, editing and accessibility, so there is no DOM layer to write. The TanStack Svelte adapter is Svelte 5 in its v9 line, but it is headless by design; you still build and maintain the table, virtualization and editing UI. TanStack wins if you need one API across several frameworks, or if owning that markup is the point.\n\n### Can I keep a headless setup like TanStack Table?\n\nYes. createSvGrid plus the row-model factories is a headless engine; you can drive your own markup exactly as with TanStack and adopt the SvGrid component only where you want it. The headless docs and the headless demos on this page show both.\n\n### Does the TanStack Svelte adapter support Svelte 5?\n\nYes. The @tanstack/svelte-table package on npm declares a Svelte 5 peer range in its v9 line and its examples pass data through getters rather than stores. The At a glance table shows the version and the peer range as read from the registry.\n\n### How long is a TanStack Table to SvGrid migration?\n\nAbout thirty minutes for a read-only grid and two to four hours for editing-heavy ones. The row-model concepts map almost one to one; the migration guide walks through createTable to createSvGrid, the features object and the rendering options.\n\n### Which is smaller, TanStack Table or SvGrid?\n\nThe TanStack adapter, as an engine with no rendering. The At a glance table has both packages measured the same way on the same date. Add what you would write on top of TanStack (a virtualizer, filter UI, editors) before comparing, since that is what the extra size in SvGrid is.\n\n### Is SvGrid a good TanStack Table alternative for Svelte?\n\nPeople arrive here wanting less glue code, and that is the trade: you keep a headless engine with row models and composable features, and you stop hand-building the DOM, the virtualizer, the filter menus and the editors. If you need one table engine across React and Svelte, stay where you are; that portability is exactly what SvGrid gives up.\n\n## Related comparisons and docs\n\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/)\n- [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/)\n- [SvGrid vs Flowbite / Skeleton / shadcn-svelte tables](https://svgrid.com/compare/svelte-ui-kit-tables/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Build a table from scratch](https://svgrid.com/docs/help/headless/build-a-table/)\n- [Server-side data (load on demand)](https://svgrid.com/docs/help/headless/server-side/)\n- [Headless virtualization](https://svgrid.com/docs/help/headless/virtualization/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- tanstack-svelte: The Svelte adapter is headless: build your own markup from the table instance's state and APIs; createTable takes features, columns and data through a getter; adapters exist for React, Vue, Solid, Qwik, Lit and Svelte (checked 12 Sep 2026) https://tanstack.com/table/latest/docs/framework/svelte/overview\n- tanstack-npm: The latest version's peerDependencies declare svelte ^5.0.0; licence MIT (checked 12 Sep 2026) https://www.npmjs.com/package/@tanstack/svelte-table\n- tanstack-home: Sponsor-supported with gold, silver and bronze sponsors; sponsors get private discord channels, priority issue requests and direct support; an Enterprise Support tier offers private consulting and expert support; no licence for the table is sold (checked 12 Sep 2026) https://tanstack.com/table/latest\n"
|
|
7012
|
+
"markdown": "# SvGrid vs TanStack Table (Svelte)\n\nCanonical URL: https://svgrid.com/compare/tanstack-table/\nFacts verified: 2026-09-12\nCompetitor package: @tanstack/svelte-table\nCompetitor site: https://tanstack.com/table/latest\n\nTanStack Table is the headless table engine with adapters for React, Vue, Svelte, Solid, Qwik and Lit; you bring the markup.\n\n## Verdict\n\nThe closest peer to SvGrid's headless core. SvGrid ships a rendered component on top of the same kind of engine, in Svelte 5 runes; TanStack stays framework-agnostic and asks you to build and maintain the DOM, the virtualizer, the filter menus and the editors yourself.\n\nMigration guide: moving from TanStack Table (Svelte) to SvGrid: https://svgrid.com/docs/help/migrating-from-tanstack-table/\n\n## At a glance\n\n| Fact | SvGrid | TanStack Table (Svelte) | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 9.2.4 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 28 Aug 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Yes (peer svelte ^5.0.0) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 231,000 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 36.3 KB JS, no separate stylesheet, svelte external | 12 Sep 2026 |\n| Engine alone, minified + gzip | 2.7 KB JS, no separate stylesheet (`createSvGrid` from `@svgrid/grid/core`) | the row above; the package is the engine | 22 Sep 2026 |\n| Frameworks | Svelte 5 | Svelte, React, Vue, Solid, Qwik, Lit | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | TanStack Table is MIT and free; tanstack.com is sponsor-supported and offers Enterprise Support as private consulting and expert support, with no licence sold for the table | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; @tanstack/svelte-table 9.2.4 entry `whole package` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\nTanStack Table is the canonical headless table library: it provides the data pipeline (filter, sort, group, expand, paginate, select) and leaves the markup to you. The v9 line ships a Svelte adapter, @tanstack/svelte-table, whose peer dependency range is Svelte 5, with createTable and getters for reactive data instead of the stores the v8 adapter used.\n\nSvGrid covers the same headless surface (createSvGrid, row models, a features object) and adds a full render component with virtualization, Excel-style filters, inline editing, cell-range selection with a fill handle, grouping with aggregation, master/detail, a server-side row model and integrated charts, all in the MIT package.\n\n## Looking for a TanStack Table alternative for Svelte?\n\nPeople arrive here wanting less glue code, and that is the trade: you keep a headless engine with row models and composable features, and you stop hand-building the DOM, the virtualizer, the filter menus and the editors. If you need one table engine across React and Svelte, stay where you are; that portability is exactly what SvGrid gives up.\n\n## What they have in common\n\n- Headless-first architecture with row-model factories and a features object.\n- Composable features: sorting, filtering, grouping, pagination, expansion, selection.\n- TypeScript-first, MIT-licensed, with paid support available from the maintainers.\n- A createTable / createSvGrid entry point that takes columns, data and features.\n- Svelte 5 in both: runes in SvGrid, a Svelte 5 peer range in the TanStack adapter.\n\n## Where SvGrid is stronger\n\n- Ships <SvGrid />: a production render component with virtualization, Excel-style filters, cell-range selection, inline editing, grouping, master/detail and pagination. With TanStack Table you build all of this.\n- The headless core is written in Svelte 5 runes; the TanStack adapter wraps a framework-agnostic core.\n- An imperative API (SvGridApi) for adding rows, setting filters and mutating columns from outside the component.\n- A gallery of runnable examples that covers every feature, and per-feature docs pages with embedded demos.\n- In-grid AI helpers free in @svgrid/grid, and @svgrid/mcp so assistants fetch real example sources and can check the code they write.\n- A paid pack with Excel, PDF and print output, import, pivot tables and support.\n\n## Where TanStack Table (Svelte) is stronger\n\n- A far larger community; the At a glance table has the download counts side by side.\n- Multi-framework parity: if your shop has React, Vue and Svelte apps, the API stays consistent.\n- A smaller bundle when all you want is the engine; the At a glance table has both measured sizes.\n- Framework-specific documentation for each adapter and years of production use in large companies.\n- Enterprise Support as private consulting, and sponsor perks such as priority issue requests.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | TanStack Table (Svelte) |\n| --- | --- | --- |\n| Headless engine | Yes - createSvGrid | Yes - createTable |\n| Render component (drop-in) | Yes - <SvGrid /> | No - bring your own markup |\n| Svelte 5 | Yes - runes throughout | Yes - the adapter's peer range is Svelte 5 |\n| Row virtualization | Yes - built in | Partial - pair with @tanstack/svelte-virtual |\n| Column virtualization | Yes - built in | Partial - pair with @tanstack/svelte-virtual |\n| Excel-style filter menu | Yes - built in | No - filtering logic only; the UI is yours |\n| Inline editing | Yes - enableInlineEditing | No - bring your own |\n| Cell-range selection and clipboard | Yes - enableCellSelection, fill handle | No - bring your own |\n| Server-side data, flat (sort, filter, paging, infinite scroll) | Yes - createServerDataSource: page or infinite block scroll | Yes - manual sorting, filtering and pagination flags |\n| Server-side row model (lazy grouping, tree, pivot, transactions, select-all across unloaded rows) | Paid tier - @svgrid/enterprise | No - the engine has no server row model; the app fetches per group |\n| Master/detail and tree | Yes | Yes - expansion and subRows |\n| Grouping with aggregation | Yes - engine and rendered group rows | Yes - engine only |\n| Integrated charts | Yes - SvGridChart | No - not part of a headless engine |\n| WAI-ARIA helpers | Yes - exported, and applied by <SvGrid /> | Partial - your markup, your ARIA |\n| In-grid AI helpers and MCP server | Yes - helpers free in @svgrid/grid; @svgrid/mcp, MIT | No - not in the docs |\n| Multi-framework support | No - Svelte only | Yes - React, Vue, Svelte, Solid, Qwik, Lit |\n| Paid support tier | Yes - with @svgrid/enterprise, per developer per year | Yes - Enterprise Support (private consulting) and sponsor perks such as priority issues |\n\n## Measured performance\n\nMeasured 12 Sep 2026 with the harness in the repository (pnpm bench:compare): 100,000 rows, fastest of 7 samples per operation, each grid in a fresh page, Chromium through Playwright, headless, on win32 10.0.26200 x64, Intel(R) Core(TM) Ultra 7 255U; a developer workstation, not a dedicated bench rig. Versions: @svgrid/grid 3.0.3, @tanstack/svelte-table 9.2.4. Lower is better.\n\n| Operation | SvGrid | TanStack Table (Svelte) |\n| --- | --- | --- |\n| Mount | 75.5 ms | 196 ms |\n| Sort, text column | 149 ms | 466 ms |\n| Sort, numeric column | 115.7 ms | 374.6 ms |\n| Filter, one column (indicative only) | 99.6 ms | 111.7 ms |\n| Scroll, p95 frame | 34.6 ms | 35.3 ms |\n| Rows kept in the DOM (virtualization on) | 27 | 27 |\n\nThe filter row is not like for like: each grid is driven through its own single-column filter API, and the amount of work differs. The comparison guide explains the method, what is left out and why.\n\nTanStack Table renders nothing, so its adapter draws the row model through a minimal fixed-height windowed table with no virtualizer library, filter UI or editors; the numbers are the engine plus that DOM.\n\n## When to choose SvGrid\n\n- You are on Svelte 5 and want a grid that uses runes idiomatically, headless or rendered.\n- You want a drop-in <SvGrid /> with virtualization, filters, editing and selection working in one prop pass.\n- You want AI tools to give accurate answers about your grid through MCP, and to have their code checked.\n- You want paid support available without switching libraries later.\n\n## When to choose TanStack Table (Svelte)\n\n- You ship to multiple frameworks (React, Vue, Svelte) and want one API across them.\n- You explicitly want a headless library and intend to build your own render layer.\n- You want the smallest possible engine and the largest possible community.\n- A shadcn-svelte data table built on TanStack already does what you need.\n\n## Migration effort\n\nEstimated effort: About 30 minutes per read-only grid, 2-4 hours for editing-heavy grids.\n\nWhat you give up:\n\n- One table engine across React, Vue, Svelte, Solid, Qwik and Lit.\n- The smallest engine-only bundle; the At a glance table has both measured sizes.\n- The TanStack ecosystem around the table: Virtual, Query and the shadcn-svelte data table recipe.\n\nMigration guide: moving from TanStack Table (Svelte) to SvGrid: https://svgrid.com/docs/help/migrating-from-tanstack-table/\n\n## Live example\n\nHeadless Table: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/186-headless-table/\n\n## The bottom line\n\nIf you build across React, Vue and Svelte and want one headless API, TanStack Table is the safer bet. If you are committed to Svelte 5 and want virtualization, Excel-style filters, editing and selection out of the box, SvGrid gets you there with far less code, and you keep a headless core when you need it.\n\n## Frequently asked questions\n\n### Is SvGrid better than TanStack Table for Svelte?\n\nFor a Svelte 5 app, SvGrid is usually the faster path: it ships a virtualized render component with built-in filters, editing and accessibility, so there is no DOM layer to write. The TanStack Svelte adapter is Svelte 5 in its v9 line, but it is headless by design; you still build and maintain the table, virtualization and editing UI. TanStack wins if you need one API across several frameworks, or if owning that markup is the point.\n\n### Can I keep a headless setup like TanStack Table?\n\nYes. createSvGrid plus the row-model factories is a headless engine; you can drive your own markup exactly as with TanStack and adopt the SvGrid component only where you want it. The headless docs and the headless demos on this page show both.\n\n### Does the TanStack Svelte adapter support Svelte 5?\n\nYes. The @tanstack/svelte-table package on npm declares a Svelte 5 peer range in its v9 line and its examples pass data through getters rather than stores. The At a glance table shows the version and the peer range as read from the registry.\n\n### How long is a TanStack Table to SvGrid migration?\n\nAbout thirty minutes for a read-only grid and two to four hours for editing-heavy ones. The row-model concepts map almost one to one; the migration guide walks through createTable to createSvGrid, the features object and the rendering options.\n\n### Which is smaller, TanStack Table or SvGrid?\n\nThe TanStack adapter, as an engine with no rendering. The At a glance table has both packages measured the same way on the same date. Add what you would write on top of TanStack (a virtualizer, filter UI, editors) before comparing, since that is what the extra size in SvGrid is.\n\n### Is SvGrid a good TanStack Table alternative for Svelte?\n\nPeople arrive here wanting less glue code, and that is the trade: you keep a headless engine with row models and composable features, and you stop hand-building the DOM, the virtualizer, the filter menus and the editors. If you need one table engine across React and Svelte, stay where you are; that portability is exactly what SvGrid gives up.\n\n## Related comparisons and docs\n\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/)\n- [SvGrid vs SVAR Svelte DataGrid](https://svgrid.com/compare/svar-svelte-datagrid/)\n- [SvGrid vs Flowbite / Skeleton / shadcn-svelte tables](https://svgrid.com/compare/svelte-ui-kit-tables/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Build a table from scratch](https://svgrid.com/docs/help/headless/build-a-table/)\n- [Server-side data (load on demand)](https://svgrid.com/docs/help/headless/server-side/)\n- [Headless virtualization](https://svgrid.com/docs/help/headless/virtualization/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- tanstack-svelte: The Svelte adapter is headless: build your own markup from the table instance's state and APIs; createTable takes features, columns and data through a getter; adapters exist for React, Vue, Solid, Qwik, Lit and Svelte (checked 12 Sep 2026) https://tanstack.com/table/latest/docs/framework/svelte/overview\n- tanstack-npm: The latest version's peerDependencies declare svelte ^5.0.0; licence MIT (checked 12 Sep 2026) https://www.npmjs.com/package/@tanstack/svelte-table\n- tanstack-home: Sponsor-supported with gold, silver and bronze sponsors; sponsors get private discord channels, priority issue requests and direct support; an Enterprise Support tier offers private consulting and expert support; no licence for the table is sold (checked 12 Sep 2026) https://tanstack.com/table/latest\n"
|
|
7013
7013
|
},
|
|
7014
7014
|
{
|
|
7015
7015
|
"slug": "compare/vincjo-datatables",
|
|
7016
7016
|
"path": "docs/_data/comparisons/vincjo-datatables.json",
|
|
7017
7017
|
"title": "SvGrid vs @vincjo/datatables",
|
|
7018
7018
|
"section": "Comparisons",
|
|
7019
|
-
"markdown": "# SvGrid vs @vincjo/datatables\n\nCanonical URL: https://svgrid.com/compare/vincjo-datatables/\nFacts verified: 2026-09-12\nCompetitor package: @vincjo/datatables\nCompetitor site: https://github.com/vincjo/datatables\n\n@vincjo/datatables is a lightweight, headless Svelte datatable helper for sorting, filtering, and paginating your own markup.\n\n## Verdict\n\n@vincjo/datatables is a great minimal pick when you want to keep your own table markup and just need sort / filter / paginate. SvGrid is the fuller grid - virtualization, Excel filters, editing, a render component - for heavier apps.\n\nMigration guide: moving from @vincjo/datatables to SvGrid: https://svgrid.com/docs/help/migrating-from-vincjo-datatables/\n\n## At a glance\n\n| Fact | SvGrid | @vincjo/datatables | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 2.8.1 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 4 Jun 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Yes (peer svelte ^5.56.1) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 72,800 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 10.2 KB JS, no separate stylesheet, svelte external | 12 Sep 2026 |\n| Engine alone, minified + gzip | 2.7 KB JS, no separate stylesheet (`createSvGrid` from `@svgrid/grid/core`) | the row above; the package is the engine | 22 Sep 2026 |\n| Frameworks | Svelte 5 | Svelte | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $
|
|
7019
|
+
"markdown": "# SvGrid vs @vincjo/datatables\n\nCanonical URL: https://svgrid.com/compare/vincjo-datatables/\nFacts verified: 2026-09-12\nCompetitor package: @vincjo/datatables\nCompetitor site: https://github.com/vincjo/datatables\n\n@vincjo/datatables is a lightweight, headless Svelte datatable helper for sorting, filtering, and paginating your own markup.\n\n## Verdict\n\n@vincjo/datatables is a great minimal pick when you want to keep your own table markup and just need sort / filter / paginate. SvGrid is the fuller grid - virtualization, Excel filters, editing, a render component - for heavier apps.\n\nMigration guide: moving from @vincjo/datatables to SvGrid: https://svgrid.com/docs/help/migrating-from-vincjo-datatables/\n\n## At a glance\n\n| Fact | SvGrid | @vincjo/datatables | Checked |\n| --- | --- | --- | --- |\n| Latest version | 3.0.3 | 2.8.1 | 12 Sep 2026 |\n| Licence field on npm | MIT | MIT | 12 Sep 2026 |\n| Last published | 11 Sep 2026 | 4 Jun 2026 | 12 Sep 2026 |\n| Svelte 5 support | Native (Svelte 5 runes) | Yes (peer svelte ^5.56.1) | 12 Sep 2026 |\n| npm downloads, 30 days to 10 Sep 2026 | 16,900 | 72,800 | 12 Sep 2026 |\n| Bundle, minified + gzip | 97.6 KB JS + 10.5 KB CSS | 10.2 KB JS, no separate stylesheet, svelte external | 12 Sep 2026 |\n| Engine alone, minified + gzip | 2.7 KB JS, no separate stylesheet (`createSvGrid` from `@svgrid/grid/core`) | the row above; the package is the engine | 22 Sep 2026 |\n| Frameworks | Svelte 5 | Svelte | 12 Sep 2026 |\n| Pricing | MIT core; @svgrid/enterprise from $299 per developer per year (Indie, under $1M revenue), $599 for Enterprise | @vincjo/datatables is MIT on npm and free; no licence is sold | 12 Sep 2026 |\n\nBundle sizes: each package built alone with Vite in library mode, minified, gzip level 9, Svelte kept external where a package uses it (it is a peer dependency). SvGrid 3.0.4 measured 22 Sep 2026 with packages/grid/scripts/measure-size.mjs; @vincjo/datatables 2.8.1 entry `whole package` measured 12 Sep 2026 with packages/grid/scripts/measure-competitor-bundles.mjs.\n\n## Overview\n\n@vincjo/datatables gives you a small, ergonomic handler that wraps your data with reactive sorting, filtering, and pagination while you keep full control of the markup. It is MIT-licensed and popular for its simplicity.\n\nSvGrid scales further up the curve: it keeps a headless engine but also ships a virtualized render component, an Excel-style filter menu, inline editing, cell selection, and an imperative API - for when a hand-rolled table stops being enough.\n\n## Looking for a @vincjo/datatables alternative for Svelte?\n\nIt is a helper for your own markup rather than a grid, which is exactly right until you need virtualization, inline editing or column pinning and start building them yourself. Moving to SvGrid keeps the headless option and adds those. If your table is a few hundred rows of your own HTML, staying put is the smaller dependency.\n\n## What they have in common\n\n- Svelte-native, not a port.\n- Headless-friendly: you can drive your own markup.\n- MIT-licensed.\n- Client- and server-side data modes.\n\n## Where SvGrid is stronger\n\n- Built-in virtualized render component - no need to author the table.\n- Excel-style filter menu, inline editing, and cell-range selection.\n- Row + column virtualization for large datasets.\n- Imperative SvGridApi + @svgrid/mcp MCP server.\n- Optional Enterprise pack for export, import, pivot, and AI.\n\n## Where @vincjo/datatables is stronger\n\n- Much smaller surface and bundle if all you need is sort / filter / paginate.\n- You keep 100% control of the table markup with zero render opinions.\n- Faster to learn for a simple table.\n\n## Feature by feature\n\nYes: shipped in the package. Partial: needs extra work or a companion package. Paid tier: only in a paid edition. No: not available. n/a: does not apply.\n\n| Feature | SvGrid | @vincjo/datatables |\n| --- | --- | --- |\n| Svelte native | Yes | Yes - Svelte 5 peer range |\n| Render component | Yes - <SvGrid /> | No - headless, you render the markup |\n| Virtualization | Yes | No |\n| Excel-style filters | Yes | Partial - Basic filtering |\n| Inline editing | Yes | No - BYO |\n| Cell selection + copy | Yes | No - BYO |\n| Grouping / tree / master-detail | Yes | No |\n| Footprint for a simple table | Partial - Larger | Yes - Tiny |\n| AI / MCP integration | Yes | No |\n\n## When to choose SvGrid\n\n- You need virtualization, editing, or Excel-style filtering.\n- You want a render component instead of hand-authoring the table.\n- You expect the grid to grow into grouping, tree, or master/detail.\n\n## When to choose @vincjo/datatables\n\n- You only need sort / filter / paginate over a small dataset.\n- You want to keep full control of your own table markup.\n- You want the smallest possible bundle for a simple table.\n\n## Migration effort\n\nEstimated effort: 30 minutes to 2 hours per table.\n\nWhat you give up:\n\n- A tiny dependency-free helper when a sortable, filterable list is all you need.\n- Full control of the markup without opting into a headless mode.\n\nMigration guide: moving from @vincjo/datatables to SvGrid: https://svgrid.com/docs/help/migrating-from-vincjo-datatables/\n\n## Live example\n\nHeadless Table: open it in the gallery for the source and the full-size version. https://svgrid.com/demos/186-headless-table/\n\n## The bottom line\n\nFor a small sort/filter/paginate list you keep full control over, @vincjo/datatables is delightfully light. The moment you need virtualization, Excel-style filters, editing, or grouping, SvGrid is the grid that already has them.\n\n## Frequently asked questions\n\n### SvGrid vs @vincjo/datatables - which to pick?\n\nPick @vincjo/datatables for a small, markup-controlled table; pick SvGrid when you need virtualization, editing, filters, or grouping. Both are MIT and Svelte-native.\n\n### Is @vincjo/datatables lighter than SvGrid?\n\nYes, for a simple table it is smaller. SvGrid carries more because it ships a virtualized render component and a full feature set.\n\n### Can SvGrid be headless like @vincjo/datatables?\n\nYes - its headless core lets you keep your own markup, the same way @vincjo/datatables does.\n\n### Is SvGrid a good @vincjo/datatables alternative for Svelte?\n\nIt is a helper for your own markup rather than a grid, which is exactly right until you need virtualization, inline editing or column pinning and start building them yourself. Moving to SvGrid keeps the headless option and adds those. If your table is a few hundred rows of your own HTML, staying put is the smaller dependency.\n\n## Related comparisons and docs\n\n- [SvGrid vs svelte-headless-table](https://svgrid.com/compare/svelte-headless-table/)\n- [SvGrid vs TanStack Table (Svelte)](https://svgrid.com/compare/tanstack-table/)\n- [SvGrid vs Flowbite / Skeleton / shadcn-svelte tables](https://svgrid.com/compare/svelte-ui-kit-tables/)\n- [Comparison: SvGrid vs AG Grid vs TanStack Table](https://svgrid.com/docs/help/comparison/)\n- [Build a table from scratch](https://svgrid.com/docs/help/headless/build-a-table/)\n\n## Sources and last verified\n\nEvery claim on this page was last checked on 12 Sep 2026. Versions, licences and download counts come from the npm registry; feature and pricing statements from the pages listed below.\n\n- vincjo-docs: A headless, SSR-friendly toolkit with no dependency: sort, filter, search and pagination in client-side and server-side modes; you render the markup (checked 12 Sep 2026) https://vincjo.fr/datatables/\n- vincjo-npm: MIT; the latest version declares a Svelte 5 peer range (checked 12 Sep 2026) https://www.npmjs.com/package/@vincjo/datatables\n"
|
|
7020
7020
|
}
|
|
7021
7021
|
];
|
|
7022
7022
|
export const apiReference = {
|
|
@@ -7094,7 +7094,7 @@ export const apiReference = {
|
|
|
7094
7094
|
};
|
|
7095
7095
|
export const apiSurface = {
|
|
7096
7096
|
"gridVersion": "3.0.8",
|
|
7097
|
-
"enterpriseVersion": "3.1.
|
|
7097
|
+
"enterpriseVersion": "3.1.4",
|
|
7098
7098
|
"grid": {
|
|
7099
7099
|
"values": [
|
|
7100
7100
|
"ALL_FILTER_OPERATORS",
|