<!-- https://svgrid.com/docs/help/migrating-from-glide/ - SvGrid documentation as markdown. Index of every page: https://svgrid.com/llms.txt -->

# Migrating from Glide Data Grid

Glide Data Grid is the canvas-rendered, ultra-high-performance choice
for very wide datasets (100k+ rows, 100+ columns). Sv-grid renders to
DOM with virtualization, which trades peak FPS for
accessibility + standards-compliant HTML.

> Estimated effort: **3-6 hours** per grid. Glide's getCellContent /
> onCellEdited cell-data model is the opposite of sv-grid's
> data-array model; the mental flip takes the most time.

<!-- facts:start glide-data-grid -->
> **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/).
<!-- facts:end -->

## Mental-model flip

Glide gives you a **canvas + a `getCellContent` callback**: the grid
asks you for each visible cell on demand. Sv-grid wants the
**whole data array up front** (`<SvGrid data={rows}>`); the engine
slices for virtualization.

The example at the end of this page runs against these rows:

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

  type Person = {
    id: number
    name: string
    department: string
    city: string
    age: number
    salary: number
  }

  const people: Person[] = [
    { id: 1, name: 'Ada Lovelace',   department: 'Engineering', city: 'London',   age: 36, salary: 142000 },
    { id: 2, name: 'Grace Hopper',   department: 'Engineering', city: 'New York', age: 45, salary: 168000 },
    { id: 3, name: 'Linus Torvalds', department: 'Platform',    city: 'Portland', age: 54, salary: 155000 },
    { id: 4, name: 'Radia Perlman',  department: 'Networking',  city: 'Seattle',  age: 49, salary: 161000 },
    { id: 5, name: 'Barbara Liskov', department: 'Platform',    city: 'Boston',   age: 52, salary: 172000 },
  ]

  let rows = $state<Person[]>(people)

  const columns: GridColumns<Person> = [
    { field: 'name',       header: 'Name',       width: 200, editorType: 'text' },
    { field: 'department', header: 'Department', width: 150, editorType: 'text' },
    { field: 'city',       header: 'City',       width: 140, editorType: 'text' },
    { field: 'age',        header: 'Age',        width: 90,  editorType: 'number' },
    { field: 'salary',     header: 'Salary',     width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },
  ]
</script>
```

```diff
- function getCellContent([col, row]) {
-   const r = rows[row]
-   if (col === 0) return { kind: 'text', data: r.name,    displayData: r.name,    allowOverlay: true }
-   if (col === 1) return { kind: 'number', data: r.amount, displayData: fmt(r.amount), allowOverlay: true }
- }
- <DataEditor columns={[...]} getCellContent={getCellContent} rows={rows.length} />

+ const columns: ColumnDef<typeof features, Row>[] = [
+   { field: 'name',   header: 'Name',   editorType: 'text' },
+   { field: 'amount', header: 'Amount', editorType: 'number',
+     format: { type: 'currency', currency: 'USD' } },
+ ]
+ <SvGrid data={rows} columns={columns} features={features} />
```

This change is **good** for 99% of apps: it's less code, less risk
of typos in cell coordinates, full TypeScript type checking on the
row shape. For the 1% of apps with rows that don't fit in memory,
see "Out-of-memory data" below.

## Cell editing

```diff
- function onCellEdited([col, row], newValue) {
-   rows[row] = { ...rows[row], [colToField(col)]: newValue.data }
- }
- <DataEditor onCellEdited={onCellEdited} />

+ <SvGrid
+   data={rows} columns={columns} features={features}
+   onCellValueChange={(e) => {
+     rows[e.rowIndex] = { ...rows[e.rowIndex], [e.columnId]: e.newValue }
+   }}
+ />
```

You can also rely on sv-grid's built-in write-back if `data` is a
Svelte 5 `$state` array - mutations propagate automatically.

## Sorting + filtering

Glide doesn't ship sort / filter UI; you wrap your own. Sv-grid
ships them:

```diff
- // Build your own sort buttons in the toolbar; sort rows yourself.

+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })
+ <SvGrid data={rows} columns={columns} features={features} filterMode="menu" />
```

## Frozen columns / row markers

| Glide                                  | sv-grid                                       |
| -------------------------------------- | --------------------------------------------- |
| `freezeColumns={1}`                    | `api.setColumnPinning({ left: ['firstColId'] })` |
| `rowMarkers="number"`                  | `showRowNumbers={true}` prop                  |
| `rowMarkers="checkbox"`                | `selectionMode="row"` prop                    |

## Custom drawing → custom snippets

Glide's `drawCustomCell` lets you render anything via canvas. The
sv-grid equivalent is a Svelte snippet (DOM):

```diff
- drawCustomCell(args) {
-   const ctx = args.ctx
-   ctx.fillStyle = args.cell.data.color
-   ctx.fillRect(args.rect.x, args.rect.y, args.rect.width, args.rect.height)
-   return true
- }

+ {
+   field: 'color',
+   cell: (ctx) => renderSnippet(ColorChip, { color: ctx.row.original.color }),
+ }
```

```svelte
{#snippet ColorChip(props)}
  <span style="display: inline-block; width: 18px; height: 18px; background: {props.color};"></span>
{/snippet}
```

## Out-of-memory data

For "10M rows, fetched on scroll" workloads (the only case Glide
genuinely beats sv-grid on), use sv-grid's
[server-side / infinite-scroll pattern](https://svgrid.com/docs/help/server-side-data/):

```svelte
<SvGrid
  data={loadedSlice}
  columns={columns} features={features}
  externalSort={true}
  externalFilter={true}
  onSortingChange={async (s) => { loadedSlice = await fetchPage({ sort: s, offset: 0, limit: 200 }) }}
/>
```

You'll cap practical perf at ~100k rendered rows; for true 10M+
datasets Glide's canvas approach has a perf edge sv-grid won't
match. Most apps don't need 10M rows on screen at once - they need
fast server-side filtering, which both libraries support equally.

## Theming

Glide: huge `theme` prop object. Sv-grid: CSS custom properties (`--sg-*`).

```diff
- <DataEditor theme={{
-   accentColor: '#4F5DFF',
-   accentLight: 'rgba(62, 116, 253, 0.2)',
-   bgCell: '#1c1c20',
-   /* …40 more properties… */
- }} />

+ <div style="--sg-accent: #4F5DFF; --sg-bg: #1c1c20;">
+   <SvGrid {data} {columns} features={features} />
+ </div>
```

See [design tokens](https://svgrid.com/docs/help/tokens/) for the full list (≤ 30 tokens
covers everything; Glide's theme has ~40).

## What you get for free vs Glide

- **Accessibility.** Glide's canvas is invisible to screen readers
  unless you build an off-screen ARIA buffer. Sv-grid is WAI-ARIA
  1.2 grid pattern out of the box; demo 17 covers axe-core CI.
- **Standard HTML.** SEO crawlers, browser Find-in-Page, browser
  zoom, OS-level text scaling - all work because the grid emits
  actual `<table><tr><td>`.
- **Familiar editing.** Browser-native `<input>` / `<select>` for
  cells, with autofill / clipboard / autocorrect intact.
- **Built-in sort / filter / pagination UI.**

## What you give up

- **Peak FPS on >200k visible rows.** Canvas wins here. For most
  apps the gap is invisible; if you've actually measured it on real
  hardware and need the FPS, Glide remains the right call.
- **Per-pixel cell drawing.** DOM cells are sub-pixel-uniform but
  not arbitrarily drawn.

## Frequently asked questions

### Should I move from Glide Data Grid to SvGrid?

Move if you need accessibility, standards-compliant HTML, SEO-friendly markup,
or DOM-based custom cells. Stay on Glide only if you have measured a need for
peak canvas FPS on 200k+ simultaneously visible rows. For most apps the
performance gap is invisible, and SvGrid virtualizes comfortably to 100k+ rows.

### How long does a Glide migration take?

About 3-6 hours per grid. The biggest shift is conceptual: Glide's
`getCellContent` / `onCellEdited` cell-data model is the inverse of SvGrid's
plain data-array model, so the mental flip takes the most time, not the code.

### Does SvGrid render to canvas or DOM?

DOM, with row and column virtualization. That is what gives you WAI-ARIA roles,
keyboard navigation, screen-reader support, and selectable/indexable text -
things a canvas grid like Glide cannot offer.

## What you end up with

Inline editing over a virtualized body, without a canvas to draw into.

```svelte
<SvGrid data={rows} {columns} editable enableCellSelection sortable />
```

## See also

- [SvGrid vs Glide Data Grid](https://svgrid.com/compare/glide-data-grid/) - the side-by-side comparison
- [Performance benchmarks](https://svgrid.com/docs/help/benchmarks/) - measured numbers
- [Server-side data](https://svgrid.com/docs/help/server-side-data/) - the >100k-row pattern
- [Accessibility](https://svgrid.com/docs/help/accessibility/) - the standards compliance Glide doesn't ship

---

SvGrid is the Svelte 5 data grid (`npm install @svgrid/grid`, MIT). This page: https://svgrid.com/docs/help/migrating-from-glide/ . All docs: https://svgrid.com/llms.txt
