@smallwebco/tinypivot-vue
| Install | |
|---|---|
npm install @smallwebco/tinypivot-vue |
|
| Latest Version: | 1.3.1 |
| Vue: | 3 |
| License: | Custom |
| Last Updated: | Oct 12, 2026 |
| Links: | GitHub · npm |
@smallwebco/tinypivot-vue
A lightweight data grid with free pivot tables, Pro charts, and optional AI-powered data exploration for Vue 3. Under 50KB gzipped — 10x smaller than AG Grid.
Why TinyPivot?
- Lightweight: Under 50KB gzipped vs 500KB+ for AG Grid
- Free Pivot Tables: Sum aggregations, totals, and calculated fields included
- Pro Upgrade: Advanced aggregations, charts, AI Data Analyst, and no watermark
- AI Data Analyst (Pro): Natural language queries with BYOK — use your own OpenAI/Anthropic key
- Lifetime License: No subscriptions — buy once, use forever
Installation
pnpm add @smallwebco/tinypivot-vue
Quick Start
<script setup lang="ts">
import { DataGrid } from '@smallwebco/tinypivot-vue'
import '@smallwebco/tinypivot-vue/style.css'
const data = [
{ id: 1, region: 'North', product: 'Widget A', sales: 12500, units: 150 },
{ id: 2, region: 'North', product: 'Widget B', sales: 8300, units: 95 },
{ id: 3, region: 'South', product: 'Widget A', sales: 15200, units: 180 },
{ id: 4, region: 'South', product: 'Widget B', sales: 9800, units: 110 },
]
</script>
<template>
<DataGrid
:data="data"
:enable-export="true"
:enable-search="true"
:enable-pagination="true"
:page-size="100"
theme="light"
/>
</template>
Theming
TinyPivot ships 22 themes — 2 neutral (light, dark) plus 10 brand themes each with a light and dark variant. Themes are applied via the theme prop on DataGrid.
Quick start
<DataGrid :data="data" theme="slate-dark" />
theme="auto" resolves to 'light' or 'dark' based on the user's system preference (prefers-color-scheme).
Available themes
| Theme | Accent | Vibe |
|---|---|---|
light / dark / auto |
indigo / violet | TinyPivot defaults — neutral cool grays |
slate / slate-dark |
#4f46e5 indigo |
Linear / Stripe — cool neutral |
zinc / zinc-dark |
near-mono | Vercel / Anthropic — minimalist |
indigo / indigo-dark |
#6366f1 vivid indigo |
Premium SaaS |
violet / violet-dark |
#8b5cf6 purple |
Data viz / AI tools |
emerald / emerald-dark |
#10b981 green |
Fintech / finance |
sky / sky-dark |
#0ea5e9 light blue |
Productivity / airy |
rose / rose-dark |
#f43f5e warm pink |
Friendly / creator |
amber / amber-dark |
#f59e0b warm orange |
Energy / wellness |
solar / solar-dark |
#b58900 mustard |
Solarized-inspired warm cream + dark teal |
mono / mono-dark |
#000 / #fff |
Editorial — pure grayscale, high contrast |
Custom themes
Brand themes redefine ~25 CSS custom property tokens at the grid root. You can override these in your own CSS to create a custom theme:
<template>
<DataGrid :data="data" theme="light" class="my-brand" />
</template>
<style>
.vpg-data-grid.my-brand {
--vpg-accent: #ff6b35;
--vpg-accent-hover: #e55426;
--vpg-surface-bg: #fafaf7;
--vpg-surface-panel: #f0eee7;
/* …override any of the tokens below */
}
</style>
Token reference — these are the variables you can override:
- Surfaces:
--vpg-surface-bg,--vpg-surface-panel,--vpg-surface-elevated,--vpg-surface-hover,--vpg-surface-selected,--vpg-surface-striped - Text:
--vpg-text-primary,--vpg-text-secondary,--vpg-text-muted,--vpg-text-inverse - Borders:
--vpg-border-default,--vpg-border-strong,--vpg-border-subtle - Accent:
--vpg-accent,--vpg-accent-hover,--vpg-accent-soft-bg,--vpg-accent-soft-text,--vpg-focus-ring - States:
--vpg-state-error,--vpg-state-warning,--vpg-state-success,--vpg-state-info - Scrollbar:
--vpg-scrollbar-thumb,--vpg-scrollbar-track
Custom theme classes layer on top of any preset, so you can start from theme="dark" and tweak just the accent, for example.
Adding a theme switcher
Let users pick their own theme — bind a reactive theme value to a <select>:
<script setup lang="ts">
import { DataGrid } from '@smallwebco/tinypivot-vue'
import '@smallwebco/tinypivot-vue/style.css'
import { ref } from 'vue'
const theme = ref<'light' | 'dark' | 'slate' | 'slate-dark' | 'emerald' | 'emerald-dark'>('dark')
const data = [/* ... */]
</script>
<template>
<select v-model="theme">
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="slate-dark">Slate (dark)</option>
<option value="emerald-dark">Emerald (dark)</option>
<!-- …add more themes -->
</select>
<DataGrid :data="data" :theme="theme" />
</template>
Features
| Feature | Free | Pro |
|---|---|---|
| Excel-like data grid | ✅ | ✅ |
| Column filtering & sorting | ✅ | ✅ |
| Global search | ✅ | ✅ |
| CSV export | ✅ | ✅ |
| Pagination | ✅ | ✅ |
| Column resizing | ✅ | ✅ |
| Clipboard (Ctrl+C) | ✅ | ✅ |
| Dark mode | ✅ | ✅ |
| Pivot table with Sum aggregation | ✅ | ✅ |
| Row/column totals | ✅ | ✅ |
| Calculated fields with formulas | ✅ | ✅ |
| Pivot row group expand/collapse | ✅ | ✅ |
| Axis value filters (filter row/column items) | ✅ | ✅ |
| Pivot drill-through (double-click to inspect source rows) | ❌ | ✅ |
| Excel (XLSX) Export (styled, multi-level pivot headers, lazy-loaded) | ❌ | ✅ |
| AI Data Analyst (natural language, BYOK) | ❌ | ✅ |
| Chart Builder (6 chart types) | ❌ | ✅ |
| Advanced aggregations (Count, Avg, Min, Max, Unique, Median, Std Dev, %) | ❌ | ✅ |
| No watermark | ❌ | ✅ |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
data |
Record<string, unknown>[] |
required | Array of data objects |
loading |
boolean |
false |
Show loading spinner |
fontSize |
'xs' | 'sm' | 'base' |
'xs' |
Font size preset |
showPivot |
boolean |
true |
Show pivot toggle |
enableExport |
boolean |
true |
Show the Export dropdown menu (CSV free / Excel .xlsx Pro) |
enableSearch |
boolean |
true |
Show global search |
enablePagination |
boolean |
false |
Enable pagination |
pageSize |
number |
50 |
Rows per page |
enableColumnResize |
boolean |
true |
Drag to resize columns |
enableClipboard |
boolean |
true |
Ctrl+C to copy cells |
theme |
string |
'light' |
Color theme — see Theming for the full list (22 presets) |
numberFormat |
'us' | 'eu' | 'plain' |
'us' |
Number display format: US (1,234.56), EU (1.234,56), plain (1234.56) |
dateFormat |
'us' | 'eu' | 'iso' |
'iso' |
Date display format: US (MM/DD/YYYY), EU (DD/MM/YYYY), ISO (YYYY-MM-DD) |
fieldRoleOverrides |
Record<string, FieldRole> |
undefined |
Override auto-detected chart field roles per column ('dimension' | 'measure' | 'temporal') |
enableDrillDown |
boolean |
true |
Enable pivot row group expand/collapse chevrons |
enableDrillThrough |
boolean |
true |
Enable double-click drill-through on pivot cells (Pro feature) |
pivotLayout |
'grouped' | 'tabular' |
'grouped' |
Row layout for multi-field pivots: 'grouped' merges repeated parent values into a spanning cell; 'tabular' repeats every value on each row. |
Events
| Event | Payload | Description |
|---|---|---|
@cell-click |
{ row, col, value, rowData } |
Cell clicked |
@selection-change |
{ cells, values } |
Selection changed |
@export |
{ rowCount, filename } |
CSV exported |
@copy |
{ text, cellCount } |
Cells copied |
@collapse-change |
string[] |
Pivot row groups collapsed/expanded (array of collapsed path keys) |
@drill-through |
DrillThroughResult |
Pivot cell double-clicked and drill-through modal opened (Pro) |
Export
When enableExport is true (the default), the toolbar shows a single Export dropdown button. Clicking it opens a menu with two items:
- CSV — always available (free). Downloads a
.csvfile of the current view. - Excel (.xlsx) — Pro only. Free users see this item disabled with a Pro badge. Pro users get a styled
.xlsxdownload.exceljs(~250 KB) loads lazily via dynamic import — never part of your main bundle.
CSV Export (Free)
import { exportToCSV, exportPivotToCSV } from '@smallwebco/tinypivot-vue'
exportToCSV(data, columns, { filename: 'my-data.csv' })
Excel (XLSX) Export (Pro)
import { exportToXLSX, exportPivotToXLSX } from '@smallwebco/tinypivot-vue'
// Flat grid
await exportToXLSX(data, columns, {
filename: 'report.xlsx',
sheetName: 'Sales',
numberFormats: { revenue: '#,##0.00' },
})
// Pivot table
await exportPivotToXLSX(pivotData, rowFields, columnFields, valueFields, {
filename: 'pivot.xlsx',
})
Pivot XLSX: two-sheet workbook
Pivot XLSX export produces a two-sheet workbook:
- Pivot — the styled pivot summary (merged column headers, bold totals row, frozen header).
- Source Data — the underlying source rows as an interactive Excel Table (filter/sort dropdowns,
TableStyleMedium2). Open it in Excel and choose Insert → PivotTable to build a native PivotTable in two clicks.
Note: TinyPivot does not generate a native Excel PivotTable object (exceljs does not support writing pivot table XML). The Source Data sheet is the practical alternative.
## Pivot Drill-Down
### Row Group Expand/Collapse (Free)
When a pivot has two or more row fields, each group row displays a `▸`/`▾` chevron. Click to collapse or expand that group. Alt-click collapses/expands every group at the same depth. Collapsed groups still show correct aggregated values over all rows in the group.
By default (`pivot-layout="grouped"`), the parent row value is rendered once as a vertically spanning cell across its children, making the hierarchy immediately readable. Set `:pivot-layout="'tabular'"` to repeat the parent value on every row instead.
```vue
<template>
<DataGrid
:data="data"
@collapse-change="(collapsedPaths) => console.log('Collapsed:', collapsedPaths)"
/>
</template>
Drill-Through to Source Rows (Pro)
Double-click any pivot value cell (including totals) to open a modal with the underlying source rows. Includes a slice description header, paginated table (50/page), and CSV export. Requires a Pro license.
<template>
<DataGrid
:data="data"
@drill-through="({ rows, descriptor }) => console.log(`${descriptor.rowCount} rows`)"
/>
</template>
Disable either behaviour individually:
<DataGrid :data="data" :enable-drill-down="false" :enable-drill-through="false" />
AI Data Analyst (Pro)
Optional AI-powered data analyst that lets users explore data using natural language. Ask questions like "What's the return rate by category?" and get instant results.
See the AI Analyst Demo for a complete working example.
<script setup lang="ts">
import { DataGrid } from '@smallwebco/tinypivot-vue'
import '@smallwebco/tinypivot-vue/style.css'
const data = [/* your data */]
const aiConfig = {
enabled: true,
aiEndpoint: '/api/ai-proxy', // Your AI proxy endpoint
databaseEndpoint: '/api/tp-database', // Optional: auto-discover tables
aiModelName: 'Claude Sonnet 4', // Optional: display in UI
persistToLocalStorage: true, // Preserve conversation on tab switch
}
</script>
<template>
<DataGrid
:data="data"
:ai-analyst="aiConfig"
/>
</template>
AI Analyst Config Options
| Option | Type | Description |
|---|---|---|
enabled |
boolean |
Enable the AI Analyst tab |
aiEndpoint |
string |
Your AI proxy endpoint (keeps API keys secure) |
databaseEndpoint |
string |
Unified endpoint for table discovery and queries |
dataSources |
AIDataSource[] |
Manual list of available tables |
queryExecutor |
function |
Custom query executor (e.g., client-side DuckDB) |
aiModelName |
string |
Display name for the AI model in UI |
persistToLocalStorage |
boolean |
Persist conversation across tab switches |
sessionId |
string |
Unique session ID for conversation isolation |
maxRows |
number |
Max rows to return (default: 10000) |
demoMode |
boolean |
Use canned responses (no real AI calls) |
AI Analyst Events
| Event | Payload | Description |
|---|---|---|
@ai-data-loaded |
{ data, query, rowCount } |
Query results loaded |
@ai-conversation-update |
{ conversation } |
Conversation state changed |
@ai-query-executed |
{ query, rowCount, duration, success } |
SQL query executed |
@ai-error |
{ message, type } |
Error occurred |
State Preservation
The AI Analyst preserves state when switching between tabs (Grid, Pivot, Chart, AI):
- Conversation history is maintained in memory
- Query results are preserved
- SQL queries remain accessible via the SQL panel
To persist across page refreshes, enable persistToLocalStorage: true. The conversation will be saved to localStorage using the sessionId as the key.
For production apps, listen to @ai-conversation-update to implement your own persistence:
<template>
<DataGrid
:data="data"
:ai-analyst="aiConfig"
@ai-conversation-update="saveConversation"
/>
</template>
<script setup>
function saveConversation({ conversation }) {
// Save to your backend
api.saveConversation(userId, conversation)
}
</script>
Documentation
See the full documentation for complete API reference, styling, and Pro license activation.
License
- Free Tier: MIT License for core grid and pivot features
- Pro Features: Commercial license required
Purchase at tiny-pivot.com/#pricing
Built with ❤️ by Small Web, LLC
Related Packages
Vue data grid and Vue table for modern apps with Excel-like editing, filtering,...
A high-performance Vue 3 data grid component with virtual scrolling, cell select...
Zero-dependency, framework-agnostic data grid web component with virtualization,...
Jspreadsheet is a lightweight, vanilla javascript plugin to create amazing web-b...
Jspreadsheet CE is a lightweight, vanilla JavaScript plugin for creating powerfu...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.3.1 | ^3.3.0 | Custom | |
| 1.3.0 | ^3.3.0 | Custom | |
| 1.2.1 | ^3.3.0 | Custom | |
| 1.2.0 | ^3.3.0 | Custom | |
| 1.1.2 | ^3.3.0 | Custom | |
| 1.1.1 | ^3.3.0 | Custom | |
| 1.1.0 | ^3.3.0 | Custom | |
| 1.0.83 | ^3.3.0 | Custom | |
| 1.0.81 | ^3.3.0 | Custom | |
| 1.0.80 | ^3.3.0 | Custom | |
| 1.0.79 | ^3.3.0 | Custom | |
| 1.0.74 | ^3.3.0 | Custom | |
| 1.0.73 | ^3.3.0 | Custom | |
| 1.0.72 | ^3.3.0 | Custom | |
| 1.0.71 | ^3.3.0 | Custom | |
| 1.0.70 | ^3.3.0 | Custom | |
| 1.0.69 | ^3.3.0 | Custom | |
| 1.0.68 | ^3.3.0 | Custom | |
| 1.0.67 | ^3.3.0 | Custom | |
| 1.0.66 | ^3.3.0 | Custom | |
| 1.0.65 | ^3.3.0 | Custom | |
| 1.0.64 | ^3.3.0 | Custom | |
| 1.0.63 | ^3.3.0 | Custom | |
| 1.0.62 | ^3.3.0 | Custom | |
| 1.0.61 | ^3.3.0 | Custom | |
| 1.0.60 | ^3.3.0 | Custom | |
| 1.0.59 | ^3.3.0 | Custom | |
| 1.0.58 | ^3.3.0 | Custom | |
| 1.0.57 | ^3.3.0 | Custom | |
| 1.0.55 | ^3.3.0 | Custom |
Showing the latest 30 of 69. See every release on npm