
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
@mindfiredigital/pivothead-web-component
Advanced tools
Web Component implementation of PivotHead for use in any JavaScript framework
Universal Pivot Tables for Any JavaScript Framework
Features • Installation • Quick Start • API • Examples • Support
** Try it live**: Check out the examples directory for working demos across different modes and frameworks
Framework Agnostic
|
WebAssembly Performance
|
Three Rendering ModesDefault Mode - Full UI included
Minimal Mode - Customizable slots
Headless Mode - Full API control
|
Rich Data Features
|
# npm
npm install @mindfiredigital/pivothead-web-component
# yarn
yarn add @mindfiredigital/pivothead-web-component
# pnpm
pnpm add @mindfiredigital/pivothead-web-component
# CDN (for quick prototyping)
<script type="module" src="https://unpkg.com/@mindfiredigital/pivothead-web-component"></script>
<!DOCTYPE html>
<html>
<head>
<title>PivotHead Demo</title>
</head>
<body>
<pivot-head id="myPivot"></pivot-head>
<script type="module">
import '@mindfiredigital/pivothead-web-component';
const pivotTable = document.getElementById('myPivot');
// Sample data
const salesData = [
{ product: 'Laptop', region: 'North', sales: 5000, quarter: 'Q1' },
{ product: 'Phone', region: 'South', sales: 3000, quarter: 'Q1' },
{ product: 'Tablet', region: 'East', sales: 2000, quarter: 'Q2' },
// ... more data
];
// Configure the pivot
const options = {
rows: ['product'],
columns: ['region'],
values: ['sales'],
};
pivotTable.data = salesData;
pivotTable.options = options;
// Listen for events
pivotTable.addEventListener('stateChange', e => {
console.log('Pivot state changed:', e.detail);
});
</script>
</body>
</html>
import { useEffect, useRef } from 'react';
import '@mindfiredigital/pivothead-web-component';
export default function PivotDemo() {
const pivotRef = useRef<HTMLElement>(null);
useEffect(() => {
if (pivotRef.current) {
pivotRef.current.data = salesData;
pivotRef.current.options = {
rows: ['product'],
columns: ['region'],
values: ['sales'],
};
}
}, []);
return <pivot-head ref={pivotRef}></pivot-head>;
}
Prefer React? Use our official React wrapper:
@mindfiredigital/pivothead-react
<template>
<pivot-head
:data="salesData"
:options="pivotOptions"
@stateChange="handleStateChange"
/>
</template>
<script setup>
import { ref } from 'vue';
import '@mindfiredigital/pivothead-web-component';
const salesData = ref([...]);
const pivotOptions = ref({
rows: ['product'],
columns: ['region'],
values: ['sales']
});
const handleStateChange = (e) => {
console.log('State:', e.detail);
};
</script>
// app.component.ts
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import '@mindfiredigital/pivothead-web-component';
@Component({
selector: 'app-root',
template: `<pivot-head
[attr.data]="dataJson"
[attr.options]="optionsJson"
></pivot-head>`,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppComponent {
dataJson = JSON.stringify(salesData);
optionsJson = JSON.stringify({
rows: ['product'],
columns: ['region'],
values: ['sales'],
});
}
Perfect for rapid development with zero configuration.
<pivot-head
data='[{"product":"A","sales":100}]'
options='{"rows":["product"],"values":["sales"]}'
></pivot-head>
Includes:
Best for: Admin panels, dashboards, internal tools, rapid prototyping
You control the UI, we handle the data.
<pivot-head mode="minimal" id="customPivot">
<!-- Custom Header Slot -->
<div slot="header" class="my-toolbar">
<button onclick="document.getElementById('customPivot').exportToPDF()">
Export PDF
</button>
<button onclick="document.getElementById('customPivot').exportToExcel()">
Export Excel
</button>
</div>
<!-- Custom Body Slot -->
<div slot="body" id="tableContainer"></div>
</pivot-head>
<script type="module">
import '@mindfiredigital/pivothead-web-component';
const pivot = document.getElementById('customPivot');
pivot.addEventListener('stateChange', e => {
const { headers, rows, totals } = e.detail.processedData;
// Render your custom table
const tableHTML = `
<table class="my-custom-table">
<thead>
<tr>${headers.map(h => `<th>${h}</th>`).join('')}</tr>
</thead>
<tbody>
${rows
.map(
row => `
<tr>${row.map(cell => `<td>${cell}</td>`).join('')}</tr>
`
)
.join('')}
</tbody>
</table>
`;
document.getElementById('tableContainer').innerHTML = tableHTML;
});
pivot.data = yourData;
pivot.options = yourOptions;
</script>
Best for: Custom designs, branded applications, unique UX requirements
Zero UI, maximum flexibility. Build anything on top of the pivot engine.
<pivot-head id="headless" mode="none"></pivot-head>
<div id="myCustomUI">
<!-- Your completely custom UI here -->
</div>
<script type="module">
import '@mindfiredigital/pivothead-web-component';
const pivot = document.getElementById('headless');
pivot.addEventListener('stateChange', e => {
const state = e.detail;
// Build your custom visualization
renderCustomChart(state.processedData);
renderCustomFilters(state.filters);
renderCustomStats(state.processedData.totals);
});
pivot.data = yourData;
pivot.options = yourOptions;
// Use the full API
function handleSort(field) {
pivot.sort(field, 'desc');
}
function handleExport() {
pivot.exportToPDF('my-report');
}
</script>
Best for: Custom visualizations, D3.js integrations, charting libraries, unique interfaces
<input type="file" id="csvUpload" accept=".csv" />
<pivot-head id="pivot"></pivot-head>
<script type="module">
import '@mindfiredigital/pivothead-web-component';
const pivot = document.getElementById('pivot');
document.getElementById('csvUpload').addEventListener('change', async e => {
const file = e.target.files[0];
// Just pass the File object - automatic optimization!
pivot.data = file;
pivot.addEventListener('stateChange', e => {
console.log('Performance mode:', e.detail.performanceMode);
// Output: 'standard', 'workers', 'wasm', or 'streaming-wasm'
});
});
</script>
| File Size | Strategy | Processing Time* | Memory |
|---|---|---|---|
| < 1 MB | JavaScript | ~50ms | Low |
| 1-8 MB | Web Workers | ~200ms | Medium |
| 8-100 MB | WASM (in-memory) | ~800ms | Medium |
| 100MB-1GB | WASM + Streaming | ~3-5s | Low (chunked) |
Key Benefits:
| Property | Type | Default | Description |
|---|---|---|---|
mode | 'default' | 'minimal' | 'none' | 'default' | Rendering mode |
data | Array | File | string | [] | Data source (array, CSV File, or JSON string) |
options | object | string | {} | Pivot configuration |
filters | object | string | [] | Active filters |
pagination | object | string | {} | Pagination settings |
Access via JavaScript:
const pivot = document.querySelector('pivot-head');
// State Management
pivot.getState() // Get current state
pivot.refresh() // Refresh the pivot table
pivot.getData() // Get raw data
pivot.getProcessedData() // Get processed/grouped data
// Configuration
pivot.setMeasures([...]) // Update measures
pivot.setDimensions([...]) // Update dimensions
pivot.setGroupConfig({...}) // Update grouping
pivot.setLayout(rows, cols, vals) // Set complete layout
// Data Manipulation
pivot.sort(field, direction) // Sort by field ('asc' | 'desc')
pivot.filter(field, operator, val) // Apply filter
pivot.clearFilters() // Remove all filters
// Pagination
pivot.setPageSize(size) // Set page size
pivot.goToPage(pageNum) // Navigate to page
pivot.getPagination() // Get pagination state
// Export
pivot.exportToPDF(fileName) // Export to PDF
pivot.exportToExcel(fileName) // Export to Excel
pivot.exportToHTML(fileName) // Export to HTML
// File Operations (ConnectService)
await pivot.connectToLocalCSV() // Open CSV file picker
await pivot.connectToLocalJSON() // Open JSON file picker
await pivot.connectToLocalFile() // Open file picker (any supported format)
| Event | Detail Type | Description |
|---|---|---|
stateChange | PivotTableState | Emitted on any state change (data, sort, filter, etc.) |
dataLoaded | { recordCount, fileSize } | Emitted when file loading completes |
error | { message, code } | Emitted on errors |
pivot.addEventListener('stateChange', event => {
const state = event.detail;
console.log('Headers:', state.processedData.headers);
console.log('Rows:', state.processedData.rows);
console.log('Totals:', state.processedData.totals);
console.log('Performance mode:', state.performanceMode);
});
pivot.addEventListener('dataLoaded', event => {
console.log(`Loaded ${event.detail.recordCount} records`);
});
import type {
PivotTableState,
PivotTableOptions,
FilterConfig,
PaginationConfig,
} from '@mindfiredigital/pivothead';
interface PivotTableState<T> {
data: T[];
processedData: {
headers: string[];
rows: any[][];
totals: Record<string, number>;
};
filters: FilterConfig[];
pagination: PaginationConfig;
performanceMode?: 'standard' | 'workers' | 'wasm' | 'streaming-wasm';
// ... other properties
}
<div class="dashboard">
<h1>Sales Analytics</h1>
<pivot-head id="salesPivot"></pivot-head>
<div class="actions">
<button onclick="exportReport()">Export Report</button>
<button onclick="refreshData()">Refresh</button>
</div>
</div>
<script type="module">
import '@mindfiredigital/pivothead-web-component';
const pivot = document.getElementById('salesPivot');
// Fetch data from API
async function loadSalesData() {
const response = await fetch('/api/sales/2024');
const data = await response.json();
pivot.data = data;
pivot.options = {
rows: ['region', 'product'],
columns: ['quarter'],
values: ['sales', 'profit'],
};
}
function exportReport() {
pivot.exportToPDF('sales-report-2024');
}
function refreshData() {
loadSalesData();
}
loadSalesData();
</script>
<pivot-head mode="minimal">
<div slot="header" class="custom-toolbar">
<h2>Company Analytics</h2>
<div class="toolbar-actions">
<select id="timeRange">
<option>Last 7 days</option>
<option>Last 30 days</option>
<option>Last year</option>
</select>
</div>
</div>
<div slot="body" id="tableBody"></div>
</pivot-head>
<pivot-head id="livePivot"></pivot-head>
<script type="module">
import '@mindfiredigital/pivothead-web-component';
const pivot = document.getElementById('livePivot');
let currentData = [];
// Connect to WebSocket for real-time updates
const ws = new WebSocket('wss://api.example.com/live-data');
ws.onmessage = event => {
const newRecord = JSON.parse(event.data);
currentData.push(newRecord);
// Update pivot with new data
pivot.data = [...currentData];
};
pivot.options = {
rows: ['category'],
columns: ['status'],
values: ['count'],
};
</script>
Build pivot tables for any framework:
| Package | Description | NPM | Documentation |
|---|---|---|---|
| @mindfiredigital/pivothead | Core TypeScript engine | README | |
| @mindfiredigital/pivothead-react | React wrapper component | - | README |
| @mindfiredigital/pivothead-vue | Vue wrapper | - | Coming soon |
We welcome contributions! See our Contributing Guide to get started.
If PivotHead helps your project, please consider:
Check out complete working examples in the repository:
| Example | Description | Path |
|---|---|---|
| Vanilla JS | Pure JavaScript implementation | simple-js-demo |
| Default Mode | Full UI with all features | pivothead-default-demo |
| Minimal Mode | Custom rendering with slots | pivothead-minimal-demo |
| Headless Mode | Complete control for custom visualizations | pivothead-none-demo |
| React Integration | Using web component in React | react-web-component-demo |
| Vue Integration | Using web component in Vue | vue-example |
# Clone the repository
git clone https://github.com/mindfiredigital/PivotHead.git
cd PivotHead
# Navigate to an example (e.g., simple-js-demo)
cd examples/simple-js-demo
# Install dependencies
pnpm install
# Start development server
pnpm dev
MIT © Mindfiredigital
Built with ❤️ by the Mindfiredigital team
FAQs
Web Component implementation of PivotHead for use in any JavaScript framework
We found that @mindfiredigital/pivothead-web-component demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.