---
title: "Flutter"
description: "Add Tanrei to a Flutter app."
url: "https://tanrei.chnotchy.com/getting-started/flutter/"
last_updated: 2026-10-20T01:38:40.000Z
---

# Flutter

> Add Tanrei to a Flutter app.

The `tanrei` package is pure Dart. It provides widgets, an inherited `TanreiTheme` and generated token constants, and it does not depend on `MaterialApp` or `CupertinoApp`; it works inside either, or in a plain `WidgetsApp`.

> [!WARNING]
> **Not published yet**
>
> `tanrei` is not on pub.dev yet. A platform is published once it has caught up with the current specs, and Flutter’s CI is paused until then. “From source” below shows how the package is added from [chnotchy/tanrei](https://github.com/chnotchy/tanrei); “Once it is published” shows how installing will work then.

## Install

### From source

> [!WARNING]
> **Does not build today**
>
> The Flutter package has not caught up with the current specs and tokens: its sources were written against an earlier version of the generated token code and do not compile against today’s. Its CI is paused until it catches up, and the [status page](https://tanrei.chnotchy.com/status/) marks its components _lagging_. The steps below are how it is added to an app; they work once the package has caught up.

Clone the repository next to your app and depend on the package by its path:

```sh
flutter pub add "tanrei:{path: ../tanrei/packages/flutter}"
```

`flutter pub add "tanrei:{git: {url: https://github.com/chnotchy/tanrei, path: packages/flutter}}"` follows the repository instead of a local clone.

### Once it is published

```sh
flutter pub add tanrei
```

## Use

```dart
import 'package:flutter/widgets.dart';
import 'package:tanrei/tanrei.dart';

class DeployButton extends StatelessWidget {
  const DeployButton({super.key, required this.isDeploying, required this.onDeploy});

  final bool isDeploying;
  final VoidCallback onDeploy;

  @override
  Widget build(BuildContext context) {
    return TanreiTheme(
      data: TanreiThemeData.platform(context),
      child: TanreiButton(
        variant: TanreiButtonVariant.filled,
        onPressed: isDeploying ? null : onDeploy,
        child: const Text('Deploy'),
      ),
    );
  }
}
```

There is no `disabled` flag. As with Flutter’s own buttons, passing `null` for `onPressed` disables the button.

## Theme and contrast

`TanreiThemeData.platform(context)` reads brightness and the high-contrast flag from `MediaQuery`. To fix them, start from a constant and copy:

```dart
TanreiTheme(
  data: TanreiThemeData.dark.copyWith(contrast: TanreiContrast.high),
  child: const App(),
)
```

Put `TanreiTheme` above your navigator so that every route sees it.

## Text styles

`TanreiTheme.of(context).system.typescale` holds the sixteen text styles by level — `heading2` for a section title, `body` for running text, `label` for a control — as `TanreiTextStyle` tokens; `theme.textStyle(system.typescale.heading2)` (or `token.toTextStyle()`) turns one into a Flutter `TextStyle`. `theme.textStyle(token, emphasized: true)` — by hand, `token.emphasized(system.typescale.emphasis)` — is the same style at its weight plus the family’s emphasis step (`typescale.emphasis`); emphasis is a weight, not another role. See [Typography](https://tanrei.chnotchy.com/foundations/typography/) for the roles and the element mapping.
