expo/expo · error

The '@expo/ui' package needs to be installed in order to use

Error message

The '@expo/ui' package needs to be installed in order to use this feature.

What it means

expo-router's `@expo/ui` integration (Compose-style components like Icon, DropdownMenu, Box) is optional. `requireExpoUI` throws when `@expo/ui` (or its modifiers) isn't installed/resolvable, since the feature cannot work without it.

Source

Thrown at packages/expo-router/src/optional-libraries/expo-ui.ts:18

type ExpoUI = typeof import('@expo/ui/jetpack-compose');
type ExpoUIModifiers = typeof import('@expo/ui/jetpack-compose/modifiers');

let expoUI: ExpoUI | undefined;
let modifiers: ExpoUIModifiers | undefined;

try {
  const loadedExpoUI: ExpoUI = require('@expo/ui/jetpack-compose');
  const loadedModifiers: ExpoUIModifiers = require('@expo/ui/jetpack-compose/modifiers');
  expoUI = loadedExpoUI;
  modifiers = loadedModifiers;
} catch {}

export function requireExpoUI(
  errorMessage = "The '@expo/ui' package needs to be installed in order to use this feature."
): { expoUI: ExpoUI; modifiers: ExpoUIModifiers } {
  if (!expoUI || !modifiers) {
    throw new Error(errorMessage);
  }
  return { expoUI, modifiers };
}

View on GitHub (pinned to 7da61120be)

Solutions

  1. Install: `npx expo install @expo/ui`
  2. Rebuild the native app / dev client so the new module is linked
  3. If in a monorepo, ensure `@expo/ui` is resolvable from the app package (no nohoist/pruning issue)
  4. Verify imports come from the correct optional-library module and version compatibility between expo-router and @expo/ui

Example fix

// before
const { expoUI: { Icon } } = requireExpoUI(); // throws
// after
// terminal: npx expo install @expo/ui, rebuild, then:
const { expoUI: { Icon } } = requireExpoUI();
Defensive patterns

Strategy: fallback

Validate before calling

let expoUI = null; try { expoUI = require('@expo/ui'); } catch {}
const expoUIAvailable = !!expoUI;

Type guard

function hasExpoUI(): boolean { try { require.resolve('@expo/ui'); return true; } catch { return false; } }

Try / catch

try { const { expoUI, modifiers } = requireExpoUI(); renderComposeUI(expoUI, modifiers); } catch { renderFallbackRNView(); }

Prevention

When it happens

Trigger: Using expo-router APIs/components that render `@expo/ui` elements (Icon, IconButton, DropdownMenu, Box, RNHostView, etc.) without `@expo/ui` installed in the project.

Common situations: Upgrading expo-router to a version whose built-in UI now requires `@expo/ui`; copying sample screens using expo-ui components; dependency missing from a fresh install or monorepo hoisting failure.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of expo/expo@7da61120be (2026-09-09). Data as JSON: /api/errors/5242b9ccc6098532. Report an issue: GitHub.