# Migrating from AG Grid to SvGrid
If you tried AG Grid on a Svelte 5 project - via ag-grid-svelte, the
old ag-grid-community/svelte, or a hand-rolled wrapper - you probably
hit the same friction everyone hits: the bridge between AG Grid's
React/Angular-first API and Svelte 5 runes is brittle, the bundle is
heavy, and the Enterprise pricing only makes sense at scale.
This page is a 30-minute migration recipe from AG Grid to SvGrid. It covers what maps 1:1, what's different by design, and what you'll lose. We tell you when not to switch at the bottom.
TL;DR
| AG Grid Community | AG Grid Enterprise | SvGrid Community | sv-grid-pro | |
|---|---|---|---|---|
| License | MIT | Commercial (~$999/dev/yr) | MIT | $599/dev/yr (single app) or $999/dev/yr (multi app) |
| Svelte 5 native | ❌ (wrapper) | ❌ (wrapper) | ✅ | ✅ |
| Bundle (gzipped) | ~250 KB | ~400 KB | ~7.5 KB headless / ~42 KB full | lazy-loaded subpaths |
| Sorting / filtering / grouping | ✅ | ✅ | ✅ | (in Community) |
| Master/detail, tree, range select | ❌ Enterprise only | ✅ | ✅ (free) | (in Community) |
| Excel export | ❌ | ✅ Enterprise | ❌ | ✅ |
| PDF / CSV / TSV / HTML export | ❌ | Partial | ❌ | ✅ |
| Print view | ❌ | ❌ | ❌ | ✅ |
| Set filter / Excel-style filter menu | ❌ Enterprise | ✅ | ✅ (free) | (in Community) |
The headline: SvGrid Community gives you most of AG Grid Enterprise's
features for free, and sv-grid-pro adds the export + print pack for
~40% less than AG Grid Enterprise. The catch is Svelte-only and a much
smaller ecosystem.
Mental model - what changes
AG Grid is one big object you configure declaratively. SvGrid is a
headless engine (createSvGrid) with an optional render
component (<SvGrid>) on top - the same split TanStack Table made
popular. You can use either layer; most projects use the render
component.
<!-- AG Grid (via a Svelte wrapper) -->
<AgGridSvelte
gridOptions={{
rowData: rows,
columnDefs: columns,
onGridReady: (params) => (gridApi = params.api),
}}
/>
<!-- SvGrid -->
<SvGrid
data={rows}
columns={columns}
features={features}
onApiReady={(api) => (gridApi = api)}
/>
Three things to note:
- No giant
gridOptionsblob. Each capability is a top-level prop. - Features are opt-in. You pass a
featuresobject built withtableFeatures({...})- only the features you list ship JS. onApiReadygives you a typedSvGridApithat is roughly the AG GridgridApiequivalent (see the API-mapping table below).
Column definitions - direct translation
The shapes are similar enough that you can usually translate by hand without thinking too hard.
// AG Grid
const columnDefs: ColDef[] = [
{ field: 'name', headerName: 'Name', sortable: true, filter: true, width: 200 },
{ field: 'price', headerName: 'Price', type: 'numericColumn',
valueFormatter: ({ value }) => `${value.toFixed(2)}` },
{ field: 'date', headerName: 'Date',
valueGetter: ({ data }) => new Date(data.date).toISOString().slice(0, 10) },
{ field: 'status', headerName: 'Status',
cellRenderer: StatusCellRenderer,
cellRendererParams: { onChange: handleStatusChange } },
]
// SvGrid
import { renderComponent, type ColumnDef } from 'sv-grid-community'
import StatusCell from './StatusCell.svelte'
const columns: ColumnDef<typeof features, Row>[] = [
{ field: 'name', header: 'Name', width: 200 }, // sortable + filterable by default
{ field: 'price', header: 'Price',
format: { type: 'currency', currency: 'USD' } },
{ field: 'date', header: 'Date',
format: { type: 'date', pattern: 'y-m-d' } },
{ field: 'status', header: 'Status',
cell: renderComponent(StatusCell, (ctx) => ({
value: ctx.getValue(),
onChange: handleStatusChange,
})),
},
]
Property mapping
| AG Grid | SvGrid | Notes |
|---|---|---|
field |
field |
Same. |
headerName |
header |
Accepts a string or a snippet/component. |
width |
width |
Same. |
minWidth / maxWidth |
minWidth / maxWidth |
Same. |
sortable: true |
(default) | Sorting is on when rowSortingFeature is registered. |
filter: true |
(default) | Filtering is on when columnFilteringFeature is registered. |
valueFormatter |
format: { ... } |
Built-in types: number, currency, percent, date. For custom, use cell. |
valueGetter |
accessorFn |
Returns the value for sorting/filtering. |
cellRenderer + cellRendererParams |
cell: renderComponent(C, ctx => props) |
One call, type-checked. |
cellEditor: 'agTextCellEditor' |
editorType: 'text' |
Built-in: text, number, checkbox, date. |
editable: true |
enableInlineEditing prop on <SvGrid> |
Per-grid, not per-column. (Per-column control on the roadmap.) |
pinned: 'left' / 'right' |
Right-click column menu → Pin | Set programmatically via the api. |
rowGroup: true |
Via setGroupBy([colId]) |
See Grouping below. |
aggFunc: 'sum' |
aggregation: 'sum' |
Built-in: sum, avg, min, max, count. |
Feature registration - the one new thing
AG Grid auto-enables most features; you turn them off. SvGrid is the opposite - features are opt-in. The result is a smaller bundle.
import {
tableFeatures,
rowSortingFeature,
columnFilteringFeature,
columnGroupingFeature,
rowExpandingFeature,
rowPaginationFeature,
rowSelectionFeature,
} from 'sv-grid-community'
const features = tableFeatures({
rowSortingFeature,
columnFilteringFeature,
rowSelectionFeature,
// omit any you don't need - their code won't ship
})
Pass features to <SvGrid> once. From then on the grid behaves like
AG Grid's enableSorting, enableFilter, rowSelection, etc. are all
on for the registered features.
API mapping (gridApi → SvGridApi)
You get the SvGrid API from onApiReady (equivalent to AG Grid's
onGridReady).
AG Grid gridApi.X() |
SvGrid api.X() |
|---|---|
setRowData(rows) |
(declarative - just update data prop) |
addRow(row) / applyTransaction({ add: [row] }) |
api.addRow(row) / api.addRows(rows) |
applyTransaction({ remove: [row] }) |
api.removeRow(rowIndex) |
getValue(colId, rowNode) |
api.getCellValue(rowIndex, columnId) |
setValue(...) |
api.setCellValue(rowIndex, columnId, value) |
setColumnVisible(colId, visible) |
api.setColumnVisible(columnId, visible) |
getSortModel() / setSortModel() |
api.setSort(columnId, 'asc'|'desc'|null) |
setFilterModel({...}) |
api.setFilter(columnId, { operator, value }) |
getDisplayedRowAtIndex(i) / forEachNodeAfterFilterAndSort(...) |
api.getDisplayedRows() |
getModel() (raw rows) |
api.getData() |
Common patterns
Sorting + filtering + pagination (the 80% case)
<script lang="ts">
import {
SvGrid,
tableFeatures,
rowSortingFeature,
columnFilteringFeature,
rowPaginationFeature,
} from 'sv-grid-community'
const features = tableFeatures({
rowSortingFeature,
columnFilteringFeature,
rowPaginationFeature,
})
</script>
<SvGrid
data={rows}
columns={columns}
features={features}
showPagination
showColumnFilters
/>
AG Grid equivalent: gridOptions: { defaultColDef: { sortable: true, filter: true }, pagination: true }.
Cell editing with persistence
<script lang="ts">
function onCellValueChange(e: { rowIndex: number; columnId: string; value: unknown }) {
// Persist however you like (fetch to backend, optimistic local update, etc.)
console.log('cell changed', e)
}
</script>
<SvGrid
data={rows}
columns={columns}
features={features}
enableInlineEditing
onCellValueChange={onCellValueChange}
/>
AG Grid equivalent: onCellValueChanged: ({ data, colDef, newValue, oldValue }) => ....
SvGrid's event payload is column-id + row-index based rather than node-based; the row data is yours
to mutate (or not) on the rows array you passed in.
Grouping + aggregation
<script lang="ts">
import {
SvGrid,
tableFeatures,
columnGroupingFeature,
rowSortingFeature,
rowExpandingFeature,
} from 'sv-grid-community'
const features = tableFeatures({
rowSortingFeature,
columnGroupingFeature,
rowExpandingFeature,
})
const columns = [
{ field: 'department', header: 'Department' },
{ field: 'team', header: 'Team' },
{ field: 'salary', header: 'Salary', aggregation: 'sum',
format: { type: 'currency', currency: 'USD' } },
]
function setGroup(api) {
api.setGroupBy(['department', 'team'])
}
</script>
<SvGrid
data={rows}
columns={columns}
features={features}
showGroupingControls
onApiReady={setGroup}
/>
AG Grid Enterprise's rowGroupPanelShow: 'always' + aggFunc: 'sum' translates 1:1.
Master / detail
AG Grid Enterprise feature; free in SvGrid Community. See demo 08 for the exact pattern.
Server-side data
AG Grid uses an IServerSideDatasource interface. SvGrid uses
externalSort + externalFilter props - your code keeps full control
over the query, and the grid records UI state but doesn't re-order rows
locally. See demo 09.
Excel / PDF export
AG Grid: gridApi.exportDataAsExcel({...}) (Enterprise-only).
SvGrid: install sv-grid-pro, call api.exportData({ format: 'xlsx', ... }). See Data export and printing.
import { installPro, setLicenseKey } from 'sv-grid-pro'
setLicenseKey('SVPRO-...') // your Pro key
// inside onApiReady:
const pro = installPro(api)
await pro.exportData({ format: 'xlsx', filename: 'orders' })
Gotchas - things that don't translate directly
1. Per-column editable: true
SvGrid v1.0 toggles editing at the grid level (enableInlineEditing).
Per-column editability is on the roadmap - until then, you can gate
edits in your onCellValueChange handler.
2. Column drag-to-reorder
SvGrid v1.0 supports column reorder via the API (setColumnOrder), not
header drag. Built-in header drag is on the roadmap. Most teams don't
miss it - it's a power-user feature.
3. AG Grid valueGetter chains
AG Grid's valueGetter can read other column values via the API. In
SvGrid, accessorFn only receives the row; if you need cross-column
computed values, do it in the cell renderer with ctx.row.original or
compute the derived value upstream and store it in the row.
4. cellClass / rowClass callbacks
On the roadmap. For now, render a wrapper element in your cell snippet
with the conditional class.
5. The Status Bar / Side Bar / Tool Panels
AG Grid's chrome (status bar with row count, side bar with filters and columns panels) doesn't exist in SvGrid - build it as plain Svelte markup around the grid. Most teams build their own anyway because AG Grid's defaults rarely match a polished design system.
6. Set filter (the Excel-style funnel popup)
SvGrid ships an Excel-style filter menu (free in Community). API surface is similar but not identical - see Set filter.
When NOT to migrate
Be honest. Stay on AG Grid if you:
- Use multiple frameworks - AG Grid has React, Angular, Vue, Solid, Qwik, vanilla adapters. SvGrid is Svelte-only.
- Use AG Grid's integrated charts - those depend on AG Grid's chart engine; SvGrid has no equivalent.
- Depend on AG Grid pivoting - not in SvGrid's roadmap.
- Are mid-project and shipping in <2 weeks - the migration is a few hours per grid, but only do it when you have buffer.
- Have a Svelte 4 codebase you can't upgrade - SvGrid requires Svelte 5 runes. (Consider htmlelements.com for vanilla / multi-framework.)
If none of those apply: switching saves you $400-$1000 per dev per year, cuts your bundle by 200+ KB, and gives you a Svelte-native API that plays well with runes.
Step-by-step migration
A typical migration of a single grid takes 1-3 hours:
- Install -
pnpm add sv-grid-community(andsv-grid-proif you need export). - Translate columnDefs - use the mapping table above. Most columns are 1:1.
- Wrap features - figure out which AG Grid features you actually use; register only those in
tableFeatures({...}). - Swap the component -
<AgGridSvelte gridOptions={...}>→<SvGrid data={rows} columns={columns} features={features}>. - Move event handlers - AG Grid
onCellValueChanged→ SvGridonCellValueChange(signature differs slightly, see above). - Move API calls - AG Grid
gridApi.X()→ SvGridapi.X()per the API table. - Test interactions - sort, filter, edit, select. Most "just works."
- Remove
ag-grid-*packages -pnpm remove ag-grid-community ag-grid-svelteetc. Inspect your bundle to confirm the 200+ KB drop.
Need help migrating?
Pro customers get migration help included with the support plan
(architecture review, port one grid for you as a reference). Email
[email protected] after purchase, or [email protected] for
pre-sales questions.
See also
- Getting started - full SvGrid walkthrough
- Why headless? - the headless / render-component split
- Data export and printing - the
sv-grid-profeature pack - SvGrid vs AG Grid comparison page
Frequently asked questions
Is SvGrid a drop-in replacement for AG Grid in Svelte?
Not a literal drop-in - there is no ag-grid-svelte shim to swap. But the
concepts map closely: column definitions, row models, sorting, filtering,
grouping, and an imperative API all have direct SvGrid equivalents, so most
teams port a grid in 30 minutes to a day. It is a configuration translation,
not a rewrite.
What is the SvGrid equivalent of AG Grid Enterprise?
sv-grid-pro. It adds Excel/PDF/CSV/TSV/HTML export, a printable view, pivot
tables, data import, and AI helpers. It is licensed per developer
($599 single-app / $999 multi-app), not per deployment, and the Community
package is MIT-licensed and free for commercial use.
Does SvGrid use Svelte 5 runes, or is it a wrapper?
It is Svelte-5-native. State is $state / $derived / $effect and cells
render through Svelte snippets - there is no React or Angular core underneath
and no framework bridge to keep in sync.
Will my AG Grid bundle size shrink?
Almost always. SvGrid's full render component is ~42 KB gzipped (or ~7.5 KB
for the headless core) versus a much heavier AG Grid Community bundle, and you
only add sv-grid-pro features you actually use - so you ship a fraction of
the JavaScript.