cortex-agents 1.1.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/agents/build.md +34 -3
- package/.opencode/agents/debug.md +24 -2
- package/.opencode/agents/devops.md +1 -2
- package/.opencode/agents/fullstack.md +1 -2
- package/.opencode/agents/plan.md +5 -3
- package/.opencode/agents/security.md +1 -2
- package/.opencode/agents/testing.md +1 -2
- package/.opencode/skills/api-design/SKILL.md +348 -0
- package/.opencode/skills/architecture-patterns/SKILL.md +323 -0
- package/.opencode/skills/backend-development/SKILL.md +329 -0
- package/.opencode/skills/code-quality/SKILL.md +12 -0
- package/.opencode/skills/database-design/SKILL.md +347 -0
- package/.opencode/skills/deployment-automation/SKILL.md +7 -0
- package/.opencode/skills/design-patterns/SKILL.md +295 -0
- package/.opencode/skills/desktop-development/SKILL.md +295 -0
- package/.opencode/skills/frontend-development/SKILL.md +210 -0
- package/.opencode/skills/mobile-development/SKILL.md +407 -0
- package/.opencode/skills/performance-optimization/SKILL.md +330 -0
- package/.opencode/skills/testing-strategies/SKILL.md +33 -0
- package/README.md +390 -76
- package/dist/cli.js +249 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -0
- package/dist/plugin.js +3 -2
- package/dist/registry.d.ts +45 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +140 -0
- package/dist/tools/cortex.d.ts.map +1 -1
- package/dist/tools/cortex.js +2 -3
- package/dist/tools/docs.d.ts +52 -0
- package/dist/tools/docs.d.ts.map +1 -0
- package/dist/tools/docs.js +328 -0
- package/package.json +11 -4
- package/.opencode/skills/web-development/SKILL.md +0 -122
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mobile-development
|
|
3
|
+
description: Cross-platform (React Native, Flutter) and native (Swift/SwiftUI, Kotlin/Compose) mobile development patterns
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
compatibility: opencode
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Mobile Development Skill
|
|
9
|
+
|
|
10
|
+
This skill provides patterns and best practices for building mobile applications, covering both cross-platform and native approaches.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
Use this skill when:
|
|
15
|
+
- Building new mobile applications (iOS, Android, or both)
|
|
16
|
+
- Choosing between cross-platform and native development
|
|
17
|
+
- Implementing mobile-specific features (offline, push, deep linking)
|
|
18
|
+
- Optimizing mobile app performance
|
|
19
|
+
- Distributing apps to stores
|
|
20
|
+
|
|
21
|
+
## Framework Decision Matrix
|
|
22
|
+
|
|
23
|
+
| Framework | Language | Performance | Native Feel | Code Sharing | Best For |
|
|
24
|
+
|-----------|----------|-------------|-------------|--------------|----------|
|
|
25
|
+
| Swift/SwiftUI | Swift | Excellent | Excellent | iOS only | iOS-only apps, Apple ecosystem |
|
|
26
|
+
| Kotlin/Compose | Kotlin | Excellent | Excellent | Android only | Android-only, Google ecosystem |
|
|
27
|
+
| Flutter | Dart | Very Good | Good | ~95% shared | Cross-platform, custom UI |
|
|
28
|
+
| React Native | JS/TS | Good | Good | ~85% shared | Web teams, JS ecosystem |
|
|
29
|
+
| Expo | JS/TS | Good | Good | ~90% shared | RN with managed workflow |
|
|
30
|
+
| Capacitor | JS/TS | Fair | Fair | ~95% shared | Web app → mobile wrapper |
|
|
31
|
+
| KMP | Kotlin | Good | Excellent | Logic only | Shared logic, native UI |
|
|
32
|
+
|
|
33
|
+
### When to Choose Cross-Platform
|
|
34
|
+
- Target both iOS and Android with shared codebase
|
|
35
|
+
- Web development team (React Native, Capacitor)
|
|
36
|
+
- Uniform UI across platforms (Flutter)
|
|
37
|
+
- Rapid prototyping and iteration
|
|
38
|
+
- Budget constraints — one team for both platforms
|
|
39
|
+
|
|
40
|
+
### When to Choose Native
|
|
41
|
+
- Deep platform integration (HealthKit, ARKit, Widgets)
|
|
42
|
+
- Maximum performance needed (games, video, AR)
|
|
43
|
+
- Single-platform target
|
|
44
|
+
- Platform-specific design language is critical
|
|
45
|
+
|
|
46
|
+
## Cross-Platform: React Native
|
|
47
|
+
|
|
48
|
+
### Architecture (New Architecture)
|
|
49
|
+
```
|
|
50
|
+
┌────────────────────────────────┐
|
|
51
|
+
│ React Native App │
|
|
52
|
+
├────────────────────────────────┤
|
|
53
|
+
│ JavaScript / TypeScript │
|
|
54
|
+
│ React Components │
|
|
55
|
+
│ State Management │
|
|
56
|
+
├────────────────────────────────┤
|
|
57
|
+
│ JSI (JavaScript Interface) │ ← Direct JS ↔ Native bridge
|
|
58
|
+
│ Fabric Renderer │ ← Concurrent rendering
|
|
59
|
+
│ TurboModules │ ← Lazy-loaded native modules
|
|
60
|
+
├────────────────────────────────┤
|
|
61
|
+
│ Hermes Engine (JS runtime) │
|
|
62
|
+
├────────────────────────────────┤
|
|
63
|
+
│ iOS (UIKit) │ Android (View) │
|
|
64
|
+
└───────────────┴────────────────┘
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Project Setup
|
|
68
|
+
- **Expo** (Recommended) — Managed workflow, easy native module integration via config plugins
|
|
69
|
+
- **Bare React Native** — Full control, needed for custom native code
|
|
70
|
+
- **Expo + Dev Client** — Best of both: Expo convenience + custom native modules
|
|
71
|
+
|
|
72
|
+
### State Management
|
|
73
|
+
| Library | Style | Best For |
|
|
74
|
+
|---------|-------|----------|
|
|
75
|
+
| Zustand | Simple, hook-based | Most apps, minimal boilerplate |
|
|
76
|
+
| Redux Toolkit | Flux pattern | Large apps, complex state |
|
|
77
|
+
| Jotai/Recoil | Atomic state | Fine-grained reactivity |
|
|
78
|
+
| TanStack Query | Server state | API data, caching, sync |
|
|
79
|
+
| MMKV | Persistent key-value | Fast local storage |
|
|
80
|
+
|
|
81
|
+
### React Native Best Practices
|
|
82
|
+
- Use `FlatList` or `FlashList` for lists — never `.map()` for scrollable content
|
|
83
|
+
- Minimize bridge crossings — batch native calls, use JSI
|
|
84
|
+
- Avoid inline styles — use `StyleSheet.create()` for performance
|
|
85
|
+
- Test on real devices — simulators don't reflect real performance
|
|
86
|
+
- Use Hermes engine — faster startup, lower memory
|
|
87
|
+
|
|
88
|
+
## Cross-Platform: Flutter
|
|
89
|
+
|
|
90
|
+
### Architecture
|
|
91
|
+
```
|
|
92
|
+
┌──────────────────────────────┐
|
|
93
|
+
│ Flutter App │
|
|
94
|
+
├──────────────────────────────┤
|
|
95
|
+
│ Dart Code │
|
|
96
|
+
│ Widget Tree │
|
|
97
|
+
│ State Management │
|
|
98
|
+
├──────────────────────────────┤
|
|
99
|
+
│ Flutter Framework │
|
|
100
|
+
│ (Material, Cupertino, │
|
|
101
|
+
│ Rendering, Painting) │
|
|
102
|
+
├──────────────────────────────┤
|
|
103
|
+
│ Skia / Impeller Engine │ ← Custom rendering (not native views)
|
|
104
|
+
├──────────────────────────────┤
|
|
105
|
+
│ Platform Channels │ ← Bridge to native APIs
|
|
106
|
+
├──────────────────────────────┤
|
|
107
|
+
│ iOS (Darwin) │ Android (JNI) │
|
|
108
|
+
└───────────────┴──────────────┘
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### State Management
|
|
112
|
+
| Library | Pattern | Best For |
|
|
113
|
+
|---------|---------|----------|
|
|
114
|
+
| Riverpod | Provider-based, compile-safe | Most apps (recommended) |
|
|
115
|
+
| BLoC | Stream-based, event-driven | Large apps, enterprise |
|
|
116
|
+
| Provider | InheritedWidget wrapper | Simple apps, beginners |
|
|
117
|
+
| GetX | All-in-one (state, routing, DI) | Rapid prototyping |
|
|
118
|
+
|
|
119
|
+
### Widget Patterns
|
|
120
|
+
```dart
|
|
121
|
+
// Stateless — pure UI, no internal state
|
|
122
|
+
class UserCard extends StatelessWidget {
|
|
123
|
+
final User user;
|
|
124
|
+
const UserCard({required this.user});
|
|
125
|
+
|
|
126
|
+
@override
|
|
127
|
+
Widget build(BuildContext context) {
|
|
128
|
+
return Card(
|
|
129
|
+
child: ListTile(
|
|
130
|
+
title: Text(user.name),
|
|
131
|
+
subtitle: Text(user.email),
|
|
132
|
+
leading: CircleAvatar(backgroundImage: NetworkImage(user.avatar)),
|
|
133
|
+
),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Riverpod — reactive state management
|
|
139
|
+
final userProvider = FutureProvider<User>((ref) async {
|
|
140
|
+
final api = ref.watch(apiClientProvider);
|
|
141
|
+
return api.getUser();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
class UserScreen extends ConsumerWidget {
|
|
145
|
+
@override
|
|
146
|
+
Widget build(BuildContext context, WidgetRef ref) {
|
|
147
|
+
final userAsync = ref.watch(userProvider);
|
|
148
|
+
return userAsync.when(
|
|
149
|
+
data: (user) => UserCard(user: user),
|
|
150
|
+
loading: () => CircularProgressIndicator(),
|
|
151
|
+
error: (err, stack) => Text('Error: $err'),
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Flutter Best Practices
|
|
158
|
+
- Use `const` constructors wherever possible — reduces rebuilds
|
|
159
|
+
- Keep widget tree shallow — extract widgets into separate classes
|
|
160
|
+
- Use `ListView.builder()` for long lists — lazy rendering
|
|
161
|
+
- Platform-adaptive UI — `Platform.isIOS` for Cupertino vs Material
|
|
162
|
+
- Use Impeller renderer (default on iOS, opt-in on Android) for smooth rendering
|
|
163
|
+
|
|
164
|
+
## Native: iOS (Swift / SwiftUI)
|
|
165
|
+
|
|
166
|
+
### SwiftUI Patterns
|
|
167
|
+
```swift
|
|
168
|
+
struct ContentView: View {
|
|
169
|
+
@StateObject private var viewModel = UserViewModel()
|
|
170
|
+
|
|
171
|
+
var body: some View {
|
|
172
|
+
NavigationStack {
|
|
173
|
+
List(viewModel.users) { user in
|
|
174
|
+
NavigationLink(value: user) {
|
|
175
|
+
UserRow(user: user)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
.navigationTitle("Users")
|
|
179
|
+
.navigationDestination(for: User.self) { user in
|
|
180
|
+
UserDetailView(user: user)
|
|
181
|
+
}
|
|
182
|
+
.refreshable {
|
|
183
|
+
await viewModel.refresh()
|
|
184
|
+
}
|
|
185
|
+
.task {
|
|
186
|
+
await viewModel.loadUsers()
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### iOS Architecture Patterns
|
|
194
|
+
- **MVVM** — ViewModel as ObservableObject, View observes with @StateObject
|
|
195
|
+
- **Coordinator** — Navigation logic extracted from views
|
|
196
|
+
- **Repository** — Data access abstraction (network + cache)
|
|
197
|
+
- **async/await** — Modern concurrency with structured tasks
|
|
198
|
+
|
|
199
|
+
### iOS-Specific Features
|
|
200
|
+
- **Widgets** — WidgetKit for home screen and lock screen widgets
|
|
201
|
+
- **App Clips** — Lightweight app experiences without full install
|
|
202
|
+
- **SharePlay** — Real-time shared experiences
|
|
203
|
+
- **Core Data / SwiftData** — Local persistence with sync
|
|
204
|
+
- **CloudKit** — Apple's cloud database with sync
|
|
205
|
+
|
|
206
|
+
## Native: Android (Kotlin / Jetpack Compose)
|
|
207
|
+
|
|
208
|
+
### Compose Patterns
|
|
209
|
+
```kotlin
|
|
210
|
+
@Composable
|
|
211
|
+
fun UserListScreen(
|
|
212
|
+
viewModel: UserViewModel = hiltViewModel()
|
|
213
|
+
) {
|
|
214
|
+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
|
215
|
+
|
|
216
|
+
Scaffold(
|
|
217
|
+
topBar = { TopAppBar(title = { Text("Users") }) }
|
|
218
|
+
) { padding ->
|
|
219
|
+
when (val state = uiState) {
|
|
220
|
+
is UiState.Loading -> CircularProgressIndicator()
|
|
221
|
+
is UiState.Success -> {
|
|
222
|
+
LazyColumn(contentPadding = padding) {
|
|
223
|
+
items(state.users) { user ->
|
|
224
|
+
UserCard(user = user, onClick = { viewModel.selectUser(it) })
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
is UiState.Error -> ErrorMessage(state.message)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Android Architecture (Recommended)
|
|
235
|
+
- **MVVM + Clean Architecture** — Google's recommended approach
|
|
236
|
+
- **Hilt** — Dependency injection
|
|
237
|
+
- **Navigation Compose** — Type-safe navigation
|
|
238
|
+
- **Room** — SQLite abstraction for local persistence
|
|
239
|
+
- **DataStore** — Modern replacement for SharedPreferences
|
|
240
|
+
|
|
241
|
+
### Android-Specific Features
|
|
242
|
+
- **App Widgets** — Glance (Jetpack Compose for widgets)
|
|
243
|
+
- **WorkManager** — Reliable background processing
|
|
244
|
+
- **Foreground Services** — Long-running tasks with notification
|
|
245
|
+
- **Dynamic Feature Modules** — Download features on demand
|
|
246
|
+
- **Material 3** — Dynamic color, Material You theming
|
|
247
|
+
|
|
248
|
+
## Mobile-Specific Patterns
|
|
249
|
+
|
|
250
|
+
### App Lifecycle
|
|
251
|
+
| iOS State | Android State | Description |
|
|
252
|
+
|-----------|---------------|-------------|
|
|
253
|
+
| Active | Resumed | App is in foreground, receiving events |
|
|
254
|
+
| Inactive | Paused | App visible but not receiving events |
|
|
255
|
+
| Background | Stopped | App not visible, limited execution |
|
|
256
|
+
| Suspended | — | App in memory but not executing |
|
|
257
|
+
| Not Running | Destroyed | App not in memory |
|
|
258
|
+
|
|
259
|
+
### Deep Linking / Universal Links
|
|
260
|
+
```
|
|
261
|
+
// URL scheme: myapp://users/123
|
|
262
|
+
// Universal link: https://myapp.com/users/123
|
|
263
|
+
|
|
264
|
+
// React Native (React Navigation)
|
|
265
|
+
const linking = {
|
|
266
|
+
prefixes: ['myapp://', 'https://myapp.com'],
|
|
267
|
+
config: {
|
|
268
|
+
screens: {
|
|
269
|
+
User: 'users/:id',
|
|
270
|
+
Settings: 'settings',
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// Flutter (go_router)
|
|
276
|
+
GoRouter(
|
|
277
|
+
routes: [
|
|
278
|
+
GoRoute(path: '/users/:id', builder: (context, state) =>
|
|
279
|
+
UserScreen(id: state.pathParameters['id']!)),
|
|
280
|
+
],
|
|
281
|
+
);
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Push Notifications
|
|
285
|
+
- **FCM** (Firebase Cloud Messaging) — Android + iOS
|
|
286
|
+
- **APNs** (Apple Push Notification Service) — iOS native
|
|
287
|
+
- Request permission gracefully — explain value before asking
|
|
288
|
+
- Support notification categories and actions
|
|
289
|
+
- Handle notification tap to deep link into specific screen
|
|
290
|
+
- Silent/background push for data sync
|
|
291
|
+
|
|
292
|
+
### Biometric Authentication
|
|
293
|
+
- Face ID / Touch ID (iOS) via LocalAuthentication
|
|
294
|
+
- Fingerprint / Face (Android) via BiometricPrompt
|
|
295
|
+
- Always provide fallback (PIN, password)
|
|
296
|
+
- Store sensitive data in Keychain (iOS) / Keystore (Android)
|
|
297
|
+
|
|
298
|
+
### Permissions
|
|
299
|
+
- Request at time of use, not on launch
|
|
300
|
+
- Explain why permission is needed before requesting
|
|
301
|
+
- Handle denial gracefully — degrade functionality, don't crash
|
|
302
|
+
- Check permission status before requesting again
|
|
303
|
+
|
|
304
|
+
## Offline-First Architecture
|
|
305
|
+
|
|
306
|
+
### Local Storage Options
|
|
307
|
+
| Technology | Platform | Best For |
|
|
308
|
+
|------------|----------|----------|
|
|
309
|
+
| SQLite / Room | Android | Complex relational data |
|
|
310
|
+
| Core Data / SwiftData | iOS | Apple-integrated persistence |
|
|
311
|
+
| Realm | Both | Cross-platform object database |
|
|
312
|
+
| MMKV | Both | Fast key-value storage |
|
|
313
|
+
| Hive | Flutter | Lightweight, Dart-native |
|
|
314
|
+
| AsyncStorage / MMKV | React Native | Simple key-value data |
|
|
315
|
+
|
|
316
|
+
### Sync Strategies
|
|
317
|
+
- **Optimistic sync** — Write locally, sync to server in background
|
|
318
|
+
- **Conflict resolution** — Last-write-wins, server-wins, or manual merge
|
|
319
|
+
- **Queue-based** — Queue mutations offline, replay when online
|
|
320
|
+
- **Delta sync** — Only sync changes since last sync timestamp
|
|
321
|
+
|
|
322
|
+
### Best Practices
|
|
323
|
+
- Design for offline first — assume network is unreliable
|
|
324
|
+
- Show cached data immediately, refresh in background
|
|
325
|
+
- Queue user actions when offline, sync when reconnected
|
|
326
|
+
- Visual indicators for sync status (synced, pending, conflict)
|
|
327
|
+
- Test with airplane mode and poor network conditions
|
|
328
|
+
|
|
329
|
+
## Navigation Patterns
|
|
330
|
+
|
|
331
|
+
| Pattern | Use Case | Implementation |
|
|
332
|
+
|---------|----------|----------------|
|
|
333
|
+
| Stack | Linear flows, drill-down | NavigationStack, NavHost, Stack.Navigator |
|
|
334
|
+
| Tab | Top-level sections | TabView, BottomNavigation, Tab.Navigator |
|
|
335
|
+
| Drawer | Many sections, settings | NavigationDrawer, Drawer.Navigator |
|
|
336
|
+
| Modal | Alerts, forms, detail views | .sheet, BottomSheet, Modal |
|
|
337
|
+
| Bottom Sheet | Quick actions, filters | .presentationDetents, ModalBottomSheet |
|
|
338
|
+
|
|
339
|
+
## Performance Optimization
|
|
340
|
+
|
|
341
|
+
### Render Performance
|
|
342
|
+
- Flatten view hierarchy — avoid deeply nested layouts
|
|
343
|
+
- Use lazy lists — `LazyColumn`, `FlatList`, `ListView.builder()`
|
|
344
|
+
- Minimize re-renders — memoize, use keys, const constructors
|
|
345
|
+
- Avoid overdraw — don't stack opaque views unnecessarily
|
|
346
|
+
|
|
347
|
+
### Startup Performance
|
|
348
|
+
- Reduce initial bundle size — code splitting, lazy module loading
|
|
349
|
+
- Defer non-critical initialization — load after first frame
|
|
350
|
+
- Use splash screen — iOS Launch Storyboard, Android SplashScreen API
|
|
351
|
+
- Profile startup — Xcode Instruments, Android Profiler, Flipper
|
|
352
|
+
|
|
353
|
+
### Memory Management
|
|
354
|
+
- Profile with Xcode Instruments (iOS) or Android Profiler
|
|
355
|
+
- Watch for retain cycles (iOS) — use `[weak self]` in closures
|
|
356
|
+
- Release large resources (images, video) when not visible
|
|
357
|
+
- Use image caching libraries — SDWebImage, Coil, cached_network_image
|
|
358
|
+
|
|
359
|
+
## Platform Design Guidelines
|
|
360
|
+
|
|
361
|
+
### Apple Human Interface Guidelines (iOS)
|
|
362
|
+
- Tab bar for top-level navigation (max 5 tabs)
|
|
363
|
+
- Large titles in navigation bars
|
|
364
|
+
- SF Symbols for icons
|
|
365
|
+
- Haptic feedback for meaningful interactions
|
|
366
|
+
- Respect Dynamic Type (accessibility text sizing)
|
|
367
|
+
|
|
368
|
+
### Material Design 3 (Android)
|
|
369
|
+
- Navigation bar (bottom) or navigation rail (tablet)
|
|
370
|
+
- Material You — dynamic color from wallpaper
|
|
371
|
+
- Top app bars with scroll behavior
|
|
372
|
+
- FAB (Floating Action Button) for primary actions
|
|
373
|
+
- Predictive back gesture support
|
|
374
|
+
|
|
375
|
+
## App Distribution
|
|
376
|
+
|
|
377
|
+
### iOS
|
|
378
|
+
- **TestFlight** — Beta testing (up to 10,000 testers)
|
|
379
|
+
- **App Store** — Public distribution (Apple review required)
|
|
380
|
+
- **Enterprise** — In-house distribution with Enterprise certificate
|
|
381
|
+
- **Ad Hoc** — Direct install for up to 100 registered devices
|
|
382
|
+
|
|
383
|
+
### Android
|
|
384
|
+
- **Google Play** — Public distribution (review process)
|
|
385
|
+
- **Google Play Internal Testing** — Fast iteration, no review
|
|
386
|
+
- **Firebase App Distribution** — Beta testing
|
|
387
|
+
- **APK / AAB sideloading** — Direct install (requires opt-in)
|
|
388
|
+
|
|
389
|
+
### CI/CD for Mobile
|
|
390
|
+
- **Fastlane** — Automate screenshots, builds, signing, deployment
|
|
391
|
+
- **EAS Build** (Expo) — Cloud builds for React Native
|
|
392
|
+
- **Codemagic** — CI/CD for Flutter
|
|
393
|
+
- **Xcode Cloud** — Apple's native CI/CD
|
|
394
|
+
- **GitHub Actions** — Universal CI with mobile-specific actions
|
|
395
|
+
|
|
396
|
+
## Technology Recommendations
|
|
397
|
+
|
|
398
|
+
### By Use Case
|
|
399
|
+
| Use Case | Recommended Stack |
|
|
400
|
+
|----------|-------------------|
|
|
401
|
+
| Startup, both platforms | React Native (Expo) + Zustand + TanStack Query |
|
|
402
|
+
| Custom UI, both platforms | Flutter + Riverpod + go_router |
|
|
403
|
+
| iOS-only app | SwiftUI + Combine + async/await |
|
|
404
|
+
| Android-only app | Kotlin + Jetpack Compose + Hilt + Room |
|
|
405
|
+
| Web app → Mobile | Capacitor + existing web frontend |
|
|
406
|
+
| Shared logic, native UI | Kotlin Multiplatform + SwiftUI/Compose |
|
|
407
|
+
| Enterprise, internal | React Native (Expo) or Flutter |
|