Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
popup-studio-ai avatar

Mobile App

  • 110 installs
  • 586 repo stars
  • Updated July 28, 2026
  • popup-studio-ai/bkit-claude-code

mobile-app is a bkit-claude-code agent skill that guides cross-platform mobile development with React Native Expo and Flutter for developers building iOS and Android apps from web development experience.

About

mobile-app is a capability skill in popup-studio-ai/bkit-claude-code (v1.3.0 tier system) for building iOS and Android apps with React Native Expo as Tier 1 and Flutter as Tier 2. The skill documents npx create-expo-app scaffolding, Expo Router tab and stack navigation, NativeWind Tailwind styling, useApi fetch hooks, SecureStore authentication patterns, and EAS Build plus eas submit store deployment. Flutter coverage includes flutter create structure, Riverpod StateNotifier providers, and platform-specific safe-area and keyboard handling. A mobile PDCA checklist spans schema, mockup, UI, security, and deployment phases including App Store review timelines. Developers reach for mobile-app when scoping a first cross-platform app, choosing Expo versus React Native CLI versus Flutter, or implementing navigation, API integration, and store submission from an existing web codebase.

  • Tier 1 recommends React Native Expo; Tier 2 supports Flutter for 6-platform targets
  • Documents Expo Router (tabs) app/ structure with Stack and Tabs navigation examples
  • Includes SecureStore auth context, useApi fetch hook, and EAS Build submit commands
  • Covers Flutter Riverpod StateNotifierProvider and feature-based lib/ folder layout
  • Mobile PDCA checklist spans 5 phases: schema, mockup, UI, security, deployment

Mobile App by the numbers

  • 110 all-time installs (skills.sh)
  • +2 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #555 of 1,039 Mobile Development skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/popup-studio-ai/bkit-claude-code --skill mobile-app

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs110
repo stars586
Last updatedJuly 28, 2026
Repositorypopup-studio-ai/bkit-claude-code

How do you build a cross-platform mobile app with Expo?

Scaffold a React Native Expo app with tab navigation, SecureStore auth, and EAS Build deployment using the mobile-app skill patterns.

Who is it for?

Web developers starting a cross-platform mobile app who want framework selection guidance and copy-paste patterns for Expo Router or Flutter Riverpod.

Skip if: Native Swift or Kotlin-only projects without cross-platform frameworks, or backend API design unrelated to mobile client implementation.

When should I use this skill?

A developer asks to build a mobile app, set up React Native Expo, configure Flutter navigation, or deploy to App Store and Google Play with EAS.

What you get

Expo or Flutter project structure, navigation layouts, API integration hooks, auth context, EAS build configuration, and mobile PDCA checklist completion.

  • Expo or Flutter project scaffold
  • Navigation and auth patterns
  • EAS build and submit configuration

By the numbers

  • Framework tier guide at v1.3.0 with React Native Expo as Tier 1 and Flutter as Tier 2
  • Mobile PDCA checklist covers 5 implementation phases from schema through deployment

Files

SKILL.mdMarkdownGitHub ↗

Mobile App Development Expertise

Overview

A guide for developing mobile apps based on web development experience. Develop for iOS and Android simultaneously using cross-platform frameworks.

---

Framework Selection Guide

Framework Selection by Tier (v1.3.0)

FrameworkTierRecommendationUse Case
React Native (Expo)Tier 1⭐ PrimaryTypeScript ecosystem, AI tools
React Native CLITier 1RecommendedNative module needs
FlutterTier 2SupportedMulti-platform (6 OS), performance
AI-Native Recommendation: React Native with TypeScript
- Full Copilot/Claude support
- Extensive npm ecosystem
- 20:1 developer availability vs Dart
Performance Recommendation: Flutter
- Impeller rendering engine
- Single codebase for 6 platforms
- Smaller bundles

Level-wise Recommendations

Starter → Expo (React Native) [Tier 1]
  - Simple setup, can leverage web knowledge
  - Full AI tool support

Dynamic → Expo + EAS Build [Tier 1] or Flutter [Tier 2]
  - Includes server integration, production build support
  - Choose Flutter for multi-platform needs

Enterprise → React Native CLI [Tier 1] or Flutter [Tier 2]
  - Complex native features, performance optimization needed
  - Flutter for consistent cross-platform UI

---

Expo (React Native) Guide

Project Creation

# Install Expo CLI
npm install -g expo-cli

# Create new project
npx create-expo-app my-app
cd my-app

# Start development server
npx expo start

Folder Structure

my-app/
├── app/                    # Expo Router pages
│   ├── (tabs)/            # Tab navigation
│   │   ├── index.tsx      # Home tab
│   │   ├── explore.tsx    # Explore tab
│   │   └── _layout.tsx    # Tab layout
│   ├── _layout.tsx        # Root layout
│   └── +not-found.tsx     # 404 page
├── components/            # Reusable components
├── hooks/                 # Custom hooks
├── constants/             # Constants
├── assets/               # Images, fonts, etc.
├── app.json              # Expo configuration
└── package.json

Navigation Patterns

// app/_layout.tsx - Stack navigation
import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
      <Stack.Screen name="modal" options={{ presentation: 'modal' }} />
    </Stack>
  );
}
// app/(tabs)/_layout.tsx - Tab navigation
import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';

export default function TabLayout() {
  return (
    <Tabs>
      <Tabs.Screen
        name="index"
        options={{
          title: 'Home',
          tabBarIcon: ({ color }) => <Ionicons name="home" color={color} size={24} />,
        }}
      />
      <Tabs.Screen
        name="profile"
        options={{
          title: 'Profile',
          tabBarIcon: ({ color }) => <Ionicons name="person" color={color} size={24} />,
        }}
      />
    </Tabs>
  );
}

Styling Patterns

// Basic StyleSheet
import { StyleSheet, View, Text } from 'react-native';

export function MyComponent() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Hello</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
    backgroundColor: '#fff',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
  },
});
// NativeWind (Tailwind for RN) - Recommended
import { View, Text } from 'react-native';

export function MyComponent() {
  return (
    <View className="flex-1 p-4 bg-white">
      <Text className="text-2xl font-bold">Hello</Text>
    </View>
  );
}

API Integration

// hooks/useApi.ts
import { useState, useEffect } from 'react';

export function useApi<T>(endpoint: string) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(`${process.env.EXPO_PUBLIC_API_URL}${endpoint}`);
        if (!response.ok) throw new Error('API Error');
        const json = await response.json();
        setData(json);
      } catch (e) {
        setError(e as Error);
      } finally {
        setLoading(false);
      }
    };
    fetchData();
  }, [endpoint]);

  return { data, loading, error };
}

Authentication Pattern

// context/AuthContext.tsx
import { createContext, useContext, useState, useEffect } from 'react';
import * as SecureStore from 'expo-secure-store';

interface AuthContextType {
  user: User | null;
  signIn: (email: string, password: string) => Promise<void>;
  signOut: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | null>(null);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);

  useEffect(() => {
    // Check for stored token on app start
    const loadToken = async () => {
      const token = await SecureStore.getItemAsync('authToken');
      if (token) {
        // Load user info with token
      }
    };
    loadToken();
  }, []);

  const signIn = async (email: string, password: string) => {
    const response = await fetch('/api/auth/login', {
      method: 'POST',
      body: JSON.stringify({ email, password }),
    });
    const { token, user } = await response.json();
    await SecureStore.setItemAsync('authToken', token);
    setUser(user);
  };

  const signOut = async () => {
    await SecureStore.deleteItemAsync('authToken');
    setUser(null);
  };

  return (
    <AuthContext.Provider value={{ user, signIn, signOut }}>
      {children}
    </AuthContext.Provider>
  );
}

export const useAuth = () => useContext(AuthContext)!;

---

Flutter Guide

Project Creation

# After installing Flutter SDK
flutter create my_app
cd my_app

# Start development server
flutter run

Folder Structure

my_app/
├── lib/
│   ├── main.dart           # App entry point
│   ├── app/
│   │   ├── app.dart        # MaterialApp setup
│   │   └── routes.dart     # Route definitions
│   ├── features/           # Feature-based folders
│   │   ├── auth/
│   │   │   ├── screens/
│   │   │   ├── widgets/
│   │   │   └── providers/
│   │   └── home/
│   ├── shared/
│   │   ├── widgets/        # Common widgets
│   │   ├── services/       # API services
│   │   └── models/         # Data models
│   └── core/
│       ├── theme/          # Theme settings
│       └── constants/      # Constants
├── assets/                 # Images, fonts
├── pubspec.yaml           # Dependency management
└── android/ & ios/        # Native code

Basic Widget Patterns

// lib/features/home/screens/home_screen.dart
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: const Center(
        child: Text('Hello, Flutter!'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: const Icon(Icons.add),
      ),
    );
  }
}

State Management (Riverpod)

// lib/providers/counter_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = StateNotifierProvider<CounterNotifier, int>((ref) {
  return CounterNotifier();
});

class CounterNotifier extends StateNotifier<int> {
  CounterNotifier() : super(0);

  void increment() => state++;
  void decrement() => state--;
}
// Usage
class CounterScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);

    return Text('Count: $count');
  }
}

---

Web vs Mobile Differences

UI/UX Differences

ElementWebMobile
ClickonClickonPress
Scrolloverflow: scrollScrollView / FlatList
InputinputTextInput
Linksa hrefLink / navigation
Layoutdiv + CSSView + StyleSheet

Navigation Differences

Web: URL-based (browser back button)
Mobile: Stack-based (screen stacking)

Web: /users/123
Mobile: navigation.navigate('User', { id: 123 })

Storage Differences

Web: localStorage, sessionStorage, Cookie
Mobile: AsyncStorage, SecureStore, SQLite

⚠️ SecureStore is required for sensitive info on mobile!

---

Build & Deployment

Expo EAS Build

# Install EAS CLI
npm install -g eas-cli

# Login
eas login

# Configure build
eas build:configure

# iOS build
eas build --platform ios

# Android build
eas build --platform android

# Submit to stores
eas submit --platform ios
eas submit --platform android

Environment Variables

// app.json
{
  "expo": {
    "extra": {
      "apiUrl": "https://api.example.com"
    }
  }
}
// Usage
import Constants from 'expo-constants';

const apiUrl = Constants.expoConfig?.extra?.apiUrl;

---

Mobile PDCA Checklist

Phase 1: Schema

□ Identify data that needs offline caching
□ Define sync conflict resolution strategy

Phase 3: Mockup

□ Follow iOS/Android native UX guidelines
□ Consider gestures (swipe, pinch, etc.)
□ Layout for different screen sizes (phone, tablet)

Phase 6: UI

□ Keyboard handling (screen adjustment during input)
□ Safe Area handling (notch, home button area)
□ Handle platform-specific UI differences

Phase 7: Security

□ Store sensitive info with SecureStore
□ Certificate Pinning (if needed)
□ App obfuscation settings

Phase 9: Deployment

□ Follow App Store review guidelines
□ Prepare Privacy Policy URL
□ Prepare screenshots, app description

---

Frequently Asked Questions

Q: Can I convert a web project to an app?

A: Recommend separate project over full conversion
   - APIs can be shared
   - UI needs to be rewritten (for native UX)
   - Business logic can be shared

Q: Should I use Expo or React Native CLI?

A: Start with Expo!
   - 90%+ of apps are sufficient with Expo
   - Can eject later if needed
   - Use CLI only when native modules are absolutely required

Q: How long does app review take?

A:
   - iOS: 1-7 days (average 2-3 days)
   - Android: Few hours ~ 3 days

   ⚠️ First submission has high rejection possibility → Follow guidelines carefully!

---

Requesting from Claude

Project Creation

"Set up a [app description] app project with React Native + Expo.
Configure with 3 tab navigation (Home, Search, Profile)."

Screen Implementation

"Implement [screen name] screen.
- Display [content] at the top
- Display [list/form/etc.] in the middle
- [Button/navigation] at the bottom"

API Integration

"Implement screen integrating with [API endpoint].
- Show loading state
- Handle errors
- Support pull-to-refresh"

Related skills

How it compares

Use mobile-app for opinionated Expo-first cross-platform guidance within bkit; prefer platform-native docs for SwiftUI or Jetpack Compose-only apps.

FAQ

Does mobile-app recommend Expo or React Native CLI?

mobile-app recommends starting with Expo for Tier 1 projects because most apps do not need ejecting. React Native CLI is suggested for Enterprise tier when complex native modules are required. Flutter is Tier 2 for multi-platform or performance-focused builds.

What deployment tooling does mobile-app document?

mobile-app documents Expo EAS Build and eas submit for iOS and Android store submission. The skill notes typical App Store review takes 1–7 days and Android review takes hours to 3 days, with first submissions facing higher rejection risk.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.