TerraUI v0.1.0

Getting started

Install @terratcg/ui, mount ThemeProvider and OverlayHost once at the root, and press your first Button.

Install

npm install @terratcg/ui react-native-screens

TerraUI runs on plain React Native for iOS and Android, with or without Expo. Its peers are React, React Native and react-native-screens; only the overlay layer (Dialogs, Menus and toasts) uses Screens. The supported versions are on Compatibility.

Set up

Mount one ThemeProvider and one OverlayHost at the root of your app:

import { Button, ButtonText, OverlayHost, ThemeProvider, defaultDark, defaultLight, showDialog } from "@terratcg/ui";
import { useColorScheme } from "react-native";

export function App() {
  const dark = useColorScheme() === "dark";
  return (
    <ThemeProvider theme={dark ? defaultDark : defaultLight}>
      <Button onPress={() => showDialog({ title: "Saved", body: "Your changes are saved.", confirm: "OK", tone: "info" })}>
        <ButtonText>Save</ButtonText>
      </Button>
      <OverlayHost failureText="Something went wrong. Try again." />
    </ThemeProvider>
  );
}
  • ThemeProvider gives every component its theme, and your feedback handler if you have one. Without a provider, components fall back to defaultLight. See ThemeProvider and feedback.
  • OverlayHost draws the Dialogs, Menus and toasts that showDialog, showMenu and showToast open from anywhere. Put it after your navigator, inside ThemeProvider. See OverlayHost.

To match your brand, start from the default theme and override a few tokens with createTheme: see Theming.

React Native rules

TerraUI is React Native for iOS and Android, not web React. Follow these rules before writing code with it:

  • Versions: react ~19.3.0, react-native ~0.88.0 and react-native-screens ~4.30.0. Expo is optional.
  • Style props, not className: style through each component's props and React Native's style prop. There is no CSS and no class name.
  • onPress, not onClick: every pressable control takes onPress.
  • Text inside text components: put every string inside a text component, such as ButtonText, Text, RowTitle or NoticeTitle. A bare string inside a Button or a View does not render.
  • One ThemeProvider, one OverlayHost: mount each once, at the root of the app, with OverlayHost inside ThemeProvider and after your navigator. Dialogs, menus and toasts open through them, from anywhere.
  • Native first: import from @terratcg/ui, never a web component library. Haptics, sounds, icons and navigation stay in your app.

Imports

Import everything from the root, or one family from its subpath:

import { Button, ButtonText } from "@terratcg/ui";
import { Switch } from "@terratcg/ui/switch";

Both resolve to the same modules. Anything not listed in the package's exports is internal and may change in any release.

Docs for coding agents

The package carries these docs as Markdown, in the version you installed, at node_modules/@terratcg/ui/docs/. index.md there opens with the rules above and lists every page.

AGENTS.md

Paste this section into your project's AGENTS.md (or CLAUDE.md), so coding agents read the installed docs and the rules before writing TerraUI code:

## TerraUI

This project uses TerraUI (`@terratcg/ui`). Its docs, for the version installed here, are Markdown files in `node_modules/@terratcg/ui/docs/`. Read `index.md` there first, then the page of every component you use, and trust them over what you remember.

TerraUI is React Native for iOS and Android, not web React. Follow these rules before writing code with it:

- **Versions:** `react ~19.3.0`, `react-native ~0.88.0` and `react-native-screens ~4.30.0`. Expo is optional.
- **Style props, not `className`:** style through each component's props and React Native's `style` prop. There is no CSS and no class name.
- **`onPress`, not `onClick`:** every pressable control takes `onPress`.
- **Text inside text components:** put every string inside a text component, such as `ButtonText`, `Text`, `RowTitle` or `NoticeTitle`. A bare string inside a `Button` or a `View` does not render.
- **One `ThemeProvider`, one `OverlayHost`:** mount each once, at the root of the app, with `OverlayHost` inside `ThemeProvider` and after your navigator. Dialogs, menus and toasts open through them, from anywhere.
- **Native first:** import from `@terratcg/ui`, never a web component library. Haptics, sounds, icons and navigation stay in your app.

On the site

Every page is also Markdown: append .md to its URL, such as /docs/button.md. llms.txt lists every page and opens with the rules above; llms-full.txt holds every page in full. Each page's actions copy its Markdown or open it in ChatGPT, Claude or Cursor.

On this page