Imagine building a fully functional mobile app that runs on both iOS and Android, with AI suggesting every line of code as you type. Welcome to the modern mobile development workflow: React Native + Expo + GitHub Copilot. This powerful combination can 10x your productivity and make mobile development feel like magic.
Why This Stack?
Before diving in, let's understand why this combination is revolutionary:
The Power Trio
- React Native: Write once, run everywhere (iOS & Android)
- Expo: Zero native code setup, instant testing on your phone
- GitHub Copilot: AI pair programmer that writes code with you
Setting Up Your Development Environment
Step 1: Install Prerequisites
# Install Node.js (if not already installed)
# Download from https://nodejs.org or use a package manager
# Verify installation
node --version # Should be 18.x or higher
npm --version
# Install Expo CLI globally
npm install -g expo-cli
# Verify Expo installation
expo --version
Step 2: Install VS Code Extensions
Install these essential VS Code extensions:
- GitHub Copilot - AI code completion
- GitHub Copilot Chat - Conversational AI assistant
- React Native Tools - Debugging and IntelliSense
- ES7+ React/Redux/React-Native snippets - Code snippets
- Prettier - Code formatter
- ESLint - Code linting
Step 3: Create Your First Expo App
# Create a new Expo app
npx create-expo-app HealthTracker --template blank
# Navigate to project
cd HealthTracker
# Start the development server
npx expo start
Testing on Your Phone
Download the Expo Go app from App Store or Google Play. Scan the QR code from your terminal to instantly see your app running on your phone!
Leveraging GitHub Copilot: Real-World Examples
Now comes the magic. Let's build a health tracking app and see how Copilot accelerates development.
Example 1: Building a Home Screen
Start by creating a new file: screens/HomeScreen.js
Type this comment and watch Copilot complete it:
// Create a HomeScreen component with a gradient background,
// welcome text, and cards for steps, water intake, and calories
import React from 'react';
import { View, Text, StyleSheet, ScrollView } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
export default function HomeScreen() {
return (
Welcome Back!
Let's track your health today
{/* Health Cards */}
{/* Steps Card */}
π
8,234
Steps
{/* Water Card */}
π§
6/8
Glasses
{/* Calories Card */}
π₯
1,850
Calories
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollView: {
flex: 1,
padding: 20,
},
welcomeText: {
fontSize: 32,
fontWeight: 'bold',
color: 'white',
marginTop: 60,
},
subtitle: {
fontSize: 18,
color: 'rgba(255,255,255,0.8)',
marginTop: 8,
marginBottom: 30,
},
cardsContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
},
card: {
width: '48%',
backgroundColor: 'rgba(255,255,255,0.15)',
borderRadius: 16,
padding: 20,
marginBottom: 16,
alignItems: 'center',
},
cardIcon: {
fontSize: 40,
marginBottom: 12,
},
cardValue: {
fontSize: 28,
fontWeight: 'bold',
color: 'white',
},
cardLabel: {
fontSize: 14,
color: 'rgba(255,255,255,0.8)',
marginTop: 4,
},
});
Copilot Magic Moment
Notice how Copilot suggested the entire component structure, styles, and even the emoji icons just from the comment! Press Tab to accept suggestions.
Example 2: Creating a Custom Hook with Copilot
Let's create a custom hook for managing health data. Type the function signature and let Copilot fill in the implementation:
import { useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
// Custom hook to manage health tracking data with AsyncStorage persistence
export function useHealthData() {
const [steps, setSteps] = useState(0);
const [water, setWater] = useState(0);
const [calories, setCalories] = useState(0);
const [loading, setLoading] = useState(true);
// Load data from AsyncStorage on mount
useEffect(() => {
loadHealthData();
}, []);
// Save data to AsyncStorage whenever it changes
useEffect(() => {
saveHealthData();
}, [steps, water, calories]);
const loadHealthData = async () => {
try {
const savedData = await AsyncStorage.getItem('healthData');
if (savedData) {
const { steps, water, calories } = JSON.parse(savedData);
setSteps(steps || 0);
setWater(water || 0);
setCalories(calories || 0);
}
} catch (error) {
console.error('Error loading health data:', error);
} finally {
setLoading(false);
}
};
const saveHealthData = async () => {
try {
const data = { steps, water, calories };
await AsyncStorage.setItem('healthData', JSON.stringify(data));
} catch (error) {
console.error('Error saving health data:', error);
}
};
const addSteps = (amount) => {
setSteps(prev => prev + amount);
};
const addWater = () => {
setWater(prev => Math.min(prev + 1, 8));
};
const addCalories = (amount) => {
setCalories(prev => prev + amount);
};
const resetDaily = () => {
setSteps(0);
setWater(0);
setCalories(0);
};
return {
steps,
water,
calories,
loading,
addSteps,
addWater,
addCalories,
resetDaily,
};
}
Install AsyncStorage:
npx expo install @react-native-async-storage/async-storage
Example 3: Building an Interactive Component
Let's create a water intake tracker with animations. Start typing and let Copilot suggest the complete implementation:
import React, { useRef, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Animated } from 'react-native';
export default function WaterTracker({ currentGlasses, maxGlasses, onAddGlass }) {
const scaleAnim = useRef(new Animated.Value(1)).current;
const handlePress = () => {
// Animate button press
Animated.sequence([
Animated.timing(scaleAnim, {
toValue: 1.2,
duration: 100,
useNativeDriver: true,
}),
Animated.timing(scaleAnim, {
toValue: 1,
duration: 100,
useNativeDriver: true,
}),
]).start();
onAddGlass();
};
const fillPercentage = (currentGlasses / maxGlasses) * 100;
return (
Daily Water Intake
{/* Water Glass Visualization */}
{currentGlasses} / {maxGlasses}
{/* Add Button */}
= maxGlasses && styles.addButtonDisabled
]}
onPress={handlePress}
disabled={currentGlasses >= maxGlasses}
>
{currentGlasses >= maxGlasses ? 'β Goal Reached!' : '+ Add Glass'}
{/* Progress Indicators */}
{[...Array(maxGlasses)].map((_, index) => (
))}
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'white',
borderRadius: 20,
padding: 24,
margin: 16,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 8,
elevation: 5,
},
title: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
marginBottom: 20,
},
glassContainer: {
alignItems: 'center',
marginBottom: 24,
},
glass: {
width: 100,
height: 150,
borderWidth: 3,
borderColor: '#4A90E2',
borderRadius: 10,
overflow: 'hidden',
justifyContent: 'flex-end',
},
waterFill: {
width: '100%',
backgroundColor: '#4A90E2',
opacity: 0.6,
},
glassText: {
fontSize: 24,
fontWeight: 'bold',
color: '#4A90E2',
marginTop: 12,
},
addButton: {
backgroundColor: '#4A90E2',
paddingHorizontal: 32,
paddingVertical: 12,
borderRadius: 25,
marginBottom: 16,
},
addButtonDisabled: {
backgroundColor: '#A8D5A8',
},
addButtonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
dotsContainer: {
flexDirection: 'row',
justifyContent: 'center',
gap: 8,
},
dot: {
width: 12,
height: 12,
borderRadius: 6,
backgroundColor: '#E0E0E0',
},
dotFilled: {
backgroundColor: '#4A90E2',
},
});
Using Copilot Chat for Complex Problems
Beyond code completion, Copilot Chat can explain concepts, debug issues, and suggest best practices.
Example: Ask Copilot to Add Navigation
Open Copilot Chat (Ctrl/Cmd + Shift + I) and ask:
Sample Copilot Chat Prompt
"Add React Navigation to this Expo project with a bottom tab navigator. Include Home, Stats, and Profile screens with appropriate icons."
Copilot Chat will provide step-by-step instructions:
# Install navigation packages
npx expo install @react-navigation/native @react-navigation/bottom-tabs
npx expo install react-native-screens react-native-safe-area-context
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
import HomeScreen from './screens/HomeScreen';
import StatsScreen from './screens/StatsScreen';
import ProfileScreen from './screens/ProfileScreen';
const Tab = createBottomTabNavigator();
export default function App() {
return (
({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused ? 'home' : 'home-outline';
} else if (route.name === 'Stats') {
iconName = focused ? 'stats-chart' : 'stats-chart-outline';
} else if (route.name === 'Profile') {
iconName = focused ? 'person' : 'person-outline';
}
return ;
},
tabBarActiveTintColor: '#4A90E2',
tabBarInactiveTintColor: 'gray',
headerShown: false,
})}
>
);
}
Pro Tips for Using Copilot Effectively
1. Write Descriptive Comments
The more context you provide, the better Copilot's suggestions:
// Create a function that validates email format using regex,
// returns true if valid, includes common email patterns like
// gmail, yahoo, and corporate domains
// Copilot will generate a comprehensive validation function
2. Use Copilot for Boilerplate
Let Copilot handle repetitive code:
// Redux slice for user authentication with login, logout, and token refresh
Copilot will generate the entire Redux slice with actions, reducers, and selectors!
3. Iterate with Copilot
If the first suggestion isn't perfect, press Alt/Option + ] to cycle through alternatives.
4. Ask for Explanations
Highlight code and ask Copilot Chat: "Explain this code" or "How can I optimize this?"
5. Test Generation
// Write Jest tests for the WaterTracker component
// Test: renders correctly, handles button press, shows correct glass count
Copilot will generate complete test suites!
Building a Complete Feature: Step Counter
Let's put it all together and build a step counter feature using device sensors:
npx expo install expo-sensors
// Create a StepCounter component that uses the device pedometer sensor
// Display current steps, daily goal progress, and a circular progress indicator
// Include start/stop tracking functionality
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { Pedometer } from 'expo-sensors';
import { CircularProgress } from 'react-native-circular-progress';
export default function StepCounter() {
const [steps, setSteps] = useState(0);
const [isTracking, setIsTracking] = useState(false);
const dailyGoal = 10000;
useEffect(() => {
let subscription;
const startTracking = async () => {
const isAvailable = await Pedometer.isAvailableAsync();
if (isAvailable && isTracking) {
subscription = Pedometer.watchStepCount(result => {
setSteps(result.steps);
});
}
};
startTracking();
return () => {
if (subscription) {
subscription.remove();
}
};
}, [isTracking]);
const toggleTracking = () => {
setIsTracking(!isTracking);
};
const progress = (steps / dailyGoal) * 100;
return (
Daily Steps
{() => (
{steps.toLocaleString()}
of {dailyGoal.toLocaleString()}
)}
{isTracking ? 'Stop Tracking' : 'Start Tracking'}
{progress >= 100 && (
π Congratulations! You reached your daily goal!
)}
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5F5F5',
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
title: {
fontSize: 28,
fontWeight: 'bold',
color: '#333',
marginBottom: 40,
},
progressContainer: {
marginBottom: 40,
},
progressContent: {
alignItems: 'center',
},
stepsText: {
fontSize: 48,
fontWeight: 'bold',
color: '#4A90E2',
},
goalText: {
fontSize: 16,
color: '#666',
marginTop: 8,
},
button: {
backgroundColor: '#4A90E2',
paddingHorizontal: 40,
paddingVertical: 16,
borderRadius: 30,
marginTop: 20,
},
buttonActive: {
backgroundColor: '#E74C3C',
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
congratsText: {
fontSize: 18,
color: '#27AE60',
marginTop: 30,
textAlign: 'center',
fontWeight: '600',
},
});
Debugging with Copilot
When you encounter errors, Copilot Chat can help debug:
Debugging Workflow
- Copy the error message
- Open Copilot Chat
- Paste error and ask: "Why am I getting this error and how do I fix it?"
- Copilot provides explanation and solution
Deployment Made Easy
Expo makes deployment incredibly simple. Ask Copilot Chat:
Deployment Prompt
"How do I build and deploy this Expo app to the App Store and Google Play?"
# Install EAS CLI
npm install -g eas-cli
# Login to Expo
eas login
# Configure project
eas build:configure
# Build for iOS
eas build --platform ios
# Build for Android
eas build --platform android
# Submit to stores
eas submit --platform ios
eas submit --platform android
Best Practices & Productivity Tips
Development Workflow Checklist
- Use Copilot comments to document what you want before writing code
- Press Ctrl/Cmd + I to open inline Copilot chat for quick questions
- Use Expo Go app for instant testing on real devices
- Leverage Copilot for generating TypeScript types and interfaces
- Ask Copilot to write documentation and README files
- Use Copilot to refactor code and suggest improvements
- Generate unit tests alongside your components
- Let Copilot create API integration code from OpenAPI specs
Real-World Time Savings
Based on my experience building React Native apps with this stack:
- Component Creation: 70% faster with Copilot suggestions
- Styling: StyleSheet definitions generated instantly
- API Integration: Complete service layer in minutes
- State Management: Redux/Context setup automated
- Testing: Test suites written as fast as you can type comments
- Documentation: Comprehensive docs generated from code
Result: What used to take days now takes hours. What took hours now takes minutes.
Conclusion
The combination of React Native, Expo, and GitHub Copilot represents the future of mobile development. You get:
- β Cross-platform development without the complexity
- β Instant testing on real devices
- β AI-powered code completion and generation
- β Faster iteration and deployment cycles
- β Built-in best practices and patterns
Whether you're building a simple prototype or a production app, this stack empowers you to move fast without sacrificing quality. GitHub Copilot doesn't just write codeβit teaches you, suggests improvements, and handles the boilerplate so you can focus on building amazing user experiences.
Keep Learning
The best way to master this workflow is to start building. Pick a simple app idea and let Copilot guide you through the process. You'll be amazed at how quickly you can bring ideas to life!