react-table (v7+) and react-table-6 represent two distinct generations of the same library. react-table is the modern, hook-based, fully headless implementation that gives developers complete control over markup and state. react-table-6 is the legacy, component-based version that provided more default structure but less flexibility. While both solve the problem of displaying tabular data in React, they differ fundamentally in how they integrate with the React lifecycle and how much control they hand over to the developer.
Both react-table and react-table-6 are popular solutions for building complex tables in React applications, but they belong to different eras of React development. react-table (v7+) embraces the modern hooks ecosystem, while react-table-6 relies on older component patterns. Understanding these differences is critical for architectural decisions, especially regarding long-term maintainability and flexibility.
react-table is built entirely around React hooks.
useTable (and other plugin hooks) to get table state and helper functions.<table>, <thead>, etc.).// react-table (v7): Hook-based API
import { useTable } from 'react-table';
function Table({ columns, data }) {
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({ columns, data });
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => (
<td {...cell.getCellProps()}>
{cell.render('Cell')}
</td>
))}
</tr>
);
})}
</tbody>
</table>
);
}
react-table-6 uses a monolithic component approach.
<ReactTable /> component.<div> based by default).// react-table-6: Component-based API
import ReactTable from 'react-table-6';
function Table({ columns, data }) {
return (
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
className="-striped -highlight"
/>
);
}
react-table forces you to build the markup.
<table>, a grid of <div>s, or a virtualized list.// react-table: You control the semantic tags
return (
<table {...getTableProps()}>
<thead>...</thead>
<tbody>...</tbody>
</table>
);
react-table-6 provides a default DOM structure.
<div>s instead of semantic <table> tags by default.// react-table-6: Library controls the tags
// Renders internal div structure like:
// <div class="rt-table">
// <div class="rt-thead">...</div>
// <div class="rt-tbody">...</div>
// </div>
react-table splits features into separate hooks.
useSortBy, usePagination).// react-table: Composable hooks
import { useTable, useSortBy, usePagination } from 'react-table';
const {
state: { sortBy },
setSortBy,
// ... pagination props
} = useTable(
{ columns, data },
useSortBy,
usePagination
);
react-table-6 bundles features into the main component.
sortable, pagination).// react-table-6: Built-in props
<ReactTable
data={data}
columns={columns}
sortable={true}
pagination={true}
onSortedChange={newSort => { /* handle sort */ }}
/>
react-table is designed to be fully controlled.
// react-table: Controlled state
const [state, setState] = React.useState({
pageIndex: 0,
pageSize: 10,
});
const {
state: { pageIndex },
gotoPage,
} = useTable({
columns,
data,
state,
onPageChange: page => setState({ ...state, pageIndex: page })
});
react-table-6 manages state internally by default.
page and onPageChange, but it's less consistent.// react-table-6: Internal state default
<ReactTable
data={data}
page={pageIndex}
onPageChange={page => setPageIndex(page)}
// Internal state handles the rest unless overridden
/>
react-table (v7) is the stable predecessor to the TanStack ecosystem.
@tanstack/react-table (v8).react-table-6 is deprecated and archived.
| Feature | react-table (v7) | react-table-6 |
|---|---|---|
| API Style | ⚛️ Hooks (useTable) | 🧩 Component (<ReactTable />) |
| Markup | 🔨 Fully Headless (You build it) | 📦 Default <div> Structure |
| Features | 🔌 Plugin Hooks (Opt-in) | ⚙️ Built-in Props (Bundled) |
| State | 🎮 Fully Controlled | 🤖 Internal Default |
| Status | ✅ Stable (Legacy to v8) | ⚠️ Deprecated/Archived |
| Learning Curve | 📈 Steeper (More code) | 📉 Lower (Quick setup) |
react-table is the professional choice for modern React development. It treats the table as a collection of logic hooks that you compose into your own UI. This approach aligns with how modern React libraries are built (like Headless UI or Radix). It requires more initial code but pays off in flexibility and maintainability.
react-table-6 is a relic of an earlier React era. While it was revolutionary at the time, its component-heavy API and internal state management make it difficult to integrate with modern patterns like server components or complex state synchronization.
Final Thought: If you are touching react-table-6 today, plan a migration path to react-table (v7) or @tanstack/react-table (v8). The hook-based architecture is not just a trend; it provides the necessary leverage to build complex, accessible, and performant data grids that scale with your application.
Choose react-table (v7) if you are starting a new project or refactoring an existing one, as it uses modern React hooks and offers superior flexibility. It is the direct successor to v6 and is actively maintained (though note the migration to @tanstack/react-table v8 for the absolute latest features). It is ideal when you need full control over HTML semantics, styling, and state management without being locked into a specific DOM structure.
Choose react-table-6 ONLY if you are maintaining a legacy application that already depends on it and migration costs are prohibitive. It is deprecated and should not be used for new development. This package is suitable strictly for bug fixes or minor updates in older codebases where rewriting the table logic to use hooks would introduce too much risk or effort.