Migrating from Smart.Grid (Smart Web Components)
Smart.Grid (htmlelements.com) and SvGrid come from the same team. Smart.Grid is a framework-agnostic custom element - it even works inside Svelte today - while SvGrid is the reactive, Svelte-5-native option. If you are standardising a Svelte app on idiomatic components, this guide maps a Smart.Grid setup onto SvGrid.
Estimated effort: 2-4 hours per grid. The main shift is from a custom element bound through properties / attributes to a reactive Svelte component.
Facts, checked 12 Sep 2026.
smart-webcomponents27.0.1, ISC, last published 13 Aug 2026, 6,620 npm downloads in the 30 days to 10 Sep 2026.@svgrid/grid3.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).
Vocabulary cheat sheet
| Smart.Grid (web component) | sv-grid |
|---|---|
<smart-grid> element |
<SvGrid ... /> |
grid.dataSource = new Smart.DataAdapter |
data array (or externalSort/Filter) |
{ label: 'Name', dataField: 'name' } |
{ header: 'Name', field: 'name' } |
template / cell template |
cell: (c) => renderSnippet(...) |
editing + editor |
enableInlineEditing + editorType |
sorting / filtering |
rowSortingFeature / columnFilteringFeature |
grouping |
columnGroupingFeature + api.setGroupBy() |
paging + pager |
showPagination |
element events (change, ...) |
onCellValueChange, onApiReady |
theme attribute |
--sg-* tokens / Tailwind |
Before / after
The example at the end of this page runs against these rows:
<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>
- <smart-grid id="grid" sorting filtering paging></smart-grid>
- <script>
- const grid = document.querySelector('#grid')
- grid.dataSource = new Smart.DataAdapter({ dataSource: rows, dataFields: [...] })
- grid.columns = [
- { label: 'Name', dataField: 'name' },
- { label: 'Amount', dataField: 'amount' },
- ]
- </script>
+ <script lang="ts">
+ import {
+ SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,
+ type ColumnDef,
+ } from '@svgrid/grid'
+ const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })
+ const columns: ColumnDef<typeof features, Row>[] = [
+ { field: 'name', header: 'Name' },
+ { field: 'amount', header: 'Amount', format: { type: 'currency', currency: 'USD' } },
+ ]
+ </script>
+
+ <SvGrid data={rows} columns={columns} features={features} showPagination />
What changes
- Custom element + DataAdapter → reactive
$state. Data binding is a prop, not an assigneddataSource. - Element templates → Svelte snippets via
renderSnippet. themeattribute →--sg-*tokens.
A note on family
Smart.Grid is a genuinely good framework-agnostic grid from the same team, and it runs in Svelte as a web component. The reason to pick SvGrid is idiomatic Svelte: runes, snippets, and an MIT core. If you need one grid across Angular, React, Vue, Svelte, and vanilla, Smart.Grid is the right call.
Frequently asked questions
Is SvGrid from the same team as Smart.Grid?
Yes. Smart Web Components (htmlelements.com) and SvGrid are built by the same team. SvGrid is the Svelte-5-native option with an MIT community core.
Can I keep using Smart.Grid in Svelte instead?
Yes - Smart.Grid is a web component and works inside Svelte. Choose SvGrid when you want an idiomatic Svelte component (runes + snippets) rather than a custom element bound through properties.
How do Smart.Grid columns map to SvGrid?
label becomes header, dataField becomes field, and element templates
become renderSnippet cells. Sorting / filtering / grouping move to registered
features.
More examples
Smart.Chart integration
Mounts a
Open the live example: Smart.Chart integration (Integrations)
What you end up with
Sorting, filtering and editing with a footer summary.
<SvGrid data={rows} {columns} sortable filterable editable summary />
The ported grid, running
Sorting, filtering, editing and a totals row - the working set a Smart grid usually carries, as props.
<script lang="ts">
import { SvGrid, type GridColumns } from '@svgrid/grid'
type Person = {
id: number
name: string
city: string
age: number
salary: number
}
const seed: Person[] = [
{ id: 1, name: 'Ada Lovelace', city: 'London', age: 36, salary: 142000 },
{ id: 2, name: 'Grace Hopper', city: 'New York', age: 45, salary: 168000 },
{ id: 3, name: 'Linus Torvalds', city: 'Portland', age: 54, salary: 155000 },
]
let rows = $state<Person[]>(seed.map((p) => ({ ...p })))
const columns: GridColumns<Person> = [
{ field: 'name', header: 'Name', width: 180, editorType: 'text' },
{ field: 'city', header: 'City', width: 150, editorType: 'text' },
{ field: 'salary', header: 'Salary', width: 150, editorType: 'number', summary: 'sum',
format: { type: 'currency', currency: 'USD' } },
]
</script>
<SvGrid data={rows} {columns} sortable filterable editable summary />
See also
- SvGrid vs Smart.Grid - the side-by-side comparison
- About SvGrid - built by jQWidgets / htmlelements.com
- Cell components - snippet-based custom cells
Related articles
- 15 Years of UI Components - The Story Behind jQWidgets and Smart UI - How a team spent 15 years shipping data grids - from jQuery widgets in 2011 to web components to a Svelte 5 native grid - and what actually changed each time.
- Snippets vs Slots in Svelte 5 - Svelte 5 replaces slots with snippets - a first-class value you can pass as a prop, store in a variable, or select at runtime. Here is what changed, why it matters for grid cell rendering, and where the edge cases bite.
- Migrating a Svelte 4 Table Component to Svelte 5 - A concept-by-concept guide to porting a hand-rolled Svelte 4 data table to Svelte 5 runes - props, reactivity, stores, slots, events, and when to stop hand-rolling entirely.