TL;DR: GridKit Enhanced adds enterprise features (audit logs, analytics, validation, plugins) to TanStack Table in 2-3 days instead of 3-4 weeks of custom development. Overhead: ~5-15ms. Try the live demo →
You love TanStack Table. It's flexible, headless, gives you full control.
Then business requirements arrive:
- "We need audit logging for compliance"
- "Can we track how often users change sorting?"
- "Users want Excel export"
- "Why does the table lag with 10K rows?"
- "We need analytics on user interactions"
You realize: TanStack is great, but enterprise features mean 3-4 weeks of custom development:
- Event system (instead of endless
useEffectchains) - Performance monitoring (metrics, alerts)
- Validation (schema, checking, auto-fix)
- Plugin management (audit, analytics, export)
The Solution
GridKit Enhanced is an adapter for TanStack Table that adds enterprise features without changing your existing code.
// 1. Create your TanStack table (as usual)
const tanstackTable = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
});
// 2. Wrap with GridKit (add enterprise features)
const table = createEnhancedTable(tanstackTable, {
events: true,
performance: true,
plugins: [auditLogPlugin()],
});
// 3. All TanStack APIs still work + new features
table.getRowModel(); // ✅ TanStack
table.on('row:select', handler); // ✅ GridKit
Result: Enterprise features in 2-3 days instead of 3-4 weeks.
Honest warning: ~5-15ms overhead. For enterprise apps, this is an acceptable trade-off.
Why TanStack + GridKit?
TanStack Table gives you:
- ✅ Full control over rendering
- ✅ No hidden abstractions
- ✅ Works with any UI library
- ✅ TypeScript out of the box
But you build everything yourself:
| Feature | TanStack | GridKit Enhanced |
|---|---|---|
| Basic table | ✅ | ✅ |
| Event system | ❌ | ✅ |
| Performance monitoring | ❌ | ✅ |
| Validation | ❌ | ✅ |
| Plugin ecosystem | ❌ | ✅ |
| Audit logging | ❌ | ✅ |
GridKit provides "backend for your table":
- 📊 Events — instead of
useEffectfor tracking - 📈 Metrics — instead of custom monitoring
- 🔌 Plugins — instead of building audit/analytics/export from scratch
Architecture
GridKit Enhanced works as an adapter layer between your code and TanStack Table.
Key principles:
- Zero Migration — your TanStack code continues working
- Opt-in Features — enable only what you need
- Transparent Overhead — ~5-15ms for enterprise features
- Type Safe — full TypeScript support
Live Demo
🎯 Try GridKit Enhanced on CodeSandbox
The demo includes 6 interactive examples:
1. Quick Start
Basic table with sorting and event tracking. Click a row → event logged.
2. Event System
See events in action: row:select, sorting:change, filtering:change, pagination:change.
3. Performance
Performance monitoring with metrics (render, sort, filter). Budget violation alerts, memory leak detection.
4. Validation
Schema validation with Zod. Auto-fix errors, validation reports.
5. Plugins
Toggle plugins on/off:
- Audit Log — logs all changes
- Analytics — Mixpanel integration (simulated)
- Export — CSV/Excel/PDF export
6. Benchmarks
TanStack vs GridKit Enhanced comparison.
Try this (30 seconds):
- Open Quick Start demo
- Click a table row
- Check Live Event Log — see the
row:clickevent - Go to Plugins, enable Audit Log
- Click another row
- Compare the log format
Use Cases
Scenario 1: New Table (Greenfield)
Situation: Starting a new project, choosing table stack.
Why GridKit:
- ✅ Enterprise features from day one
- ✅ No rewriting later
- ✅ Best practices built-in
Setup (5 minutes):
npm install @gridkit/tanstack-adapter @tanstack/react-table
const table = createEnhancedTable(tanstackTable, {
events: true,
plugins: [auditLogPlugin()],
});
You get: Event tracking, audit logs, performance monitoring, ready to scale.
Scenario 2: Existing Table (Brownfield)
Situation: You have a working TanStack Table in production.
Why GridKit:
- ✅ Zero breaking changes — your code continues working
- ✅ Add features gradually
- ✅ Can rollback anytime
Setup (30 minutes):
npm install @gridkit/tanstack-adapter
// Before
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
});
// After (added 1 line)
const tanstackTable = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
});
const table = createEnhancedTable(tanstackTable, {}); // Empty options = no changes
Gradual rollout:
// Week 1: Add event tracking
const table = createEnhancedTable(tanstackTable, { events: true });
table.on('row:select', (e) => analytics.track('row_selected', e.payload));
// Week 2: Add audit log
const table = createEnhancedTable(tanstackTable, {
events: true,
plugins: [auditLogPlugin()],
});
// Week 3: Add performance monitoring
const table = createEnhancedTable(tanstackTable, {
events: true,
performance: { budgets: { rowModelBuild: 16 } },
plugins: [auditLogPlugin()],
});
You get: Zero breaking changes, gradual migration, can stop anytime.
Comparison
| Criteria | New Table | Existing Table |
|---|---|---|
| Setup time | 5 minutes | 30 minutes + gradual rollout |
| Risks | None | Minimal (zero breaking changes) |
| Complexity | Low | Medium |
| ROI | Long-term | Immediate (if you need features) |
| Recommendation | ✅ Start with GridKit | ✅ Add gradually |
Quick Start (5 Minutes)
Step 1: Install (30 seconds)
npm install @gridkit/tanstack-adapter
Step 2: Import (30 seconds)
// Before
import { useReactTable } from '@tanstack/react-table';
// After (or keep as is — it works!)
import { createEnhancedTable } from '@gridkit/tanstack-adapter';
Step 3: Create Table (2 minutes)
import { createEnhancedTable } from '@gridkit/tanstack-adapter';
import {
createColumnHelper,
useReactTable,
getCoreRowModel,
} from '@tanstack/react-table';
type User = {
id: string;
name: string;
email: string;
age: number;
};
const columnHelper = createColumnHelper<User>();
const columns = [
columnHelper.accessor('name', { header: 'Name' }),
columnHelper.accessor('email', { header: 'Email' }),
columnHelper.accessor('age', { header: 'Age' }),
];
const data: User[] = [
{ id: '1', name: 'John', email: 'john@example.com', age: 30 },
{ id: '2', name: 'Jane', email: 'jane@example.com', age: 25 },
];
// 1. Create TanStack table
const tanstackTable = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
});
// 2. Add GridKit enterprise features
const table = createEnhancedTable(tanstackTable, {
events: true,
performance: true,
validation: true,
});
Step 4: First Event (2 minutes)
// Subscribe to events
table.on('row:select', (event) => {
console.log('Row selected:', event.payload.rowId);
analytics.track('row_selected', {
rowId: event.payload.rowId,
timestamp: event.timestamp,
});
});
// Or listen to sorting changes
table.on('sorting:change', (event) => {
api.saveUserPreferences({
sorting: event.payload.sorting,
});
});
Done! Enterprise table in 5 minutes.
Event System
Why Events Beat useEffect
Before (TanStack Table):
// 30+ lines for one event
useEffect(() => {
const subscription = table.options.onStateChange?.(state);
if (subscription?.sorting) {
const sortingChanged = !isEqual(prevSorting, subscription.sorting);
if (sortingChanged) {
analytics.track('sorting_changed', {
sorting: subscription.sorting,
timestamp: Date.now(),
});
api.saveUserPreferences({
sorting: subscription.sorting,
});
}
prevSorting = subscription.sorting;
}
}, [table]);
After (GridKit Enhanced):
// 1 line
table.on('sorting:change', (e) => analytics.track('sorting', e.payload));
Available Events
| Event | Payload | Use Case |
|---|---|---|
row:select |
{ rowId, row } |
Analytics, audit |
row:create |
{ row, index } |
Audit, sync |
row:update |
{ rowId, changes } |
Audit, sync |
row:delete |
{ rowId } |
Audit, sync |
sorting:change |
{ sorting } |
Save preferences |
filtering:change |
{ filtering } |
Save preferences |
pagination:change |
{ page, pageSize } |
Save preferences |
performance:budgetViolation |
{ operation, actual, budget } |
Alerting |
validation:error |
{ rowId, field, message } |
UI notifications |
Middleware
import {
createDebounceMiddleware,
createLoggingMiddleware,
} from '@gridkit/tanstack-adapter';
// Debounce frequent events
table.use(
createDebounceMiddleware({
events: ['sorting:change', 'filtering:change'],
wait: 300,
})
);
// Log all events
table.use(
createLoggingMiddleware({
logger: customLogger,
level: 'info',
})
);
Performance: Honest Truth
TL;DR
GridKit Enhanced adds ~5-15ms overhead for enterprise features.
For most enterprise apps, this is negligible:
| Operation | Time |
|---|---|
| Network latency (API) | 50-500ms |
| Database query | 10-100ms |
| User perception threshold | 100ms |
| GridKit overhead | ~5-15ms |
Verdict: GridKit overhead is 10-50x smaller than network latency.
Why GridKit Doesn't "Speed Up" TanStack
GridKit Enhanced is not about speed optimization.
TanStack Table already works great. GridKit adds features that would otherwise take weeks:
| Feature | What It Adds | "Cost" |
|---|---|---|
| Event system | Pub/sub, middleware | ~2-5ms |
| Performance monitoring | Metrics, budgets | ~1-3ms |
| Validation | Schema validation | ~3-7ms |
| Plugin manager | Registration, isolation | ~2-5ms |
| Total | All enterprise features | ~5-15ms |
This has a cost. But for enterprise apps, it's negligible compared to development time saved.
Detailed Benchmarks
Environment: M1 MacBook Pro, Chrome 122
Your results may vary based on hardware, browser, data.
| Rows | Operation | TanStack (ms) | GridKit (ms) | Difference |
|---|---|---|---|---|
| 100 | Render | 0.12 | 0.19 | +0.07ms |
| Sort | 0.48 | 0.17 | -0.31ms (faster) | |
| Filter | 0.11 | 0.19 | +0.08ms | |
| 1,000 | Render | 2.19 | 1.97 | -0.22ms (faster) |
| Sort | 1.10 | 1.16 | +0.06ms | |
| Filter | 1.18 | 2.72 | +1.54ms | |
| 5,000 | Render | 10.15 | 6.01 | -4.14ms (faster) |
| Sort | 5.85 | 14.32 | +8.47ms | |
| Filter | 5.85 | 9.41 | +3.56ms | |
| 10,000 | Render | 9.30 | 11.91 | +2.61ms |
| Sort | 9.37 | 9.23 | -0.14ms (faster) | |
| Filter | 12.45 | 9.21 | -3.24ms (faster) |
Analysis:
| Data Size | Avg Overhead | Verdict |
|---|---|---|
| 100 rows | ~0-1ms | Negligible |
| 1,000 rows | ~0-2ms | Negligible |
| 5,000 rows | ~2-9ms | Noticeable but acceptable |
| 10,000 rows | ~0-3ms | Negligible |
Important:
- Benchmarks are synthetic — real-world difference is usually smaller
- For tables < 50,000 rows, overhead is almost always < 15ms
- Some operations are faster due to GridKit caching
- Some are slower due to event processing and validation
- Positive difference = GridKit slower, Negative = GridKit faster
When GridKit Is the Right Choice
✅ Good fit:
- Enterprise apps with audit/compliance needs
- Teams valuing developer productivity
- Tables with < 50,000 rows
- Apps where event tracking, plugins, validation matter
- Projects with deadlines (weeks vs months)
❌ Consider alternatives when:
- Trading platforms (need every millisecond)
- 100,000+ rows with frequent updates
- Maximum raw performance is critical
- No enterprise feature requirements
- Have time for custom implementation
The Right Question
Don't ask: "Is GridKit faster than TanStack?"
Ask:
"Is 5-15ms overhead worth saving 10+ hours of development
and getting enterprise features out of the box?"
For most enterprise teams: Yes.
ROI Math
Scenario: Team of 3 developers
| Approach | Time to Implement | Time Saved |
|---|---|---|
| TanStack + custom features | 3-4 weeks | — |
| GridKit Enhanced | 2-3 days | ~3 weeks |
Savings: ~15 working days (3 weeks)
5-15ms overhead is worth 3 weeks of saved development time.
Validation
Schema-Based Validation
Use Zod, Yup, or Joi for data validation:
import { z } from 'zod';
import { createEnhancedTable } from '@gridkit/tanstack-adapter';
const userSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().min(0).max(150),
});
const tanstackTable = useReactTable({
columns: [
{
accessorKey: 'email',
meta: {
validation: {
schema: userSchema.shape.email,
mode: 'onChange',
},
},
},
],
data,
getCoreRowModel: getCoreRowModel(),
});
const table = createEnhancedTable(tanstackTable, {
validation: {
mode: 'strict',
throwOnError: false,
autoFix: true,
},
});
Validate Rows
// Validate single row
const result = await table.validateRow(rowData, rowIndex);
if (!result.valid) {
console.log(result.errors);
// [{ field: 'email', message: 'Invalid email format' }]
}
// Bulk validation
const report = table.validateAll();
console.log(report.summary);
// { total: 1000, valid: 987, invalid: 13, warnings: 5 }
Compliance Reports
Generate reports for auditors:
const complianceReport = table.generateValidationReport({
includeAllErrors: true,
format: 'pdf',
timestamp: new Date(),
signedBy: currentUser.id,
});
await complianceApi.submitReport(complianceReport);
Compliance tools:
- 📝 Audit Log — audit trail for GDPR, HIPAA, SOX
- 🔒 PII Masking — protect personal data
- 📊 Validation Reports — auditor-ready reports
⚠️ Important: GridKit provides tools for compliance (audit logging, PII masking, validation reports), but is not certified for GDPR/HIPAA/SOX/ISO 27001.
Your team is responsible for:
- Full compliance implementation
- Legal review
- Certification from accredited bodies
Plugin Ecosystem
Why Plugins Are Powerful
GridKit Enhanced is the only table with a full plugin architecture.*
Unlike AG Grid "modules" or Handsontable "extensions", GridKit plugins:
- ✅ Run in isolated sandbox
- ✅ Can't break table or other plugins
- ✅ Auto-load dependencies
- ✅ Have lifecycle (init/destroy)
- ✅ Access event bus, table instance, config
* Only table with isolated plugin system. Plugins in sandbox, don't break each other.
Analogy: GridKit plugins are like Chrome Extensions for tables.
Ready-to-Use Plugins
import {
auditLogPlugin,
analyticsPlugin,
exportPlugin,
} from '@gridkit/plugins';
const table = createEnhancedTable(tanstackTable, {
plugins: [
// Audit logging for compliance
auditLogPlugin({
destination: 'api/logs',
events: ['row:create', 'row:update', 'row:delete'],
pii: { mask: ['email', 'ssn'] },
}),
// Analytics
analyticsPlugin({
provider: 'mixpanel',
autoTrack: true,
}),
// Export
exportPlugin({
formats: ['csv', 'xlsx', 'pdf'],
}),
],
});
Plugin Use Cases
1. Compliance Prep (GDPR/HIPAA/SOX-ready)
Situation: Need to log all changes for compliance.
Without plugins:
// 200+ lines of code
useEffect(() => {
// Subscribe to all events
// Log every change
// PII masking
// Send to server
// Error handling
// Retry logic
}, []);
With plugin:
auditLogPlugin({
destination: '/api/audit',
events: ['row:create', 'row:update', 'row:delete'],
pii: { mask: ['email', 'ssn'] },
});
// 1 line. Done.
Saves: 2-3 weeks of development.
What Audit Log provides:
- ✅ Audit trail for GDPR (Art. 30), HIPAA (§164.312), SOX (§404)
- ✅ PII masking for data protection
- ✅ Validation reports for auditors
But you still need (not in GridKit):
- ❌ Data encryption
- ❌ Access Control
- ❌ Breach Notification
- ❌ Risk Assessment
- ❌ Certification (your responsibility)
2. Product Analytics
Situation: Need to understand how users interact with table.
Without plugins:
// Manual Mixpanel/Amplitude integration
// Track every event
// Testing
// Maintenance
With plugin:
analyticsPlugin({
provider: 'mixpanel',
autoTrack: true,
});
// 2 lines. All events tracked automatically.
Saves: 1-2 weeks of development.
3. User Export
Situation: Users want CSV/Excel export.
Without plugins:
// Generate CSV
// Format Excel
// Handle large data
// Download file
With plugin:
exportPlugin({
formats: ['csv', 'xlsx', 'pdf'],
});
// Done.
Saves: 3-5 days of development.
4. Custom Plugin for Your Team
Situation: Unique business logic (e.g., sync with external system).
const syncPlugin = {
metadata: {
id: 'sync-external',
name: 'External Sync',
version: '1.0.0',
},
initialize: async (config, context) => {
context.eventBus.on('row:update', async (e) => {
await api.syncToExternal(e.payload);
});
},
destroy: async () => {
// Cleanup
},
};
table.registerPlugin(syncPlugin);
Benefits:
- Plugin is isolated — won't break table
- Auto-subscribes to events
- Has lifecycle (cleanup on unmount)
Available Plugins
| Plugin | Description | Use Case |
|---|---|---|
| Audit Log | Logs all changes | Compliance-ready (GDPR, HIPAA, SOX) |
| Analytics | Mixpanel/Amplitude integration | Product analytics |
| Export | CSV/Excel/PDF export | User reports |
When Plugins Are Valuable
| Industry | Plugins | Why |
|---|---|---|
| FinTech | Audit Log, Access Control | Compliance-ready (SOX, PCI-DSS) |
| Healthcare | Audit Log, PII Masking | HIPAA-ready tools |
| E-commerce | Analytics, Export | Product insights |
| Enterprise SaaS | All plugins | All enterprise features |
| Internal Tools | Export, Validation | Team productivity |
| Admin Panels | Access Control, Audit | Security + audit |
Comparison with Alternatives
| Feature | TanStack Table | GridKit Enhanced | AG Grid Enterprise |
|---|---|---|---|
| Basic table | ✅ | ✅ | ✅ |
| Event system | ❌ | ✅ | ✅ |
| Performance Monitoring | ❌ | ✅ | ⚠️ Partial |
| Validation | ❌ | ✅ | ✅ |
| Audit Logging | ❌ | ✅ | ✅ |
| Plugin Ecosystem | ❌ | ✅ | ⚠️ Limited |
| Export (CSV/Excel) | ❌ | ✅ | ✅ |
| Real-time Collaboration | ❌ | ✅ | ✅ |
| Offline Support | ❌ | ✅ | ❌ |
| Cost | Free | $ | $2,000+/year |
| Migration | N/A | 5 minutes | Weeks |
| Bundle Size | 6KB | 17KB | 450KB |
When to Choose What
TanStack Table:
- ✅ Simple tables without enterprise needs
- ✅ $0 budget
- ✅ Team already knows TanStack
GridKit Enhanced:
- ✅ Need enterprise features
- ✅ Team knows TanStack
- ✅ Limited budget
- ✅ Fast migration matters
AG Grid Enterprise:
- ✅ Maximum features out of box
- ✅ Budget not a concern
- ✅ Ready for long migration
- ✅ Need vendor support
Conclusion
GridKit Enhanced is not about speeding up TanStack Table.
It's about saving development time.
Key Takeaways
- Enterprise features in 2-3 days, not 3-4 weeks
Audit logs, event tracking, performance monitoring, validation, plugins — all take weeks to build. GridKit adds them in a few lines of code.
- ~5-15ms overhead is an acceptable trade-off
For enterprise apps, this is negligible compared to:
- Network latency (50-500ms)
- Database queries (10-100ms)
- User perception threshold (100ms)
- Zero breaking changes
Your TanStack code continues working. GridKit is an adapter wrapper, not a replacement.
- Plugin Ecosystem is a unique advantage
Only table with full plugin architecture. Isolated plugins, auto dependencies, lifecycle management.
When to Choose GridKit
✅ Yes:
- Enterprise apps needing compliance-ready tools
- Teams valuing developer productivity
- Tables with < 50,000 rows
- Projects with deadlines
❌ No:
- Trading platforms (need every millisecond)
- 100,000+ rows with frequent updates
- Maximum raw performance is critical
- Need ready-made certification (GDPR/HIPAA/SOX)
Try It Yourself
6 interactive examples. 30 seconds to try. No installation needed.
What's Next
For developers:
- Install:
npm install @gridkit/tanstack-adapter - Try: Quick Start
- Learn: Event System or Plugins
For teams:
Questions? GitHub Issues — we respond within 24 hours.
GridKit Enhanced — TanStack Table with enterprise features.
Faster than building yourself. Cheaper than AG Grid. Honest about trade-offs.
Originally published at gridkit.dev
Found a bug or inaccuracy? Open an issue

Top comments (0)