
React Native
- 3 installs
- 706 repo stars
- Updated July 14, 2026
- alinaqi/maggy
This is a copy of react-native by alinaqi - installs and ranking accrue to the original listing.
react-native is a Claude Code skill that sets React Native patterns for components, hooks, state management, and platform-specific mobile code.
About
This skill is a React Native mobile-development guide Claude applies when editing RN app code. It sets patterns for components, screens, hooks, state management, and platform-specific code. Developers use it to keep mobile UI logic extracted into hooks and business logic separate from presentation. It also lists React Native anti-patterns to avoid.
- Prescribes functional components, hooks-only logic, and explicit props interfaces
- Recommends Zustand for global state and React Query for server state
- Shows platform-specific file split (.ios.tsx / .android.tsx) and Platform.select
React Native by the numbers
- 3 all-time installs (skills.sh)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
react-native capabilities & compatibility
Free; open-source React Native tooling.
- Capabilities
- react native components · state management · mobile testing
- Use cases
- frontend · testing · ui design
- IDEs
- vscode
- Pricing
- Free
What react-native says it does
React Native mobile patterns, platform-specific code
when-to-use: When working on React Native mobile app code
❌ Inline styles - use StyleSheet.create
npx skills add https://github.com/alinaqi/maggy --skill react-nativeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3 |
|---|---|
| repo stars | ★ 706 |
| Last updated | July 14, 2026 |
| Repository | alinaqi/maggy ↗ |
What it does
Apply React Native component, hook, and state-management conventions when building a mobile app UI.
Who is it for?
React Native apps that need consistent component structure and hook-extracted logic.
When should I use this skill?
Working on React Native mobile app code (.tsx/.jsx, ios/, android/, app.json).
What you get
A React Native app with hook-extracted logic, StyleSheet styles, and separated core business logic.
- component patterns
- hook extraction
- state management setup
By the numbers
- 9 listed React Native anti-patterns
Files
React Native Skill
---
Project Structure
project/
├── src/
│ ├── core/ # Pure business logic (no React)
│ │ ├── types.ts
│ │ └── services/
│ ├── components/ # Reusable UI components
│ │ ├── Button/
│ │ │ ├── Button.tsx
│ │ │ ├── Button.test.tsx
│ │ │ └── index.ts
│ │ └── index.ts # Barrel export
│ ├── screens/ # Screen components
│ │ ├── Home/
│ │ │ ├── HomeScreen.tsx
│ │ │ ├── useHome.ts # Screen-specific hook
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── navigation/ # Navigation configuration
│ ├── hooks/ # Shared custom hooks
│ ├── store/ # State management
│ └── utils/ # Utilities
├── __tests__/
├── android/
├── ios/
└── CLAUDE.md---
Component Patterns
Functional Components Only
// Good - simple, testable
interface ButtonProps {
label: string;
onPress: () => void;
disabled?: boolean;
}
export function Button({ label, onPress, disabled = false }: ButtonProps): JSX.Element {
return (
<Pressable onPress={onPress} disabled={disabled}>
<Text>{label}</Text>
</Pressable>
);
}Extract Logic to Hooks
// useHome.ts - all logic here
export function useHome() {
const [items, setItems] = useState<Item[]>([]);
const [loading, setLoading] = useState(false);
const refresh = useCallback(async () => {
setLoading(true);
const data = await fetchItems();
setItems(data);
setLoading(false);
}, []);
return { items, loading, refresh };
}
// HomeScreen.tsx - pure presentation
export function HomeScreen(): JSX.Element {
const { items, loading, refresh } = useHome();
return (
<ItemList items={items} loading={loading} onRefresh={refresh} />
);
}Props Interface Always Explicit
// Always define props interface, even if simple
interface ItemCardProps {
item: Item;
onPress: (id: string) => void;
}
export function ItemCard({ item, onPress }: ItemCardProps): JSX.Element {
...
}---
State Management
Local State First
// Start with useState, escalate only when needed
const [value, setValue] = useState('');Zustand for Global State (if needed)
// store/useAppStore.ts
import { create } from 'zustand';
interface AppState {
user: User | null;
setUser: (user: User | null) => void;
}
export const useAppStore = create<AppState>((set) => ({
user: null,
setUser: (user) => set({ user }),
}));React Query for Server State
// hooks/useItems.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
export function useItems() {
return useQuery({
queryKey: ['items'],
queryFn: fetchItems,
});
}
export function useCreateItem() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: createItem,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['items'] });
},
});
}---
Testing
Component Testing with React Native Testing Library
import { render, fireEvent } from '@testing-library/react-native';
import { Button } from './Button';
describe('Button', () => {
it('calls onPress when pressed', () => {
const onPress = jest.fn();
const { getByText } = render(<Button label="Click me" onPress={onPress} />);
fireEvent.press(getByText('Click me'));
expect(onPress).toHaveBeenCalledTimes(1);
});
it('does not call onPress when disabled', () => {
const onPress = jest.fn();
const { getByText } = render(<Button label="Click me" onPress={onPress} disabled />);
fireEvent.press(getByText('Click me'));
expect(onPress).not.toHaveBeenCalled();
});
});Hook Testing
import { renderHook, act } from '@testing-library/react-hooks';
import { useCounter } from './useCounter';
describe('useCounter', () => {
it('increments counter', () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
});---
Platform-Specific Code
Use Platform.select Sparingly
import { Platform } from 'react-native';
const styles = StyleSheet.create({
shadow: Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
},
android: {
elevation: 2,
},
}),
});Separate Files for Complex Differences
Component/
├── Component.tsx # Shared logic
├── Component.ios.tsx # iOS-specific
├── Component.android.tsx # Android-specific
└── index.ts---
React Native Anti-Patterns
- ❌ Inline styles - use StyleSheet.create
- ❌ Logic in render - extract to hooks
- ❌ Deep component nesting - flatten hierarchy
- ❌ Anonymous functions in props - use useCallback
- ❌ Index as key in lists - use stable IDs
- ❌ Direct state mutation - always use setter
- ❌ Mixing business logic with UI - keep core/ pure
- ❌ Ignoring TypeScript errors - fix them
- ❌ Large components - split into smaller pieces
Related skills
FAQ
What state management does this skill recommend?
Local state via useState first, Zustand for global state, and React Query for server state.
How does it handle platform differences?
It uses Platform.select sparingly and separate .ios.tsx / .android.tsx files for complex differences.