Ai expo-native-ui

install
source · Clone the upstream repo
git clone https://github.com/wpank/ai
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/wpank/ai "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/frontend/expo-native-ui" ~/.claude/skills/wpank-ai-expo-native-ui && rm -rf "$T"
manifest: skills/frontend/expo-native-ui/SKILL.md
source content

Expo Native UI

Build production-quality native mobile apps with Expo Router following Apple Human Interface Guidelines and modern React Native patterns.

Installation

OpenClaw / Moltbot / Clawbot

npx clawhub@latest install expo-native-ui

WHAT This Skill Does

Guides implementation of native mobile apps using Expo Router with:

  • File-based routing with native navigation stacks
  • Native tab bars (NativeTabs) and iOS 26 features
  • SF Symbols integration via expo-symbols
  • Blur effects (expo-blur) and liquid glass (expo-glass-effect)
  • Reanimated animations and gesture handling
  • Native controls: Switch, Slider, SegmentedControl, DateTimePicker

WHEN To Use

  • Building a new Expo Router app
  • Adding native tab navigation
  • Implementing iOS-style blur or liquid glass effects
  • Creating smooth animations with entering/exiting transitions
  • Integrating SF Symbols for icons
  • Setting up route structure with groups and dynamic routes

KEYWORDS

expo router, react native, native tabs, sf symbols, expo blur, liquid glass, reanimated, ios, android, mobile app, navigation stack, form sheet, modal, context menu, link preview

References

Consult these resources for detailed implementation:

ReferencePurpose
references/route-structure.md
Route conventions, dynamic routes, groups, query params
references/tabs.md
NativeTabs, migration from JS tabs, iOS 26 features
references/icons.md
SF Symbols with expo-symbols, animations, weights
references/controls.md
Native iOS controls: Switch, Slider, DateTimePicker, Picker
references/visual-effects.md
Blur effects and liquid glass
references/animations.md
Reanimated: entering, exiting, layout, scroll-driven
references/search.md
Search bar integration, useSearch hook, filtering
references/gradients.md
CSS gradients via experimental_backgroundImage
references/media.md
Camera, audio, video, file saving
references/storage.md
SQLite, AsyncStorage, SecureStore
references/webgpu-three.md
WebGPU, Three.js for 3D graphics
references/toolbar-and-headers.md
Stack headers, toolbar customization (iOS)

Core Principles

Running the App

Try Expo Go first before creating custom builds:

npx expo start  # Scan QR with Expo Go

Custom builds (

npx expo run:ios
) only needed for:

  • Local Expo modules (custom native code in
    modules/
    )
  • Apple targets (widgets, app clips via
    @bacons/apple-targets
    )
  • Third-party native modules not in Expo Go

Code Style

  • Kebab-case file names:
    comment-card.tsx
  • Path aliases in tsconfig over relative imports
  • Never co-locate components/utilities in
    app/
    directory
  • Always ensure a route matches "/" (may be in a group)
  • Escape nested backticks carefully in strings

Library Preferences

UseInstead Of
expo-audio
expo-av
expo-video
expo-av
expo-symbols
@expo/vector-icons
react-native-safe-area-context
RN SafeAreaView
process.env.EXPO_OS
Platform.OS
React.use
React.useContext
expo-image
intrinsic
img
element
expo-glass-effect
custom blur views

Responsiveness

// Always wrap root in ScrollView with automatic insets
<ScrollView contentInsetAdjustmentBehavior="automatic">
  {children}
</ScrollView>

// Use useWindowDimensions, not Dimensions.get()
const { width, height } = useWindowDimensions();

// Flexbox over Dimensions API
<View style={{ flex: 1, flexDirection: 'row', gap: 16 }} />

Navigation Patterns

Link with Preview and Context Menu

import { Link } from 'expo-router';

<Link href="/settings">
  <Link.Trigger>
    <Pressable><Card /></Pressable>
  </Link.Trigger>
  <Link.Preview />
  <Link.Menu>
    <Link.MenuAction title="Share" icon="square.and.arrow.up" onPress={handleShare} />
    <Link.MenuAction title="Delete" icon="trash" destructive onPress={handleDelete} />
  </Link.Menu>
</Link>

Form Sheet Modal

// In _layout.tsx
<Stack.Screen
  name="sheet"
  options={{
    presentation: "formSheet",
    sheetGrabberVisible: true,
    sheetAllowedDetents: [0.5, 1.0],
    contentStyle: { backgroundColor: "transparent" }, // Liquid glass on iOS 26+
  }}
/>

Native Tabs Structure

app/
  _layout.tsx — <NativeTabs />
  (index,search)/
    _layout.tsx — <Stack />
    index.tsx
    search.tsx
// app/_layout.tsx
import { NativeTabs, Icon, Label } from "expo-router/unstable-native-tabs";

export default function Layout() {
  return (
    <NativeTabs>
      <NativeTabs.Trigger name="(index)">
        <Icon sf="list.dash" />
        <Label>Items</Label>
      </NativeTabs.Trigger>
      <NativeTabs.Trigger name="(search)" role="search" />
    </NativeTabs>
  );
}

Styling Guidelines

  • Flex gap over margin/padding where possible
  • borderCurve: 'continuous'
    for rounded corners (not capsules)
  • boxShadow
    style prop, never legacy RN shadow/elevation
  • Stack title instead of custom text elements for page headers
  • Inline styles, not
    StyleSheet.create
    unless reusing
  • fontVariant: 'tabular-nums'
    for numeric counters
  • selectable
    prop
    on Text displaying copiable data
// Shadow example
<View style={{ boxShadow: "0 1px 2px rgba(0, 0, 0, 0.05)" }} />

// Continuous border curve
<View style={{ borderRadius: 12, borderCurve: 'continuous' }} />

Behavior Patterns

  • Haptics: Use
    expo-haptics
    conditionally on iOS
  • Search bar: Prefer
    headerSearchBarOptions
    in Stack.Screen
  • Selectable text: Add
    selectable
    prop to important data
  • Format large numbers: 1.4M, 38k instead of 1,400,000
  • Never use intrinsic elements (
    img
    ,
    div
    ) outside DOM components

NEVER Do

  1. NEVER use legacy modules: Picker, WebView, SafeAreaView from react-native, AsyncStorage (old), expo-permissions
  2. NEVER use
    Dimensions.get()
    — always
    useWindowDimensions
  3. NEVER co-locate components in the
    app/
    directory
  4. NEVER use
    Platform.OS
    — use
    process.env.EXPO_OS
  5. NEVER use legacy shadow styles — use CSS
    boxShadow
  6. NEVER start with custom builds — try Expo Go first
  7. NEVER use StyleSheet.create for one-time styles
  8. NEVER use
    @expo/vector-icons
    — use
    expo-symbols