Guide

Installation

How to install and set up Docyrus UI native components in your Expo project.

Preview App Install

Preview Docyrus UI Native on your device

Scan with Expo Go

Download Expo Go, then scan the QR code to preview native components.

Scan the QR code to open the Expo install page. This installs the latest internal development build on a provisioned device.

Prerequisites

Docyrus UI native components require an Expo project with React Native. Make sure your environment meets these requirements:

DependencyMinimum Version
React19
React Native0.86
Expo SDK57
Node.js18

Install the CLI

Install the Docyrus CLI globally or use it via npx:

npm install -g @docyrus/cli

Add native components

Install native components using the rn- prefix:

# Install a native component
npx @docyrus/cli add rn-button

# Install multiple native components
npx @docyrus/cli add rn-button rn-input rn-card

# Install all native components
npx @docyrus/cli add --all-rn

Components are installed to your components/docyrus-native/ directory.

Install peer dependencies

Native components require Tailwind CSS v4 for React Native via Uniwind, plus common React Native libraries:

# Tailwind CSS v4 for React Native (required)
npx expo install uniwind tailwindcss

# Common peer dependencies
npx expo install react-native-svg
npx expo install react-native-reanimated react-native-worklets
npx expo install react-native-gesture-handler react-native-safe-area-context

Docyrus-connected components and every rn-hooks-* hook also need @tanstack/react-query (a required peer). Other native modules — expo-file-system, expo-sharing, expo-print, expo-clipboard, expo-image-picker, react-native-maps, react-native-webview, expo-speech-recognition, … — are optional peers: components load them lazily and degrade gracefully when they are missing. The CLI writes the peers a component needs into your peerDependencies; install them with npx expo install <name>.

Component styling also uses these packages (installed automatically by the CLI):

npm install tailwind-variants clsx tailwind-merge

Set up Uniwind

Docyrus Native components use className prop for styling via Uniwind — a build-time Tailwind CSS v4 integration for React Native.

1. Configure Metro

Add the Uniwind Metro plugin to your metro.config.js:

metro.config.js
const { getDefaultConfig } = require('expo/metro-config');
const { withUniwindConfig } = require('uniwind/metro');

const config = getDefaultConfig(__dirname);

module.exports = withUniwindConfig(config, {
  cssEntryFile: './src/styles/global.css',
  // Docyrus components are designed on a 14px rem (text-sm, text-base, …)
  polyfills: { rem: 14 }
});

2. Create global CSS

Create a src/styles/global.css file with Tailwind, Uniwind and the Docyrus design tokens:

src/styles/global.css
@import "tailwindcss";
@import "uniwind";
@import "./docyrus-native/index.css";

The last line is required. Every native component is styled with semantic tokens (bg-background, text-muted-foreground, border-field-border, bg-success-soft, …) that are only defined by this file — without it components render transparent and unstyled. The CLI installs it with the first native component (the @docyrus/rn-styles item every rn-* component depends on) at src/styles/docyrus-native/index.css (styles/docyrus-native/ in the project root when there is no src/). It defines spacing, radius, font and light/dark color tokens; Uniwind follows the device appearance automatically. See Theming for the token list, overrides and the optional color schemes.

Import the tokens with a path relative to your CSS entry — adjust ./docyrus-native/index.css if your global.css lives elsewhere. In a pnpm/yarn workspace that depends on @docyrus/ui-native directly, @import "@docyrus/ui-native/styles"; also resolves. The optional color-schemes.css must always be imported by relative path: Uniwind reads theme variants from relatively imported files before it registers them, and a package import of that file fails with Cannot use @variant with unknown variant.

The tokens set --font-sans to Inter (Inter_400Regular, Inter_500Medium, …). Load those fonts with @expo-google-fonts/inter (useFonts), or override --font-sans* in an @theme block after the import.

3. Import in your app entry

Import the global CSS at the top of your root layout:

app/_layout.tsx
import '../styles/global.css';

import { DocyThemeProvider } from '@/lib/docyrus/theme';

export default function RootLayout() {
  return (
    <DocyThemeProvider>
      {/* Your app content */}
    </DocyThemeProvider>
  );
}

Set up the theme

Wrap your app with DocyThemeProvider at the root level. See the Theming guide for full configuration options.

app/_layout.tsx
import { DocyThemeProvider } from '@/lib/docyrus/theme';

export default function RootLayout() {
  return (
    <DocyThemeProvider defaultMode="system" defaultColorScheme="docyrus">
      {/* Your app content */}
    </DocyThemeProvider>
  );
}

Form components like Input, Textarea, and Modal work best with react-native-keyboard-controller. It prevents inputs from being hidden behind the keyboard and provides smooth animated transitions.

npx expo install react-native-keyboard-controller

Wrap your app with KeyboardProvider at the root level:

app/_layout.tsx
import '../styles/global.css';

import { KeyboardProvider } from 'react-native-keyboard-controller';

import { DocyThemeProvider } from '@/lib/docyrus/theme';

export default function RootLayout() {
  return (
    <KeyboardProvider>
      <DocyThemeProvider>
        {/* Your app content */}
      </DocyThemeProvider>
    </KeyboardProvider>
  );
}

Once the provider is active, all screens — including modals with KeyboardAvoidingView — automatically benefit from improved keyboard behavior.

Set up the Docyrus data layer

Skip this section if you only use presentational components. Docyrus-connected components (data grid, form view, calendar, kanban, composers, …) and the native hooks need a few providers near the root:

app/_layout.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import Storage from 'expo-sqlite/kv-store';

import { DocyStorageProvider, type DocyKeyValueStore } from '@/lib/docyrus/storage';
import { UiTranslationProvider } from '@/hooks/docyrus-native/use-ui-translation';
import { DocyrusTenantProvider } from '@/hooks/docyrus-native/use-docyrus-tenant';

const queryClient = new QueryClient();

// Synchronous key-value backend for view-parameter persistence, saved views, recents, …
const store: DocyKeyValueStore = {
  getItem: key => Storage.getItemSync(key),
  setItem: (key, value) => Storage.setItemSync(key, value),
  removeItem: key => Storage.removeItemSync(key)
};

export function DocyrusProviders({ client, authReady, t, children }) {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <QueryClientProvider client={queryClient}>
        <DocyStorageProvider store={store}>
          <UiTranslationProvider t={t}>
            <DocyrusTenantProvider client={client} enabled={authReady}>
              {children}
            </DocyrusTenantProvider>
          </UiTranslationProvider>
        </DocyStorageProvider>
      </QueryClientProvider>
    </GestureHandlerRootView>
  );
}
  • QueryClientProvider — required by every use-docyrus-* hook.
  • DocyrusTenantProvider — tenant date / number formats for every grid cell, value renderer and calendar (docs).
  • DocyStorageProvider — persistent backend for persistState and the active saved view (docs). Without it state lives in memory for the process lifetime.
  • UiTranslationProvider — optional; without it components render their English fallbacks (docs).
  • GestureHandlerRootView — required by the calendar, notification stack, tree view drag and image editor.
  • Warm the shared inventory cache after sign-in with useDocyrusInventoryLoader.

The Docyrus hooks require @docyrus/app-utils >= 0.20.0, which ships a React Native build (react-native export condition). No Metro config is needed for it.

Some optional peers need a development build (they are not in Expo Go): react-native-enriched-html (email composer rich body) and expo-speech-recognition (add its config plugin to app.config.ts). react-native-maps works in Expo Go, but an Android development build needs a Google Maps API key (android.config.googleMaps.apiKey).

Import and use

Once installed, import native components and use them in your screens. All components accept a className prop for Tailwind-based styling:

app/index.tsx
import { View } from 'react-native';

import { Button } from '@/components/docyrus-native/button';

export default function Home() {
  return (
    <View className="flex-1 justify-center p-4">
      <Button variant="default" onPress={() => console.log('pressed')}>
        Click me
      </Button>
    </View>
  );
}

Components are installed as source code — you can freely modify, extend, or restyle them to fit your needs.

On this page