@morne004/headless-react-data-table
v1.4.1
Published
A lightweight, powerful, and fully headless data table library for React
Downloads
1,330
Maintainers
Readme
Headless React Data Table
A lightweight, powerful, and fully headless data table library for React. Provides all the logic, state management, and functionality you need to build feature-rich data grids, while leaving rendering and styling completely in your hands.
Built with TypeScript and modern React hooks for maximum flexibility and an excellent developer experience.
📦 View on npm • 🐙 GitHub • 🐛 Issues
📚 Documentation
- FEATURES.md - Complete feature catalog with detailed explanations
- EXAMPLES.md - Real-world usage examples and patterns
- USAGE.md - Complete API reference and integration guide
Quick Links
Why Choose This Library?
✅ What You Get
- Complete Table Logic - Sorting, filtering, pagination, column management all handled
- Persistent State - User preferences auto-saved to localStorage
- TypeScript Native - Full type safety and IntelliSense
- Zero Dependencies - Only React peer dependencies
- Small Bundle - ~30KB minified, tree-shakeable
- Production Ready - Performance and reliability focused
🎨 What You Control
- Your UI - Complete control over HTML structure
- Your Styling - Works with Tailwind, Material-UI, styled-components, or any framework
- Your Components - Replace any part with custom React components
🆚 Comparison
| Feature | This Library | TanStack Table | From Scratch | |---------|-------------|----------------|--------------| | Learning Curve | Low | Medium | High | | Bundle Size | Small (~30KB) | Medium (~100KB) | Varies | | Built-in Persistence | ✅ Yes | ❌ No | ❌ No | | Time to Implement | Minutes | Hours | Days |
Installation
npm install @morne004/headless-react-data-tableOr using yarn/pnpm:
yarn add @morne004/headless-react-data-table
pnpm add @morne004/headless-react-data-tablePeer Dependencies:
- React 18.0.0+ or React 19.0.0+
- React-DOM 18.0.0+ or React 19.0.0+
Quick Start
import { DataTable } from '@morne004/headless-react-data-table';
import type { ColumnDef } from '@morne004/headless-react-data-table';
interface User {
id: number;
name: string;
email: string;
status: 'active' | 'inactive';
}
const data: User[] = [
{ id: 1, name: 'John Doe', email: '[email protected]', status: 'active' },
{ id: 2, name: 'Jane Smith', email: '[email protected]', status: 'inactive' },
];
const columns: ColumnDef<User>[] = [
{
id: 'name',
accessorKey: 'name',
header: 'Name',
},
{
id: 'email',
accessorKey: 'email',
header: 'Email',
},
{
id: 'status',
accessorKey: 'status',
header: 'Status',
cell: ({ row }) => (
<span className={row.status === 'active' ? 'text-green-600' : 'text-gray-400'}>
{row.status}
</span>
),
},
];
function App() {
return (
<div className="p-4">
<h1 className="text-2xl font-bold mb-4">Users</h1>
<DataTable data={data} columns={columns} />
</div>
);
}That's it! The table now has:
- ✅ Sorting (click headers)
- ✅ Search (global filter)
- ✅ Pagination
- ✅ Column visibility toggle
- ✅ Persistent state in localStorage
Style it your way:
// Add Tailwind CSS classes
<DataTable data={data} columns={columns} />
// Or use custom components
<DataTable
data={data}
columns={columns}
components={{
Toolbar: MyCustomToolbar,
Pagination: MyCustomPagination,
}}
/>👉 See more examples in EXAMPLES.md
Key Features
Core Functionality
- Sorting - Click headers to sort ascending/descending/unsorted • Learn more →
- Filtering - Global search + advanced multi-column filters with 6 operators • Learn more →
- Pagination - Client-side pagination with customizable page sizes • Learn more →
- Search - Instant search across all columns • Learn more →
UI Features
- Column Visibility - Show/hide columns with persistence • Learn more →
- Column Reordering - Drag-and-drop to reorder • Learn more →
- Column Resizing - Manual width adjustment • Learn more →
- Condensed View - Toggle between normal and compact density • Learn more →
Developer Experience
- TypeScript - Full type safety with generics • Learn more →
- Headless Architecture - Complete UI customization • Learn more →
- State Management - Controlled and uncontrolled modes • Learn more →
- CSV Export - Built-in export utility • Learn more →
- Custom Cell Renderers - Render any React component • Learn more →
- Component Slots - Replace toolbar, pagination, filters, skeleton • Learn more →
👉 View all features with examples →
What's Next?
Learn the Features
Explore all capabilities with detailed explanations:
📖 FEATURES.md - Complete feature catalog
- Core features (sorting, filtering, pagination)
- UI features (column controls, condensed view)
- State management (persistence, controlled mode)
- Customization options
See Real Examples
Copy-paste ready code for common use cases:
💡 EXAMPLES.md - Real-world patterns
- Basic examples (minimal setup, TypeScript)
- Styled examples (Tailwind, Material-UI)
- Server-side integration (REST API, React Query)
- Framework examples (Next.js, Remix)
- Advanced patterns (editable cells, row selection, master-detail)
- Custom cell renderers (currency, dates, badges, actions)
Read the API Docs
Complete reference for all props, hooks, and types:
📚 USAGE.md - API reference and integration guide
- Installation and setup
- Complete API reference
- TypeScript usage
- State management guide
- Performance tips
- Troubleshooting
- Migration guides
Real-World Examples
Server-Side Pagination
const [tableState, setTableState] = useState({
pageIndex: 0,
pageSize: 25,
globalFilter: '',
});
const [users, setUsers] = useState([]);
const [totalCount, setTotalCount] = useState(0);
useEffect(() => {
fetch(`/api/users?page=${tableState.pageIndex}&pageSize=${tableState.pageSize}&search=${tableState.globalFilter}`)
.then(res => res.json())
.then(response => {
setUsers(response.data); // Current page data (e.g., 25 items)
setTotalCount(response.total); // Total count from server (e.g., 1000)
});
}, [tableState]);
<DataTable
data={users}
columns={columns}
state={tableState}
onStateChange={setTableState}
manualPagination={true}
totalRowCount={totalCount}
pageCount={Math.ceil(totalCount / tableState.pageSize)}
/>Important: When using server-side pagination, you must:
- Set
manualPagination={true}to disable client-side pagination - Provide
totalRowCount(total items on server) - Provide
pageCount(total pages =Math.ceil(totalCount / pageSize)) - The
dataprop should contain only the current page's items
React Query Integration
const { data, isLoading } = useQuery(['users'], fetchUsers);
<DataTable
data={data || []}
columns={columns}
isLoading={isLoading}
/>Custom Cell Renderers
const columns: ColumnDef<Product>[] = [
{
id: 'price',
accessorKey: 'price',
header: 'Price',
cell: ({ row }) => new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(row.price),
},
];Community & Support
Get Help
- 💬 GitHub Discussions - Ask questions, share ideas
- 🐛 GitHub Issues - Report bugs, request features
- 📖 Documentation - Complete feature guide
Stay Updated
- 📦 npm Package - Latest version
- 🐙 GitHub Repository - Source code, releases
- 📝 Changelog - What's new
Contributing
Contributions are welcome! Here's how you can help:
Report Issues
Found a bug or have a feature request?
- Check existing issues
- Create a new issue with:
- Clear description
- Steps to reproduce (for bugs)
- Expected vs actual behavior
- Code example if possible
Development Setup
# Clone the repository
git clone https://github.com/Morne004/advnaced-react-table.git
cd advnaced-react-table
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Run tests (if available)
npm testProject Structure
src/
├── lib/ # Library source code
│ ├── components/ # React components (DataTable, etc.)
│ ├── hooks/ # Custom hooks (useDataTable, etc.)
│ ├── types.ts # TypeScript type definitions
│ ├── utils/ # Utility functions (CSV export, etc.)
│ └── index.ts # Main entry point
└── demo/ # Demo application
└── App.tsx # Demo examplesGuidelines
- Write clear, descriptive commit messages
- Follow existing code style
- Add TypeScript types for new features
- Update documentation for API changes
- Test your changes locally before submitting
- Be respectful and constructive in discussions
Pull Request Process
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Commit your changes (
git commit -m 'Add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
Changelog
See GitHub Releases for version history and release notes.
Recent Updates
- v1.0.4 - Added condensed view as first-class feature
- v1.0.3 - Fixed column resize stuck bug (stale closure issue)
- v1.0.2 - Fixed controlled mode state loss bug
- v1.0.1 - Added missing
exportToCsvexport, removed demo types - v1.0.0 - Initial release
License
MIT © Morne004
This library is free and open-source. You can use it in personal and commercial projects without restriction.
See LICENSE file for details.
Acknowledgments
Built with:
- React - UI library
- TypeScript - Type safety
- Vite - Build tool
Inspired by:
- TanStack Table - Headless UI patterns
- Headless UI - Component design philosophy
Star History
If you find this library useful, please consider giving it a star on GitHub! ⭐
Made with ❤️ by Morne004
