Feature Guides

Aggregation (React) Guide

Examples

Aggregation is independent from column grouping. Register rowAggregationFeature whenever columns calculate totals or aggregated values. Add columnGroupingFeature separately only when the table also groups rows.

For the complete behavior and type reference, see the core Aggregation Guide.

Aggregation Setup

Register only the built-in functions referenced by name. Passing a definition directly to a column does not require a registry entry.

tsx
import {
  rowAggregationFeature,
  aggregationFn_count,
  aggregationFn_extent,
  aggregationFn_mean,
  aggregationFn_sum,
  tableFeatures,
  useTable,
} from '@tanstack/react-table'

const features = tableFeatures({
  rowAggregationFeature,
  aggregationFns: {
    count: aggregationFn_count,
    extent: aggregationFn_extent,
    mean: aggregationFn_mean,
    sum: aggregationFn_sum,
  },
})

const table = useTable({
  features,
  columns,
  data,
})

The aggregation feature does not require a grouped row model. This makes grand totals and custom row-subset totals available in otherwise ordinary tables.

Column Aggregations

A column accepts one aggregation or an array. A single entry returns a scalar; multiple entries return an object keyed by the aggregation name or descriptor id.

tsx
columnHelper.accessor('amount', {
  aggregationFn: 'sum',
})

columnHelper.accessor('score', {
  aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }],
})

String values remain backward-compatible. Use descriptors when a result needs a stable custom key or options.

Grand Totals and Row Subsets

Call column.getAggregationValue() without arguments to aggregate the default pre-grouped row model. Filtering is included; grouping, sorting, expansion, and pagination do not change that default total.

tsx
footer: ({ column }) => column.getAggregationValue<number>().toLocaleString()

Pass one options object with rows from any row model to choose a different set:

tsx
column.getAggregationValue({ rows: table.getCoreRowModel().rows })
column.getAggregationValue({ rows: table.getRowModel().rows })
column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows })
column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) })
column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 })

Depth is relative to the supplied row array. 0 selects those roots, 1 selects their direct sub-rows, and Infinity selects terminal rows. Configure maxAggregationDepth on the column for cached default calls, or pass maxDepth in the options object as an explicit override. table.getMaxSubRowDepth() returns the deepest structural depth in the core row model. Column option getAggregationValue(context) can provide an external or server-computed value; return undefined to fall back to the configured aggregation function.

Grouped Aggregation

Grouped aggregation composes two independent features. Register both, add the grouped row-model slot, and configure aggregation functions on the columns that should produce grouped values.

tsx
const features = tableFeatures({
  rowAggregationFeature,
  columnGroupingFeature,
  groupedRowModel: createGroupedRowModel(),
  aggregationFns: { sum: aggregationFn_sum },
})

columnHelper.accessor('visits', {
  aggregationFn: 'sum',
  aggregatedCell: ({ getValue }) => getValue<number>().toLocaleString(),
  footer: ({ column }) => column.getAggregationValue<number>().toLocaleString(),
})

Use cell.getIsAggregated() to identify a grouped aggregate cell. Footer rendering uses the adapter's normal footer renderer.

Custom Aggregation Definitions

Use constructAggregationFn({ aggregate, merge? }) for custom definitions. The aggregate context includes depth-selected rows, maxDepth, getValue, column, and table. Every aggregation configured on a column receives the same row frontier. Grouped calls also include groupingRow and immediate subRows for custom structural behavior. A merge implementation can more efficiently combine already-computed sub-row results.

See Custom Aggregation Definitions for the full contract, return typing, caching behavior, and worker limitations.