The @tanstack/angular-table adapter is a wrapper around the core table logic. Most of it's job is related to managing state using angular signals, providing types and the rendering implementation of cell/header/footer templates.
@tanstack/angular-table re-exports all of @tanstack/table-core's APIs and the following:
Creates and returns an Angular-reactive table instance.
injectTable accepts either:
The initializer is intentionally re-evaluated whenever any signal read inside it changes. This is how the adapter keeps the table in sync with Angular's reactivity model.
Because of that behavior, keep expensive/static values (for example columns, feature setup, row models) as stable references outside the initializer, and only read reactive state (data(), pagination/filter/sorting signals, etc.) inside it.
Since ColumnDef is stricter about generics, prefer building columns with createColumnHelper<TFeatures, TData>() so feature and row types are inferred consistently.
The returned table is also signal-reactive: table state and table APIs are wired for Angular signals, so you can safely consume table methods inside computed(...) and effect(...).
import { computed, effect, signal } from '@angular/core'
import {
createColumnHelper,
injectTable,
type ColumnDef,
rowPaginationFeature,
stockFeatures
} from '@tanstack/angular-table'
// Register all table core features
const _features = tableFeatures(stockFeatures);
// ...or register only your needed features
const _features = tableFeatures({
rowPaginationFeature,
// ...all other features
})
const columnHelper = createColumnHelper<typeof _features, Person>()
export class AppComponent {
readonly data = signal<Person[]>([])
// If you type columns manually, include both generics:
// readonly columns: ColumnDef<typeof _features, Person>[] = [...]
readonly columns = columnHelper.columns([
columnHelper.accessor('firstName', {
header: 'First name',
cell: info => info.getValue(),
}),
// ...
])
// This function is re-run when any signal read inside changes.
readonly table = injectTable(() => ({
_features: _features,
// Reactive state can be read directly
data: this.data(),
state: {
// ...
},
// Keep stable references outside the initializer
columns: this.columns,
}))
constructor() {
effect(() => {
console.log('Visible rows:', this.table.getRowModel().rows.length)
})
}
}
createTableHook is the Angular composition API for building reusable table infrastructure.
Use it when multiple tables should share the same defaults (features, row models, default options, and component registries) while keeping strong types across the app.
At runtime, createTableHook wraps injectTable and returns typed helpers such as:
For full setup and patterns, see the Table Composition Guide.
An Angular structural rendering primitive for cell/header/footer content.
It supports the same content kinds as Angular rendering:
Column render functions (header, cell, footer) run in Angular injection context, so you can use inject() and signals directly in render logic.
For complete rendering details (*flexRender, shorthand directives, flexRenderComponent, TemplateRef, component inputs/outputs, and injectFlexRenderContext), see the Rendering components Guide.
@tanstack/angular-table also exports Angular DI helpers and directives for table/cell/header context:
These APIs provide signal-based context values and are available from nearest directives or from *flexRender-rendered components when matching props are present.