Introduction
A framework-agnostic data grid web component written in pure TypeScript, with no runtime dependencies. Import it, give it a height, and assign an array of rows.
What you get
Section titled “What you get”It exists because we wanted one grid that works in every framework, with no licence tier. The same codebase and the same API serve a vanilla prototype and an Angular enterprise app.
| Feature | Description |
|---|---|
| 🚀 Performance | Virtualized rendering handles 100k+ rows at 60fps |
| 🔧 Framework agnostic | One codebase for vanilla JS, React, Vue, Angular, Svelte |
| 📦 Bundle size | ~47 kB gzipped, zero runtime dependencies |
| 🧩 Plugins | Lifecycle hooks, dependency validation, type-safe config extension |
| ⌨️ Keyboard | Arrow keys, Tab, Enter, Escape, Home/End, Page Up/Down |
| 🎨 Theming | CSS custom properties, six built-in themes |
| 💡 Errors | Actionable messages with import hints and fix suggestions |
| 🆓 Licence | MIT — no enterprise tier, no feature gates |
Quick Start
Section titled “Quick Start”The grid ships as a standard custom element. Pick the install style that matches your setup.
npm install @toolbox-web/gridimport '@toolbox-web/grid';import { queryGrid } from '@toolbox-web/grid';
const grid = queryGrid('tbw-grid');grid.columns = [ { field: 'id', header: 'ID', type: 'number', sortable: true }, { field: 'name', header: 'Name', sortable: true }, { field: 'email', header: 'Email' },];grid.rows = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' }, { id: 3, name: 'Carol', email: 'carol@example.com' },];<tbw-grid style="height: 300px;"></tbw-grid>Drop one <script> tag and you’re done — no bundler, no install. Everything is exposed on the global TbwGrid object.
<!DOCTYPE html><script src="https://unpkg.com/@toolbox-web/grid/umd/grid.umd.js"></script>
<tbw-grid id="my-grid" style="height: 300px;"></tbw-grid>
<script> const grid = TbwGrid.queryGrid('#my-grid'); grid.columns = [ { field: 'id', header: 'ID', type: 'number', sortable: true }, { field: 'name', header: 'Name', sortable: true }, { field: 'email', header: 'Email' }, ]; grid.rows = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' }, { id: 3, name: 'Carol', email: 'carol@example.com' }, ];</script>See the Getting Started guide for framework integration (React, Vue, Angular), declarative HTML, plugins, and TypeScript setup.
Live Demo
Section titled “Live Demo”A basic grid with sortable columns. Click column headers to sort.
<tbw-grid style="height: 250px;"></tbw-grid> import '@toolbox-web/grid';import { queryGrid } from '@toolbox-web/grid';
const grid = queryGrid('tbw-grid'); if (grid) { grid.columns = [ { field: 'id', header: 'ID', type: 'number', sortable: true }, { field: 'name', header: 'Name', sortable: true }, { field: 'email', header: 'Email' }, ]; grid.rows = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' }, { id: 3, name: 'Carol', email: 'carol@example.com' }, { id: 4, name: 'Dan', email: 'dan@example.com' }, { id: 5, name: 'Eve', email: 'eve@example.com' }, ]; }Architecture
Section titled “Architecture”Six patterns do most of the work:
| Pattern | What It Does |
|---|---|
| Centralized Render Scheduler | Batches all updates into a single requestAnimationFrame per frame—no layout thrashing |
| Phase-Based Execution | Prioritizes work (config → rows → columns → render) for predictable updates |
| DOM Recycling | Reuses row elements via a pool with epoch-based invalidation—minimal GC pressure |
| Template Cloning | Pre-created templates cloned via cloneNode(true)—3-4x faster than createElement |
| Event Delegation | Single listener per event type on the container—scales to any dataset size |
| Faux Scrollbar | Separates scroll container from content—no reflow during scroll |
Read the full Architecture deep-dive for implementation details.
Plugin System
Section titled “Plugin System”The core grid is small. Everything beyond rendering, sorting and virtualization ships as a tree-shakeable plugin — import only what you need:
- SelectionPlugin — Cell, row, or range selection
- FilteringPlugin — Column header filters with custom panels
- EditingPlugin — Inline editing with built-in and custom editors
- GroupingRowsPlugin — Hierarchical row grouping with aggregations
- TreePlugin — Expandable tree data with lazy loading
- MasterDetailPlugin — Expandable detail rows
- ExportPlugin — CSV, Excel, or JSON export
- ClipboardPlugin — Copy/paste with Excel-compatible formatting
- …and many more
Plugins get dependency validation, type-safe config extension, and auto-cleanup via AbortSignal. They use the same public API third parties do, so you can build and distribute your own.
AI-Assisted Development
Section titled “AI-Assisted Development”Using an AI coding assistant like GitHub Copilot, Cursor, or ChatGPT? We publish machine-readable docs (llms.txt, llms-full.txt, and a Markdown companion for every page) so your assistant generates correct grid code grounded in the current API.
See AI-Assisted Development for what we publish, where it comes from, and how to wire it into your agentic workflow.