Why We Built Another Data Grid (and What It Took to Ship It)
If you've ever had to pick a data grid library for a React or Vue app, you know the landscape: a handful of free options that fall apart past a few thousand rows, and a handful of powerful options that come with enterprise pricing and licensing conversations before you've even seen the docs. That gap is why we built EliteGrid - a TypeScript data grid library with dedicated adapters for React, Vue, and vanilla JS, now live on npm. This post is a technical walkthrough of how it's built, not just a feature list.
The core problem: re-renders
Most grid performance problems don't come from rendering rows - they come from rendering every row when only one changed. A single edit shouldn't trigger a re-render across the whole table.
EliteGrid's React adapter is built on useSyncExternalStore with row-level derived selectors. Each row subscribes only to the slice of state it actually depends on, so an edit or update stays scoped to that row instead of cascading across the whole grid. Combined with a WeakMap-based reverse index for O(1) row-ID lookups, this is what makes virtual scrolling stay smooth even at 10,000+ rows.
Vue support: the Proxy problem
Porting the same architecture to Vue surfaced a subtler issue: Vue's reactivity system wraps objects in Proxies, and if you're not careful, passing those proxied objects back into a framework-agnostic core can create reactivity loops - the core mutates a proxy, Vue detects the change, re-triggers the core, and so on.
The fix was disciplined use of toRaw() at the adapter boundary - unwrapping proxies before they touch the core engine, and re-wrapping only where Vue's reactivity actually needs to observe. It's a small detail, but it's the difference between "works in the demo" and "works under real usage patterns."
Vanilla JS: no framework, no problem
The vanilla adapter isn't an afterthought - it's the framework-agnostic core that both React and Vue adapters are built on top of. If you're not using React or Vue, or you're integrating into a legacy app, you get the same virtualization and plugin system without any framework dependency at all.
A plugin system, not a monolith
Instead of shipping every feature by default, EliteGrid keeps the core small and treats selection, CSV export, and accessibility announcements as plugins. This keeps bundle size down for teams that don't need every feature, and makes it easier to reason about what's actually running.
Try it without installing anything
We built an interactive playground with a live Monaco editor and real preview, so you can test the actual behavior before adding a dependency to your project:
๐ elitegrid.dev/playground
Four scenarios are ready to run:
- Virtual Scroll (10K rows) - see the smooth-scroll performance for yourself
- Real API - live data fetching into the grid
- Inline Edit - validated cell editing
- CSV Export - multi-scope export (selected rows, filtered rows, or full dataset)
Getting started
npm install @elitegrid/react
# or
npm install @elitegrid/vue
# or
npm install @elitegrid/core
Full docs: elitegrid.dev
What's next
This is a v1 launch, and we're actively working through feedback. If you hit friction with any existing grid library - performance, API ergonomics, licensing, or anything else - I'd love to hear about it in the comments. That's exactly the kind of input that shapes what we build next.
Comments
No comments yet. Start the discussion.