Need a quick table with pagination, filtering, and row clicks in a React app? You don’t always need a heavyweight data-grid library — a small, focused React DataTable component covers most CRUD-style admin views in a fraction of the code. This post walks through a minimal table component (inspired by the classic jQuery DataTables) and ends with modern alternatives if you outgrow it.
Features
- Configurable column titles.
- Configurable rows per page.
- Built-in filtering (search across all columns).
- Pagination controls.
- On-row-click callback.
- Custom column formatters (render JSX, access nested fields with dot syntax).
Installation
The component was originally distributed via Bit. Note that the Bit ecosystem has changed significantly since publication — the legacy @bit/... registry is no longer the recommended way to consume Bit components. If you’re starting fresh today, see the modern alternatives section below.
For historical reference, the original install steps were:
npm config set @bit:registry https://node.bit.dev
npm i @bit/adeoy.utils.data-table
npm install --save bootstrap reactstrapThen, in your root component, import Bootstrap’s CSS:
import "bootstrap/dist/css/bootstrap.min.css";Usage
Pass two main props:
data— array of objects, one per row.columns— array of column definitions:{ title, data }for plain fields, or{ title, format }for custom JSX renderers. Use dot syntax (user.address.city) to access nested keys.
Example
import React from "react";
import DataTable from "@bit/adeoy.utils.data-table";
import "bootstrap/dist/css/bootstrap.min.css";
const App = () => {
const data = [
{ id: 1, first_name: "Herold", last_name: "Hardwich", email: "[email protected]", gender: "Male" },
{ id: 2, first_name: "Martelle", last_name: "Peddowe", email: "[email protected]", gender: "Female" },
{ id: 3, first_name: "Devan", last_name: "Foulstone", email: "[email protected]", gender: "Female" },
// ...more rows
];
const columns = [
{ title: "#", data: "id" },
{ title: "First name", data: "first_name" },
{ title: "Last Name", format: (row) => <strong>{row.last_name}</strong> },
{ title: "Email", format: (row) => <em>{row.email}</em> },
{ title: "Gender", data: "gender" },
];
const handleRowClick = (row) => console.log(row);
return (
<DataTable
data={data}
columns={columns}
striped
hover
responsive
onClickRow={handleRowClick}
/>
);
};
export default App;When to use a simple DataTable
| Use case | Recommendation |
|---|---|
| Admin CRUD with <1k rows | Simple DataTable like this one |
| Dashboards, sortable client-side data | TanStack Table (headless) |
| Server-side pagination, virtualization, large datasets | TanStack Table + TanStack Virtual, or AG Grid |
| Spreadsheet-like editing, frozen columns, enterprise features | AG Grid Enterprise / Handsontable |
| Material Design look | MUI DataGrid |
Modern alternatives (2026)
If you’re starting a new React project today, consider these maintained, framework-agnostic options:
- TanStack Table — headless, fully typed, works with any UI library. The de-facto standard in modern React.
- MUI X DataGrid — batteries-included, great if you’re already on Material UI.
- AG Grid — enterprise-grade with virtualization, cell editing, server-side row models.
- Ant Design Table — solid choice when using the Ant Design ecosystem.
For most apps, TanStack Table + a thin Tailwind/Bootstrap layer gives you the best balance of flexibility and code size.
Final thoughts
A small DataTable component covers the 80% case for admin UIs. Reach for a heavier library only when you need server-side pagination, virtualization, complex editing, or strict design-system integration. Whichever you pick, keep the column definitions data-driven — that’s the pattern that pays off as your app grows.
Have feedback or questions about this component? Drop a comment below.