React Native CLI
Standar pengembangan aplikasi menggunakan React Native CLI (bare workflow) — memberikan kontrol penuh terhadap native modules dan build configuration.
Kapan Menggunakan RN CLI?
| Kriteria | RN CLI | Expo |
|---|---|---|
| Custom native modules | ✅ Penuh | ⚠️ Terbatas (dev client) |
| Native code access | ✅ Langsung | ❌ Via config plugins |
| Build customization | ✅ Penuh | ⚠️ Terbatas |
| Setup complexity | ⚠️ Lebih rumit | ✅ Lebih mudah |
| Upgrade path | ⚠️ Manual | ✅ Otomatis |
Gunakan RN CLI jika:
- Project membutuhkan native modules kustom.
- Integrasi SDK native yang tidak tersedia di Expo.
- Membutuhkan kontrol penuh atas Gradle/Xcode configuration.
New Architecture wajib
Sejak React Native 0.82, legacy Bridge sudah dihapus total — Fabric (renderer), TurboModules, dan JSI kini satu-satunya arsitektur yang tersedia. Native module lama yang masih ditulis dengan Bridge API (NativeModules/NativeEventEmitter gaya lama) harus dimigrasikan ke TurboModules sebelum upgrade. Untuk project baru, generate module native langsung dengan Codegen (create-react-native-library) supaya kompatibel sejak awal.
Tech Stack
| Kategori | Library | Versi Min. |
|---|---|---|
| Runtime | React Native | 0.87+ |
| Architecture | New Architecture (Fabric + TurboModules + JSI) | Wajib sejak 0.82 |
| Language | TypeScript | 5.x |
| Navigation | React Navigation | 7.x |
| State Management | Zustand / Redux Toolkit | Latest |
| Networking | Axios / TanStack Query | Latest |
| Forms | React Hook Form + Zod | Latest |
| UI Library | React Native Paper / NativeWind | Latest |
| Local Storage | MMKV / Async Storage | Latest |
| Testing | Jest, React Native Testing Library | Latest |
| Linting | ESLint + Prettier | Latest |
| CI/CD | Fastlane + GitLab CI | — |
Project Structure
src/
├── app/
│ ├── App.tsx # Root component
│ └── navigation/ # Stack/Tab navigators
├── core/
│ ├── api/ # Axios instance, interceptors
│ ├── constants/
│ ├── hooks/ # Custom hooks
│ ├── theme/ # Colors, typography, spacing
│ └── utils/
├── data/
│ ├── dto/ # Data transfer objects
│ ├── repositories/ # Repository implementations
│ └── services/ # API service classes
├── domain/
│ ├── entities/ # Domain models (Zod schemas)
│ ├── repositories/ # Repository interfaces
│ └── usecases/ # Use cases
├── presentation/
│ ├── screens/
│ │ ├── Home/
│ │ │ ├── HomeScreen.tsx
│ │ │ ├── useHomeScreen.ts # Custom hook for logic
│ │ │ └── components/ # Screen-specific components
│ │ └── Profile/
│ └── components/ # Shared components
├── store/ # Zustand stores
└── types/ # Global type definitions
android/ # Native Android project
ios/ # Native iOS project
Coding Standards
TypeScript Strict Mode
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"noUnusedParameters": true
}
}
Component Pattern
// ✅ Good - typed props langsung, tanpa React.FC
// (React.FC menambahkan `children` secara implisit dan mempersulit generics)
interface UserCardProps {
user: UserEntity;
onPress: () => void;
}
export function UserCard({ user, onPress }: UserCardProps) {
return (
<Pressable onPress={onPress} style={styles.container}>
<Text style={styles.name}>{user.name}</Text>
<Text style={styles.email}>{user.email}</Text>
</Pressable>
);
}
const styles = StyleSheet.create({
container: { padding: 16, borderRadius: 8 },
name: { fontSize: 16, fontWeight: '600' },
email: { fontSize: 14, color: '#666' },
});
Custom Hook Pattern
// ✅ Screen logic disimpan di custom hook, pakai TanStack Query
// alih-alih useState/useEffect manual (dapat caching, dedup, retry gratis)
export const useHomeScreen = () => {
const {
data: users,
isLoading,
error,
refetch,
} = useQuery({
queryKey: ['users'],
queryFn: getUsersUseCase,
});
return { users: users ?? [], loading: isLoading, error, refetch };
};
Build & Run
# Install dependencies
npm install
# iOS pod install
cd ios && pod install && cd ..
# Run Android
npx react-native run-android
# Run iOS
npx react-native run-ios
# Run tests
npm test
# Lint
npx eslint src/ --fix
# Build Android release
cd android && ./gradlew assembleRelease
# Build iOS release (via Fastlane)
cd ios && fastlane release
Native Linking
Setelah menambahkan library yang memiliki native module, wajib jalankan cd ios && pod install dan rebuild.