# Mobile App Builder

> Crea aplicaciones móviles nativas iOS y Android. Usa este skill para desarrollo con React Native, Expo, Flutter, optimización de performance móvil, publicación en App Store y Play Store, y features nativos como push notifications.

- Skill: `leandroomargarcia/mobile-app-builder` (Agent Skill)
- Install (CLI): `npx skillmds@latest add leandroomargarcia/mobile-app-builder`
- Raw SKILL.md: https://api.skillmd.com/api/skills/leandroomargarcia/mobile-app-builder/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: leandroomargarcia (https://skillmd.com/u/leandroomargarcia)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/leandroomargarcia/mobile-app-builder

---


# Mobile App Builder

Especialista en crear experiencias móviles nativas y cross-platform. Expertise en React Native, Expo, Flutter, y publicación en stores.

## Cuándo Usar Este Skill

- Construir apps iOS y/o Android
- Migrar web app a móvil
- Implementar features nativos (cámara, GPS, push)
- Optimizar performance móvil
- Publicar en App Store / Play Store
- Manejar deep linking y universal links

## Responsabilidades Principales

### 1. Setup & Arquitectura
- Configura proyectos con Expo o bare React Native
- Implementa navegación con React Navigation
- Estructura el proyecto para escalabilidad
- Configura TypeScript y linting
- Implementa CI/CD para builds móviles

### 2. Features Nativos
- Integra cámara, galería, y permisos
- Implementa push notifications (FCM, APNs)
- Maneja geolocalización
- Integra biometría (Face ID, Touch ID)
- Implementa deep linking

### 3. Performance & UX
- Optimiza renders y animaciones
- Implementa gestures fluidos
- Maneja offline-first con persistencia
- Optimiza startup time
- Reduce bundle size

### 4. Publishing
- Prepara assets para stores (icons, screenshots)
- Configura app signing y certificates
- Maneja versioning semántico
- Implementa OTA updates (Expo Updates, CodePush)
- Navega review guidelines de Apple/Google

## Tech Stack

| Área | Tecnologías |
|------|-------------|
| Framework | React Native, Expo, Flutter |
| Navigation | React Navigation, Expo Router |
| State | Zustand, Jotai, Redux Toolkit |
| Storage | AsyncStorage, MMKV, WatermelonDB |
| Push | Expo Notifications, FCM, OneSignal |
| Analytics | Amplitude, Mixpanel, Firebase |

## Estructura de Proyecto (Expo)

```
app/
├── (tabs)/              # Tab navigation
│   ├── index.tsx        # Home tab
│   ├── explore.tsx      # Explore tab
│   └── profile.tsx      # Profile tab
├── _layout.tsx          # Root layout
└── modal.tsx            # Modal screens
components/
├── ui/                  # Base components
└── features/            # Domain components
hooks/
lib/
constants/
```

## Checklist Pre-Launch

```
App Store (iOS):
- [ ] App icons (1024x1024)
- [ ] Screenshots (6.7", 6.5", 5.5")
- [ ] App preview video (opcional)
- [ ] Privacy policy URL
- [ ] App description y keywords
- [ ] Age rating configurado
- [ ] In-app purchases configurados (si aplica)
- [ ] TestFlight beta probado

Play Store (Android):
- [ ] App icon (512x512)
- [ ] Feature graphic (1024x500)
- [ ] Screenshots (phone, tablet)
- [ ] Privacy policy URL
- [ ] App description
- [ ] Content rating questionnaire
- [ ] Target audience configurado
- [ ] Internal testing completado
```

## Performance Optimization

### Evitar Re-renders
```tsx
// Usar memo para componentes de lista
const ListItem = memo(({ item, onPress }) => (
  <Pressable onPress={() => onPress(item.id)}>
    <Text>{item.title}</Text>
  </Pressable>
));

// FlatList con keyExtractor y optimizations
<FlatList
  data={items}
  renderItem={({ item }) => <ListItem item={item} />}
  keyExtractor={item => item.id}
  removeClippedSubviews={true}
  maxToRenderPerBatch={10}
  windowSize={5}
/>
```

### Optimizar Imágenes
```tsx
import { Image } from 'expo-image';

<Image
  source={{ uri: imageUrl }}
  placeholder={blurhash}
  contentFit="cover"
  transition={200}
  style={styles.image}
/>
```

## Push Notifications Setup

```tsx
import * as Notifications from 'expo-notifications';

// Configurar handler
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: true,
  }),
});

// Registrar para push
async function registerForPush() {
  const { status } = await Notifications.requestPermissionsAsync();
  if (status !== 'granted') return;
  
  const token = await Notifications.getExpoPushTokenAsync();
  // Enviar token al backend
  await api.registerPushToken(token.data);
}
```

## Deep Linking

```tsx
// app.json
{
  "expo": {
    "scheme": "myapp",
    "ios": {
      "associatedDomains": ["applinks:myapp.com"]
    },
    "android": {
      "intentFilters": [{
        "action": "VIEW",
        "data": [{ "scheme": "https", "host": "myapp.com" }]
      }]
    }
  }
}

// Expo Router maneja automáticamente
// myapp://product/123 → /product/[id]
```

## Offline-First Pattern

```tsx
import NetInfo from '@react-native-community/netinfo';
import { useQuery, useQueryClient } from '@tanstack/react-query';

function useOfflineFirst(key, fetcher) {
  const queryClient = useQueryClient();
  
  // Cargar de cache primero
  useEffect(() => {
    const cached = storage.getString(key);
    if (cached) {
      queryClient.setQueryData([key], JSON.parse(cached));
    }
  }, []);
  
  return useQuery({
    queryKey: [key],
    queryFn: async () => {
      const data = await fetcher();
      storage.set(key, JSON.stringify(data));
      return data;
    },
    staleTime: 5 * 60 * 1000,
  });
}
```

## Mejores Prácticas

1. **Diseña para offline** - La red móvil no es confiable
2. **Respeta gestos nativos** - Swipe back, pull to refresh
3. **Optimiza para batería** - Evita polling, usa push
4. **Maneja permisos gracefully** - Explica por qué los necesitas
5. **Testea en devices reales** - Simuladores no son suficiente
6. **Implementa crash reporting** - Sentry, Crashlytics

## Filosofía

> "Mobile users expect perfection - 60fps, instant response, and offline capability. Anything less feels broken."

El objetivo es crear experiencias móviles que se sientan nativas, rápidas, y confiables.

