Introduction
A powerful, flexible DataTable component built with TanStack Table and Shadcn UI.
What is Niko Table?
Section titled “What is Niko Table?”Nobody’s table, everyone’s solution.
Just like Shadcn, Niko Table is not a component library. Instead, it’s a comprehensive DataTable component that you copy into your project and customize to your needs. It’s built with TanStack Table and Shadcn UI, providing enterprise-grade features while remaining fully under your control.
Why Use This DataTable?
Section titled “Why Use This DataTable?”🚀 Production-Ready
Section titled “🚀 Production-Ready”Built for real-world applications with features like:
- Sorting (single and multi-column)
- Filtering (global search and column filters)
- Pagination (client and server-side)
- Row selection and bulk actions
- Column visibility and reordering
- Virtual scrolling for large datasets
- Export to CSV/Excel
🎯 Progressive Complexity
Section titled “🎯 Progressive Complexity”Start simple and add features as you need them:
- Simple Table - Just render data (< 5 minutes)
- Basic Table - Add pagination and sorting (+ 5 minutes)
- Search Table - Add global search (+ 5 minutes)
- Filter Table - Add column filters (+ 10 minutes)
- Advanced Table - Add virtualization, sidebars, etc. (+ 15 minutes)
🛠️ Fully Customizable
Section titled “🛠️ Fully Customizable”Since you own the code, you can:
- Modify any component
- Add custom features
- Change styling
- Integrate with your backend
- No version lock-in
♿ Accessible by Default
Section titled “♿ Accessible by Default”- WCAG 2.1 compliant
- Full keyboard navigation
- Screen reader support
- Semantic HTML
- ARIA labels and roles
📱 Mobile-Friendly
Section titled “📱 Mobile-Friendly”- Responsive design
- Touch-friendly controls
- Mobile-optimized filters
- Collapsible sidebars
How It Works
Section titled “How It Works”The DataTable uses a two-layer architecture for maximum flexibility:
Components (data-table-*.tsx in /components folder) - Context-aware wrapper components that use useDataTable() hook to automatically get the table from DataTableRoot context. These eliminate prop drilling and are the recommended way to use components:
DataTableSearchFilter,DataTableFilterMenu,DataTableSortMenu,DataTablePagination, etc.
Filters (table-*.tsx in /filters folder) - Core implementation components that accept a table prop directly and use TanStack Table hooks (like table.getState(), table.setGlobalFilter(), etc.). These can be used standalone:
TableSearchFilter,TableFilterMenu,TableSortMenu, etc.
Why this architecture?
- Use
DataTable*components from ”@/components/niko-table/components” when you want context-based, zero-config usage - Use
Table*components from filters when you want to build custom components or manage the table instance yourself - All filter components use TanStack Table hooks directly, giving you full control
// Recommended: Use context-based Action components<DataTableRoot data={data} columns={columns}> <DataTableSearchFilter /> {/* Automatically gets table from context */} <DataTable> <DataTableHeader /> <DataTableBody /> </DataTable> <DataTablePagination /></DataTableRoot>
// Advanced: Use Filter components directlyconst table = useReactTable({ data, columns, ... })<TableSearchFilter table={table} /> {/* Pass table prop directly */}Build tables by composing components - start simple and add features as needed:
<DataTableRoot data={data} columns={columns}> <DataTableToolbarSection> <DataTableSearchFilter /> <DataTableFilterMenu /> </DataTableToolbarSection>
<DataTable> <DataTableHeader /> <DataTableBody /> </DataTable>
<DataTablePagination /></DataTableRoot>What’s Included
Section titled “What’s Included”This DataTable provides you with:
- TanStack Table integration - Built on the powerful headless table library
- Composable components - Build complex UIs from simple, reusable pieces
- State management - Context-based state sharing with hook-based flexibility
- Performance optimization - Virtual scrolling, memoization, and efficient rendering
- Accessibility - WCAG 2.1 compliant with full keyboard navigation and screen reader support
- TypeScript - Fully typed with comprehensive type definitions
Philosophy
Section titled “Philosophy”This project follows the Shadcn philosophy:
Copy, Don’t Install
Section titled “Copy, Don’t Install”You copy the DataTable component code into your project (not install it as a package). However, you still need to install the required dependencies:
Required Dependencies:
@tanstack/react-table- Core table library- Shadcn UI components (via
npx shadcn@latest add ...) - UI primitives - Optional:
@tanstack/react-virtual,nuqs,@dnd-kit/*for advanced features
What You Copy:
- All DataTable component files from
/components/niko-table/ - Full source code that you can read, modify, and customize
Benefits:
- ✅ No black box - See exactly how everything works
- ✅ Full control - Modify any component to fit your needs
- ✅ Easy to customize - Change styling, behavior, or add features
- ✅ No version lock-in - You control when to update
- ✅ Learn by reading - Understand the implementation
Composition Over Configuration
Section titled “Composition Over Configuration”Build complex tables by composing simple components:
// Start simple<DataTableRoot data={data} columns={columns}> <DataTable> <DataTableHeader /> <DataTableBody /> </DataTable></DataTableRoot>
// Add features incrementally<DataTableRoot data={data} columns={columns} config={{ enablePagination: true }}> <DataTableToolbarSection> <DataTableSearchFilter /> </DataTableToolbarSection>
<DataTable> <DataTableHeader /> <DataTableBody /> </DataTable>
<DataTablePagination /></DataTableRoot>
// Go advanced<DataTableRoot data={data} columns={columns} config={{ enablePagination: true, enableFilters: true, enableRowSelection: true, }}> <DataTableToolbarSection className="justify-between"> <div className="flex gap-2"> <DataTableSearchFilter /> <DataTableFilterMenu /> </div> <div className="flex gap-2"> <DataTableViewMenu /> <DataTableSortMenu /> </div> </DataTableToolbarSection>
<DataTable> <DataTableHeader /> <DataTableBody> <DataTableSkeleton /> <DataTableEmptyBody /> </DataTableBody> </DataTable>
<DataTablePagination /></DataTableRoot>Type-Safe by Default
Section titled “Type-Safe by Default”Full TypeScript support throughout:
type User = { id: string name: string email: string}
const columns: DataTableColumnDef<User>[] = [ { accessorKey: "name", // ✅ Type-safe header: "Name", cell: ({ row }) => row.original.email, // ✅ Autocomplete },]Comparison
Section titled “Comparison”vs Component Libraries
Section titled “vs Component Libraries”| Feature | This DataTable | Component Libraries |
|---|---|---|
| Customization | ✅ Full control | ❌ Limited |
| Bundle size | ✅ Copy what you need | ❌ Entire library |
| Learning curve | ✅ See the source | ❌ Read docs |
| Dependencies | ✅ Standard deps only | ❌ Library-specific |
| Updates | ✅ Copy new features | ❌ Breaking changes |
vs Building from Scratch
Section titled “vs Building from Scratch”| Feature | This DataTable | From Scratch |
|---|---|---|
| Time to implement | ✅ Minutes | ❌ Days/weeks |
| Accessibility | ✅ Built-in | ❌ Must implement |
| Mobile support | ✅ Ready | ❌ Must build |
| Advanced features | ✅ Available | ❌ Complex to build |
| Best practices | ✅ Included | ❌ Must learn |
Next Steps
Section titled “Next Steps”Ready to get started?
- Installation - Set up your project
- Simple Table - Your first table
- Basic Table - Add common features
- Search Table - Add search
- Faceted Filter Table - Advanced filtering
- Advanced Table - Master level
Community
Section titled “Community”Questions? Ideas? Contributions?
- GitHub Repository - Star us!
- Contributing Guide - How to contribute
- Feature Requests - Request features
- Component Requests - Request components
Credits
Section titled “Credits”Built on top of:
- TanStack Table by Tanner Linsley - The headless table library that powers everything
- Shadcn UI by Shadcn - Beautiful, accessible component primitives
- sadmann7’s work - Major inspiration for filter components and table patterns:
- TableCN - Inspired our filter menu, inline filter, faceted filter, and slider filter implementations
- DiceUI Sortable - Drag and drop sortable for row reordering
- nuqs by François Best - Type-safe search params state manager for URL state management
- Web Dev Simplified Registry by Kyle Cook - Registry implementation pattern
License
Section titled “License”MIT License - use it freely in your projects!