Skill

Stack: React Native Mobile

Install
1
Install the plugin
$
npx claudepluginhub syntek-dev/syntek-dev-suite --plugin syntek-dev-suite

Want just this skill?

Add to a custom plugin, then install with one command.

Description

**Last Updated**: 29/12/2025

Tool Access

This skill uses the workspace's default tool permissions.

Skill Content

Stack: React Native Mobile

Last Updated: 29/12/2025 Version: 1.3.1 Maintained By: Development Team Language: British English (en_GB) Timezone: Europe/London


Table of Contents


Architecture

LayerTechnology
PlatformNative / Simulator (NO Docker)
FrameworkReact Native, Expo (optional), TypeScript
StylingNativeWind (Tailwind for Mobile)
NavigationReact Navigation
TestingJest, React Native Testing Library

CRITICAL: Do NOT suggest Docker commands for this stack. Mobile runs natively.


Commands

TaskCommand
Start Metro Bundlernpm start
Run on iOSnpm run ios
Run on Androidnpm run android
Install iOS Podscd ios && pod install && cd ..
Run testsnpm test
Run tests (watch)npm test -- --watch
Install packagesnpm install <package>
Lintnpm run lint
Clean build (iOS)cd ios && rm -rf build && cd ..
Clean build (Android)cd android && ./gradlew clean && cd ..
Reset Metro cachenpm start -- --reset-cache

Coding Standards

Components

  • Use React Native Core Components: <View>, <Text>, <ScrollView>, <TouchableOpacity>
  • NEVER use HTML elements: No <div>, <span>, <p>, <button>
  • Functional components only with TypeScript interfaces
import { View, Text, TouchableOpacity } from 'react-native';

interface UserCardProps {
  user: User;
  onPress: (userId: string) => void;
}

export function UserCard({ user, onPress }: UserCardProps): JSX.Element {
  return (
    <TouchableOpacity
      className="rounded-lg bg-white p-4 shadow-md"
      onPress={() => onPress(user.id)}
    >
      <Text className="text-lg font-semibold text-gray-900">{user.name}</Text>
      <Text className="text-sm text-gray-500">{user.email}</Text>
    </TouchableOpacity>
  );
}

Styling (NativeWind)

  • Use Tailwind-like classes: className="flex-1 bg-white"
  • Responsive design not pixel-based - use flex
  • Test on both iOS and Android for styling differences

Platform-Specific Code

PatternUse Case
Platform.OS === 'ios'Inline conditionals
Component.ios.tsx / Component.android.tsxSeparate component files
Platform.select({ ios: {...}, android: {...} })Style objects

Navigation (React Navigation)

  • Use typed navigation with TypeScript
  • Define navigation types centrally
  • Use Stack, Tab, and Drawer navigators appropriately

File Structure

src/
├── components/
│   ├── ui/                   # Generic UI components
│   │   ├── Button.tsx
│   │   └── Card.tsx
│   └── features/             # Feature-specific components
├── screens/                  # Screen components
│   ├── HomeScreen.tsx
│   └── ProfileScreen.tsx
├── navigation/
│   ├── types.ts              # Navigation type definitions
│   ├── RootNavigator.tsx
│   └── TabNavigator.tsx
├── hooks/
│   ├── useAuth.ts
│   └── useStorage.ts
├── services/
│   └── api.ts
├── types/
│   └── index.ts
├── utils/
│   └── formatters.ts
└── App.tsx

docs/
└── METRICS/            # Self-learning system (see global-workflow skill)
    ├── README.md
    ├── config.json
    ├── runs/
    ├── feedback/
    └── optimisations/

Platform Considerations

iOS Specific

  • Handle safe area insets (SafeAreaView)
  • Face ID / Touch ID authentication
  • Test on notched devices (iPhone X+)
  • Handle keyboard avoiding view

Android Specific

  • Handle back button navigation
  • Status bar configuration
  • Handle different screen densities
  • Test on various Android versions

Testing (Jest + RNTL)

import { render, fireEvent, screen } from '@testing-library/react-native';
import { UserCard } from './UserCard';

describe('UserCard', () => {
  const mockUser = { id: '1', name: 'Test User', email: 'test@example.com' };

  it('renders user information', () => {
    render(<UserCard user={mockUser} onPress={jest.fn()} />);

    expect(screen.getByText('Test User')).toBeOnTheScreen();
    expect(screen.getByText('test@example.com')).toBeOnTheScreen();
  });

  it('calls onPress when tapped', () => {
    const onPress = jest.fn();
    render(<UserCard user={mockUser} onPress={onPress} />);

    fireEvent.press(screen.getByText('Test User'));

    expect(onPress).toHaveBeenCalledWith('1');
  });
});
Stats
Stars0
Forks0
Last CommitDec 29, 2025
Actions

Similar Skills