Frontend Mode
Give it all your data. It sorts, filters, and paginates in memory. Simple.
Use this when your dataset fits in the browser — a few hundred to a few thousand rows. If you're dealing with 50,000+ rows from a database, you probably want Backend Mode instead.
The basics
const table = DataTable.create({
el: '#my-table',
mode: 'frontend',
data: myData,
columns: [
{ key: 'name', label: 'Name', type: 'string', sortable: true },
{ key: 'age', label: 'Age', type: 'number', sortable: true },
],
})That's a fully working table. Search, pagination, page size — all included by default.
How the data pipeline works
Every time something changes, the data runs through this pipeline:
filter → sort → paginate
Always in that order. A few things to know:
- Changing a filter or search resets to page 1 (you don't want to be on page 5 of a different result set)
- Changing sort does not reset page (you're looking at the same data, just reordered)
- Changing page size resets to page 1
Search modes
You get three options. Pick the one that makes sense for your use case.
Global search (the default)
One search input, searches across all searchable columns at once.
search: {
enabled: true,
mode: 'global',
debounce: 300,
placeholder: 'Search...',
}Column filters
Individual inputs under each column header. Users filter one column at a time.
search: {
mode: 'column',
}Both at the same time
Global search bar on top + per-column filter inputs. For power users who want precise control.
search: {
mode: 'both',
}Debounce
All search inputs are debounced (default 300ms). Nobody wants to fire a filter on every keystroke. You can change the delay with search.debounce.
Updating data on the fly
The table is alive. You can mutate data after creation and it re-renders automatically.
// Nuke everything and start fresh
table.setData(newData)
// Add someone
table.addRow({ name: 'New Person', age: 28 })
// Add someone at a specific position
table.addRow({ name: 'First Person', age: 30 }, 0)
// Fix a typo in the first row
table.updateRow(0, { name: 'Fixed Name' })
// Remove the third row
table.removeRow(2)Every one of these triggers a re-render. You don't need to call .refresh() — it's automatic.
Try it
50 rows with both global search and column filters. Sort the columns, type in the search, change the page size — it all works client-side:
