@angular/material and @taiga-ui/core are both comprehensive UI component libraries built specifically for Angular applications, providing pre-built, accessible, and themeable components that follow design system guidelines. @angular/material implements Google's Material Design specification with a wide range of components like buttons, cards, dialogs, and data tables, tightly integrated with Angular's CDK for advanced interactions. @taiga-ui/core, developed by Tinkoff, offers a modern, highly customizable set of components following its own design language, with strong TypeScript support, extensive theming capabilities, and a focus on developer experience through features like contextual styling and composable APIs.
Both @angular/material and @taiga-ui/core deliver production-ready UI components for Angular apps, but they differ significantly in philosophy, API design, and integration depth. Let’s compare how they handle real-world engineering challenges.
@angular/material follows Google’s Material Design spec closely. Components look and behave like standard Material elements, which ensures consistency but limits visual deviation.
// @angular/material: Theming via pre-defined palettes
import { defineLightTheme } from '@angular/material';
const theme = defineLightTheme({
color: {
primary: '#6750A4',
secondary: '#625B71'
}
});
@taiga-ui/core uses a token-based theming system that allows granular control over every design aspect without CSS overrides.
// @taiga-ui/core: Contextual theming with tokens
import { TUI_THEME } from '@taiga-ui/core';
@Component({
template: `<button tuiButton>Click</button>`,
providers: [
{
provide: TUI_THEME,
useValue: {
button: { background: 'var(--custom-bg)' }
}
}
]
})
export class MyComponent {}
@angular/material uses attribute directives and content projection extensively. Complex components often require multiple nested elements.
<!-- @angular/material: Dialog setup -->
<mat-dialog-content>
<p>Your message here</p>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button mat-dialog-close>Cancel</button>
<button mat-button [mat-dialog-close]="true">OK</button>
</mat-dialog-actions>
@taiga-ui/core favors composable, single-element components with intuitive inputs. Many components work as standalone directives.
<!-- @taiga-ui/core: Dialog as a service with minimal template -->
<button
tuiDialog
[content]="'Your message here'"
[size]="'m'">
Open dialog
</button>
@angular/material provides solid TypeScript support, but some APIs rely on string-based configuration or loosely typed options.
// @angular/material: Table column definition
const columns = ['id', 'name', 'progress']; // string array
// Sorting direction as string
sort.direction = 'asc'; // type: SortDirection ('asc' | 'desc' | '')
@taiga-ui/core leverages TypeScript generics and discriminated unions for stricter typing, reducing runtime errors.
// @taiga-ui/core: Strictly typed dropdown items
const items: readonly TuiContext<TuiDataListHost, string>[] = [
{ content: 'Option 1', value: 'opt1' },
{ content: 'Option 2', value: 'opt2' }
];
// Button appearance is a union type
appearance: TuiAppearance = 'primary'; // 'primary' | 'secondary' | ...
@angular/material is deeply integrated with Angular CDK, offering utilities like DragDropModule, ScrollingModule, and OverlayModule out of the box.
// @angular/material: Using CDK drag-drop
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
onDrop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.items, event.previousIndex, event.currentIndex);
}
@taiga-ui/core includes its own set of utilities (e.g., TuiScrollbar, TuiPortal) but doesn’t depend on CDK. It provides equivalent functionality with a different API surface.
// @taiga-ui/core: Portal usage
import { TuiPortalService } from '@taiga-ui/core';
constructor(private readonly portal: TuiPortalService) {}
openInPortal(content: TemplateRef<unknown>) {
this.portal.add(content);
}
Both libraries prioritize accessibility (a11y) and support internationalization, but their approaches differ.
@angular/material uses ARIA attributes automatically and supports i18n via MAT_DATE_LOCALE and similar tokens.
// @angular/material: Datepicker locale
providers: [{ provide: MAT_DATE_LOCALE, useValue: 'fr-FR' }]
@taiga-ui/core handles i18n through injectable dictionaries and provides a unified TUI_LANGUAGE token for all components.
// @taiga-ui/core: Global language setup
import { TUI_ENGLISH_LANGUAGE } from '@taiga-ui/i18n';
providers: [
{
provide: TUI_LANGUAGE,
useValue: TUI_ENGLISH_LANGUAGE
}
]
@angular/material components can be tested using standard Angular testing utilities, but some interactions (like overlays) require TestBed configuration.
// @angular/material: Testing a dialog
const fixture = TestBed.createComponent(MyComponent);
const overlayContainer = TestBed.inject(OverlayContainer);
// Interact with overlayContainer.nativeElement
@taiga-ui/core components are designed to be easily testable with minimal setup, often not requiring special test harnesses.
// @taiga-ui/core: Simple component test
const fixture = TestBed.createComponent(MyComponent);
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('button')).toBeTruthy();
Many teams adopt these libraries incrementally. Both can coexist in the same app, but mixing design systems may confuse users.
@angular/material works best when adopted project-wide due to its opinionated styling.
@taiga-ui/core supports gradual adoption through scoped theming and component-level customization.
| Aspect | @angular/material | @taiga-ui/core |
|---|---|---|
| Design System | Google Material Design | Custom, flexible design language |
| Theming | Predefined palettes, CSS custom properties | Token-based, contextual, programmatic |
| API Style | Directive-heavy, content projection | Composable, input-driven, minimal markup |
| TypeScript | Good, some string-based configs | Excellent, strict generics and unions |
| CDK Dependency | Yes (tight integration) | No (self-contained utilities) |
| Learning Curve | Moderate (familiar to Material users) | Steeper (new patterns and concepts) |
Stick with @angular/material if you’re building an app that should feel like other Google products, need CDK features immediately, or have designers who work within Material constraints.
Opt for @taiga-ui/core if you require pixel-perfect control over UI, want to avoid CSS overrides, or are building a branded enterprise application where Material Design feels too restrictive.
Both libraries are actively maintained and production-ready — your choice ultimately hinges on design flexibility versus ecosystem alignment.
Choose @angular/material if your project requires strict adherence to Material Design guidelines, benefits from deep integration with Angular CDK utilities (like drag-and-drop or virtual scrolling), or needs a large ecosystem of well-documented, battle-tested components backed by the Angular team. It’s ideal for teams already invested in the Material ecosystem or building applications where design consistency with Google's standards is a priority.
Choose @taiga-ui/core if you need a more flexible, modern component library with superior TypeScript ergonomics, fine-grained customization options, and features like contextual styling and composable directives. It’s particularly well-suited for enterprise applications requiring complex forms, advanced theming, or a design system that doesn’t conform to Material Design, especially when developed by teams comfortable with Tinkoff’s architectural patterns.
The sources for this package are in the main Angular Material repo. Please file issues and pull requests against that repo.
License: MIT