eoria

Installation

Add the runtime, configure Unistyles and Reanimated, and copy your first component.

Five minutes on an existing Expo project. New projects can start from npx create-expo-app@latest with the default template.

  1. Run init.

    Terminal window
    npx @eoria/cli init

    It writes eoria.json and src/unistyles.ts, adds import '@/unistyles' as the first line of your root layout, writes a Babel config with the Unistyles and Worklets plugins, adds the @/* alias, and installs @eoria/core and the peers with expo install. Each file it would overwrite is skipped and reported. The CLI page lists exactly what it touches.

  2. Check the theme import.

    src/unistyles.ts registers the themes and has to run before any component renders. init imports it at the top of app/_layout.tsx, App.tsx or index.js, whichever it finds. If your entry file lives somewhere else, add the import yourself and keep it first.

    src/unistyles.ts
    import { configureUnistyles, defaultThemes, type EoriaTheme } from '@eoria/core'
    declare module 'react-native-unistyles' {
    export interface UnistylesThemes {
    light: EoriaTheme
    dark: EoriaTheme
    }
    }
    configureUnistyles({ themes: defaultThemes })

    configureUnistyles wraps StyleSheet.configure and turns on adaptive themes, so the app follows the OS appearance until you say otherwise. See Theming for presets and manual switching.

  3. Add your first components.

            npx @eoria/cli add button portal toast
          
            npx shadcn@latest add https://eoria.adamtrip.pt/r/button.json
          

    Dependencies resolve transitively. Adding button also copies text; adding select copies popper, portal and text.

  4. Mount the portal host and toaster.

    Overlays render through a portal so they sit above navigation. Put the host last in your root layout.

    src/app/_layout.tsx
    import '@/unistyles'
    import { Stack } from 'expo-router'
    import { PortalHost } from '@/components/ui/portal'
    import { Toaster } from '@/components/ui/toast'
    export default function RootLayout() {
    return (
    <>
    <Stack />
    <PortalHost />
    <Toaster />
    </>
    )
    }
  5. Rebuild the native app.

    Terminal window
    npx expo prebuild
    npx expo run:ios

    Expo Go will not work. If the app throws `Unistyles: One of your stylesheets is trying to

    get the theme, but no theme has been selected yet`, the themes file is not imported before the first component renders. Check step 2.

Peer versions

The only hard requirement is the New Architecture. These are the versions the example app and the previews run on:

Package Version
react-native 0.86
react-native-unistyles 3.3
react-native-reanimated 4.5
react-native-worklets 0.10
react-native-nitro-modules 0.37

These are what the example app pins. Older Unistyles 3 releases should work; Unistyles 2 will not, because the recipe engine uses useVariants and the babel plugin’s dependency tracking.

Jest

@eoria/core/jest mocks Unistyles with variant resolution. The official mock strips variants, which makes every variant test pass for the wrong reason.

jest.config.js
module.exports = {
preset: 'jest-expo',
setupFiles: ['@eoria/core/jest'],
}