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

Terminal
# 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

Terminal
# 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:

HomeScreen.js
// 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:

hooks/useHealthData.js
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:

Terminal
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:

components/WaterTracker.js
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:

Terminal (Copilot's response)
# Install navigation packages
npx expo install @react-navigation/native @react-navigation/bottom-tabs
npx expo install react-native-screens react-native-safe-area-context
App.js (Copilot's generated code)
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:

Good Comment
// 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:

Type this...
// 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

Comment
// 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:

Terminal
npx expo install expo-sensors
screens/StepCounter.js (Start with a comment)
// 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

  1. Copy the error message
  2. Open Copilot Chat
  3. Paste error and ask: "Why am I getting this error and how do I fix it?"
  4. 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?"

Terminal (EAS Build)
# 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!