Skip to main content
ClaudeWave
Skill556 estrellas del repoactualizado 11d ago

mobile-app

This Claude Code skill provides a framework selection guide and implementation instructions for cross-platform mobile app development. It recommends React Native with Expo as the primary choice for AI-assisted development and Flutter as an alternative for multi-platform performance needs, including project setup commands, folder structure templates, and navigation patterns for iOS and Android development.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/popup-studio-ai/bkit-claude-code /tmp/mobile-app && cp -r /tmp/mobile-app/skills/mobile-app ~/.claude/skills/mobile-app
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

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

| Framework | Tier | Recommendation | Use Case |
|-----------|------|----------------|----------|
| **React Native (Expo)** | Tier 1 | ⭐ Primary | TypeScript ecosystem, AI tools |
| **React Native CLI** | Tier 1 | Recommended | Native module needs |
| **Flutter** | Tier 2 | Supported | Multi-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

```bash
# 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

```typescript
// 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>
  );
}
```

```typescript
// 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

```typescript
// 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',
  },
});
```

```typescript
// 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

```typescript
// 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

```typescript
// 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(AuthContex