xiaohongshu
xiaohongshu
expo-workflow
Expo SDK 54+ workflows, EAS Build/Update, Expo Router v6, native tabs. Use for Expo development or OTA update strategies.
Full skill instructions
Comprehensive expertise in Expo SDK 54+ development workflows, EAS (Expo Application Services), and optimization strategies for rapid mobile development. Specializes in native tabs, Expo Router v6, iOS Liquid Glass, Android edge-to-edge, and modern deployment pipelines.
What's New in SDK 54
Breaking Changes from SDK 53
expo-av deprecated → use expo-video and expo-audioManaged vs Bare Workflow
Expo Go vs Development Builds
Expo SDK & Modules
npx expo install <package>Build Profiles
Platform-Specific Configuration
Build Optimization
Over-The-Air Updates
Update Workflows
Update Best Practices
app.json / app.config.js
eas.json
Dynamic Configuration
Fast Refresh & Hot Reloading
Debugging Tools
Local Development
App Store Submission
Internal Distribution
CI/CD Integration
Ask me when you need help with:
# Create new Expo project
npx create-expo-app@latest MyApp
# Navigate to project
cd MyApp
# Start development server
npx expo start
# Install Expo module
npx expo install expo-camera
# Check project health
npx expo-doctor
# Start with cache cleared
npx expo start -c
# Start with specific mode
npx expo start --dev-client # Development build
npx expo start --go # Expo Go
# Run on specific platform
npx expo run:ios
npx expo run:android
# Prebuild native projects (bare workflow)
npx expo prebuild
# Login to EAS
eas login
# Configure EAS
eas build:configure
# Build for all platforms
eas build --platform all
# Build development version
eas build --profile development --platform ios
# Build for production
eas build --profile production --platform all
# Check build status
eas build:list
# Configure EAS Update
eas update:configure
# Publish update to default channel
eas update --branch production --message "Fix critical bug"
# Publish to specific channel
eas update --channel preview --message "QA testing"
# List published updates
eas update:list
# Rollback update
eas update:rollback
# Submit to App Store
eas submit --platform ios
# Submit to Play Store
eas submit --platform android
# Submit specific build
eas submit --platform ios --id <build-id>
Create a reusable development build once, then use EAS Update for daily changes:
// eas.json
{
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"ios": {
"simulator": true
}
}
}
}
Build once:
eas build --profile development --platform all
Update JavaScript daily:
eas update --branch development --message "Daily changes"
Use app.config.js for dynamic configuration:
// app.config.js
export default ({ config }) => {
const isProduction = process.env.APP_ENV === 'production';
return {
...config,
name: isProduction ? 'MyApp' : 'MyApp Dev',
slug: 'myapp',
extra: {
apiUrl: isProduction
? 'https://api.myapp.com'
: 'https://dev-api.myapp.com',
analyticsKey: process.env.ANALYTICS_KEY,
},
updates: {
url: 'https://u.expo.dev/your-project-id'
}
};
};
Let EAS manage credentials automatically:
// eas.json
{
"build": {
"production": {
"ios": {
"credentialsSource": "remote"
},
"android": {
"credentialsSource": "remote"
}
}
}
}
Speed up builds by caching dependencies:
// eas.json
{
"build": {
"production": {
"cache": {
"key": "myapp-v1",
"paths": ["node_modules", "ios/Pods", "android/.gradle"]
}
}
}
}
Safely deploy updates to production:
# Start with 10% rollout
eas update --branch production --message "New feature" --rollout-percentage 10
# Monitor metrics, then increase
eas update:configure-rollout --branch production --percentage 50
# Full rollout
eas update:configure-rollout --branch production --percentage 100
For Expo Go (quick testing):
# Start dev server
npx expo start
# Scan QR code with:
# - iOS: Camera app
# - Android: Expo Go app
For dev client (full features):
# Install dev client once
eas build --profile development --platform ios
# Daily JavaScript updates via EAS Update
eas update --branch development
"Unable to resolve module"
# Clear Metro cache
npx expo start -c
# Reinstall dependencies
rm -rf node_modules && npm install
"Build failed on EAS"
# Check build logs
eas build:list
eas build:view <build-id>
# Run prebuild locally to catch issues early
npx expo prebuild
"Update not appearing in app"
# Check update channel matches app's channel
eas channel:list
# Verify update was published successfully
eas update:list --branch production
# Force reload in app (shake device → reload)
When you need a native module not in Expo SDK:
# Install the module
npm install react-native-awesome-module
# Prebuild to generate native projects
npx expo prebuild
# Rebuild dev client with new module
eas build --profile development --platform all
# Continue using EAS Update for JS changes
eas update --branch development
Enable true native tab bars with Expo Router v6:
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
import { Platform } from 'react-native';
export default function TabLayout() {
return (
<Tabs
screenOptions={{
// Enable native tabs (iOS has translucent effect by default)
tabBarStyle: Platform.select({
ios: { position: 'absolute' }, // For Liquid Glass
default: {},
}),
}}
>
<Tabs.Screen
name="index"
options={{ title: 'Home', tabBarIcon: ({ color }) => <HomeIcon color={color} /> }}
/>
<Tabs.Screen
name="profile"
options={{ title: 'Profile', tabBarIcon: ({ color }) => <ProfileIcon color={color} /> }}
/>
</Tabs>
);
}
Create beautiful translucent effects:
// components/GlassCard.tsx
import { View, StyleSheet, Platform } from 'react-native';
import { BlurView } from 'expo-blur';
export function GlassCard({ children }) {
if (Platform.OS === 'ios' && parseInt(Platform.Version, 10) >= 26) {
return (
<BlurView
style={styles.card}
intensity={60}
tint="systemMaterial" // Liquid Glass tint
>
{children}
</BlurView>
);
}
return <View style={[styles.card, styles.fallback]}>{children}</View>;
}
const styles = StyleSheet.create({
card: {
borderRadius: 16,
overflow: 'hidden',
},
fallback: {
backgroundColor: 'rgba(255, 255, 255, 0.8)',
},
});
Handle immersive display properly:
// app/_layout.tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { View, StyleSheet, Platform } from 'react-native';
export default function RootLayout() {
const insets = useSafeAreaInsets();
return (
<View
style={[
styles.container,
{
// Account for edge-to-edge on Android 15+
paddingTop: insets.top,
paddingBottom: insets.bottom,
},
]}
>
<Slot />
</View>
);
}
// app.json - enable edge-to-edge
{
"expo": {
"android": {
"edgeToEdge": true // SDK 54 default
}
}
}
Modern video playback:
// components/VideoPlayer.tsx
import { useVideoPlayer, VideoView } from 'expo-video';
import { useEvent } from 'expo';
import { StyleSheet, View } from 'react-native';
export function VideoPlayer({ source }: { source: string }) {
const player = useVideoPlayer(source, (player) => {
player.loop = true;
player.play();
});
useEvent(player, 'statusChange', ({ status }) => {
console.log('Player status:', status);
});
return (
<View style={styles.container}>
<VideoView
style={styles.video}
player={player}
allowsFullscreen
allowsPictureInPicture
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
video: { width: '100%', aspectRatio: 16 / 9 },
});
Modern audio handling:
// hooks/useAudio.ts
import { useAudioPlayer, useAudioPlayerStatus } from 'expo-audio';
export function useAudio(source: string) {
const player = useAudioPlayer(source);
const status = useAudioPlayerStatus(player);
return {
play: () => player.play(),
pause: () => player.pause(),
seek: (position: number) => player.seekTo(position),
isPlaying: status.playing,
position: status.currentTime,
duration: status.duration,
};
}
Imperative image loading:
import { useImage, Image } from 'expo-image';
export function PreloadedImage({ uri }: { uri: string }) {
const image = useImage(uri, {
onError: (error) => console.error('Failed to load image:', error),
});
if (!image) {
return <ActivityIndicator />;
}
return (
<Image
source={image}
style={{ width: image.width, height: image.height }}
contentFit="cover"
/>
);
}
Increment Planning
spec.mdplan.mdtasks.mdTesting Strategy
Living Documentation
.specweave/docs/internal/operations/Cost Optimization
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience