Preface¶
When building Expo / React Native interfaces with AI coding tools like Cursor or Claude Code, a common issue is that while the functionality works, the UI feels like a “thin Web wrapper” — colors hardcoded as hex values, shadows still using the old shadow* / elevation props, safe areas guessed arbitrarily, and animations thrown together with the basic Animated library. The models already know plenty of component names, but what they lack is a set of native UI conventions aligned with the current Expo SDK.
Expo official has packaged these conventions into Agent Skills. The expo-native-ui skill specifically handles “what the screen should look like”: semantic colors, native controls, SF Symbols, animations, blur and gradient effects, local storage, and responsive layout. Navigation-related needs like routing, Tabs, and Modals are handled by the expo-router skill in the same repository. The official documentation’s typical prompt is: “Build a settings screen with native-feeling controls”, and the agent will automatically match the expo-native-ui skill.
This article is organized based on the SKILL.md (version 1.1.1, MIT) of expo-native-ui from the official Expo repository expo/skills and the installation instructions from docs.expo.dev/skills. It explains what this skill is, where to install it, and what to note when asking AI to build interfaces according to this specification.
What It Is¶
expo-native-ui is an open-source Framework skill maintained by the Expo team, and is one of the free SDK skills in the expo/skills plugin suite. It is not an npm UI library, but a structured specification for AI Agents to read (SKILL.md + references/ folder), which tells agents how to build screens with a stronger native feel in Expo projects.
The official description can be summarized as: follow the Apple Human Interface Guidelines for styling; build Expo interfaces that feel close to system apps using semantic colors, native controls, SF Symbols, media, animations, visual effects, gradients, storage, and responsive layouts. Navigation-related requirements should use the expo-router skill instead.
The skill directory also includes several reference documents for on-demand consultation:
references/
animations.md Reanimated: enter/exit, layout, scroll-driven, gestures
controls.md Native controls: Switch, Slider, SegmentedControl, DateTimePicker, Picker
gradients.md CSS gradients (experimental_backgroundImage, requires New Architecture)
icons.md Use SF Symbols via expo-image's sf: source
media.md Camera, audio, video, and file saving
storage.md SQLite, AsyncStorage, SecureStore
visual-effects.md Blur (expo-blur) and liquid glass (expo-glass-effect)
webgpu-three.md WebGPU / Three.js 3D and GPU visualization
Core Conventions and Highlights¶
The points below are directly written in the official SKILL.md, and are the biggest differences between this skill and “letting AI write RN code casually”.
1. Use Expo Go first, then consider custom builds¶
The skill marks this as CRITICAL: most Expo apps do not need custom native code. The workflow is to first run npx expo start, scan the code with Expo Go for verification; only when you need local Expo Modules, Apple Targets (such as widgets / App Clips), third-party native modules not included in Expo Go, or native configuration that cannot be expressed in app.json, should you run npx expo run:ios/android or eas build.
This prevents the AI from jumping straight to local native builds and slowing down iteration.
2. Library and API preferences (avoid outdated practices)¶
The skill clearly requires the agent to follow a set of “use this, not that” rules:
- Do not use modules removed from React Native (such as legacy Picker, WebView, SafeAreaView, built-in AsyncStorage, etc.)
- Do not use the deprecated expo-permissions
- Use expo-audio / expo-video for audio and video, instead of expo-av
- Use expo-image with source="sf:name" for SF Symbols, instead of expo-symbols or @expo/vector-icons as a workaround
- Use react-native-safe-area-context for safe areas, instead of React Native’s built-in SafeAreaView
- Prioritize process.env.EXPO_OS for platform detection, instead of Platform.OS
- Use the Color API from expo-router for semantic colors, instead of writing PlatformColor by hand
- For SDK 56+, do not import directly from @react-navigation/*, instead use expo-router/react-navigation
For styling: follow Apple HIG; prioritize flex gap; use { borderCurve: 'continuous' } for rounded corners; use CSS-style boxShadow for shadows, instead of the old shadow / elevation props; CSS / Tailwind is not supported (if you need Tailwind, use the separate expo-tailwind-setup skill).
3. Semantic colors: a palette that automatically adapts to system light/dark mode¶
The official example centralizes colors in theme/colors.ts, wrapping Platform.select with Color (from expo-router), and providing a default hex fallback for Web:
// theme/colors.ts
import { Platform } from "react-native";
import { Color } from "expo-router";
export const colors = {
label: Platform.select({
ios: Color.ios.label,
android: Color.android.dynamic.onSurface,
default: "#000000",
})!,
secondaryLabel: Platform.select({
ios: Color.ios.secondaryLabel,
android: Color.android.dynamic.onSurfaceVariant,
default: "#3c3c43",
})!,
systemBackground: Platform.select({
ios: Color.ios.systemBackground,
android: Color.android.dynamic.surface,
default: "#ffffff",
})!,
systemBlue: Platform.select({
ios: Color.ios.systemBlue,
android: Color.android.dynamic.primary,
default: "#007aff",
})!,
};
You can directly reference colors.label or colors.systemBackground in your pages. Note: do not pass Color / PlatformColor into Reanimated styles; use static colors in animations (this is also noted in references/animations.md).
4. Use Reanimated as the default animation library¶
references/animations.md requires using Reanimated v4, avoiding React Native’s built-in Animated library. For enter/exit animations, use FadeIn / FadeOut, and for layout changes, use LinearTransition:
import Animated, {
FadeIn,
FadeOut,
LinearTransition,
} from "react-native-reanimated";
function App() {
return (
<Animated.View
entering={FadeIn}
exiting={FadeOut}
layout={LinearTransition}
/>
);
}
The same document also covers scroll-driven animations, gesture dragging, keyboard height synchronization, staggered list entry animations, and recommends keeping interactive animations under 300ms, and prioritizing transform properties over changing width/height.
5. Native controls and haptics¶
references/controls.md favors system controls: Switch, SegmentedControl, Slider, DateTimePicker, Picker, etc. The Switch and DateTimePicker components come with built-in haptics, and the skill reminds you not to add redundant vibration feedback. Segmented controls should have a maximum of about 4 items, keep the text short, avoid changing colors unnecessarily, so that dark mode can follow the system’s settings automatically.
Installation and Activation¶
expo-native-ui is distributed as part of the full Expo Skills suite. The installation method varies by AI tool (consistent with the official README and docs.expo.dev/skills).
Claude Code¶
Install the Expo plugin from the official plugin marketplace:
claude plugin install expo@claude-plugins-official
Alternatively, run this command in Claude Code:
/plugin install expo@claude-plugins-official
Codex¶
codex plugin add expo@openai-curated
Or open /plugins in Codex and install expo from the OpenAI-curated marketplace.
Cursor and Other Agents¶
If you have not installed it yet, use the skills CLI in your project root directory:
# npm
npx skills add expo/skills
# yarn
yarn dlx skills add expo/skills
# pnpm
pnpm dlx skills add expo/skills
# bun
bunx skills add expo/skills
The repository README also provides an equivalent command to install all Expo Skills at once, with an optional flag to specify a single skill:
npx skills@latest add expo/skills --skill '*'
To install only the skill covered in this article, replace --skill with expo-native-ui (the CLI may still ask which Agent to install it to). After installation, restart or refresh the Agent session so it can rediscover the SKILL.md file.
For Cursor: Open Settings → Rules, Skills, Subagents, confirm that Include third-party Plugins, Skills, and other configs is enabled, and you will see Expo Skills in the skills list. The official note: Cursor’s Skills will not appear in the / slash menu, but will be automatically matched by the agent when you submit Expo-related requests.
Update (for skills CLI installations):
npx skills@latest update
Or update a single skill, for example:
npx skills@latest update expo-router
For Claude Code / Codex, use their respective marketplace update mechanisms to install plugins.
Typical Usage¶
After installation, you do not need to manually “call” a command; just describe your interface requirements in natural language. The official documentation’s sample prompt is:
Build a settings screen with native-feeling controls
The README also has a more comprehensive full-screen build description:
Build a native-feeling Expo Router screen with tabs, modals, and animations.
The latter will usually trigger both the expo-router (navigation structure) and expo-native-ui (styling, controls, animations) skills. You can be more specific in actual collaboration, for example:
Build a settings page with Expo Router: grouped switches, segmented controls, date pickers;
Use expo-router's Color semantic colors; use the system Switch for toggles;
Use Reanimated FadeIn for list item entry animations; validate first in Expo Go, do not use custom native builds right away.
When the agent works according to the skill, it will typically: prioritize Expo Go; use semantic colors and boxShadow; select native components for controls; use Reanimated for animations; use kebab-case for filenames (such as comment-card.tsx); use the navigation stack title for page headers, instead of manually writing a large title in the page.
Applicable Scenarios and Notes¶
Best for:
- Building system-style interfaces like settings pages, list pages, detail pages in Expo projects with AI
- Ensuring output consistently follows HIG, semantic colors, safe areas, Reanimated and other conventions, reducing outdated API usage
- Already using or planning to use expo-router, and need to separate “navigation” and “visual/interaction” work into different skills
Things to note:
- It teaches Agents how to write Expo UI, not a replacement for Expo documentation / Expo CLI / EAS CLI; source code and commands still follow the official documentation
- It is different from expo-ui: the latter targets @expo/ui (the SwiftUI / Jetpack Compose suite); expo-native-ui focuses more on React Native components + Expo SDK’s native观感 conventions
- CSS / Tailwind is outside the scope of this skill; use expo-tailwind-setup when you need Tailwind v4 / NativeWind v5
- The experimental_backgroundImage mentioned in the gradient references relies on the New Architecture; do not forcefully copy the code if your project architecture does not match
- If you find the skill content outdated or misleading, the official provides a feedback command (needs to be specific and actionable):
npx --yes submit-expo-feedback@latest --category skills --subject "expo-native-ui" "<actionable feedback>"
Summary¶
expo-native-ui turns “how to write Expo screens that feel more native” into a skill that can be automatically loaded by Agents like Cursor, Claude Code, or Codex: semantic colors, native controls, Reanimated, safe area and shadow conventions, and the workflow of “Expo Go first, then custom builds” are all written in the official SKILL.md and references/ folder. After installing the Expo Skills suite, a simple request like “build a settings page with a native feel” will often automatically match this specification.
Official links:
- Skill directory: https://github.com/expo/skills/tree/main/plugins/expo/skills/expo-native-ui
- Full repository: https://github.com/expo/skills
- Installation and skill list: https://docs.expo.dev/skills