mobile-best-practices 1.0.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/README.md +64 -0
- package/assets/data/anti-patterns.csv +114 -0
- package/assets/data/architectures.csv +50 -0
- package/assets/data/code-snippets.csv +80 -0
- package/assets/data/gradle-deps.csv +79 -0
- package/assets/data/libraries.csv +102 -0
- package/assets/data/performance.csv +229 -0
- package/assets/data/platforms/android.csv +247 -0
- package/assets/data/platforms/flutter.csv +55 -0
- package/assets/data/platforms/ios.csv +61 -0
- package/assets/data/platforms/react-native.csv +56 -0
- package/assets/data/project-templates.csv +19 -0
- package/assets/data/reasoning-rules.csv +57 -0
- package/assets/data/security.csv +438 -0
- package/assets/data/testing.csv +74 -0
- package/assets/data/ui-patterns.csv +92 -0
- package/assets/references/CHECKLIST.md +49 -0
- package/assets/references/CODE-RULES.md +123 -0
- package/assets/scripts/__pycache__/core.cpython-314.pyc +0 -0
- package/assets/scripts/core.py +432 -0
- package/assets/scripts/search.py +104 -0
- package/assets/skills/all.md +245 -0
- package/assets/skills/android.md +168 -0
- package/assets/skills/flutter.md +153 -0
- package/assets/skills/ios.md +149 -0
- package/assets/skills/react-native.md +154 -0
- package/assets/templates/base/quick-reference.md +41 -0
- package/assets/templates/base/skill-content.md +60 -0
- package/assets/templates/platforms/agent.json +11 -0
- package/assets/templates/platforms/antigravity.json +13 -0
- package/assets/templates/platforms/claude.json +27 -0
- package/assets/templates/platforms/codebuddy.json +11 -0
- package/assets/templates/platforms/codex.json +11 -0
- package/assets/templates/platforms/continue.json +11 -0
- package/assets/templates/platforms/copilot.json +11 -0
- package/assets/templates/platforms/cursor.json +11 -0
- package/assets/templates/platforms/gemini.json +11 -0
- package/assets/templates/platforms/kiro.json +11 -0
- package/assets/templates/platforms/opencode.json +11 -0
- package/assets/templates/platforms/qoder.json +11 -0
- package/assets/templates/platforms/roocode.json +11 -0
- package/assets/templates/platforms/trae.json +11 -0
- package/assets/templates/platforms/windsurf.json +11 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +94 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +28 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/versions.d.ts +2 -0
- package/dist/commands/versions.d.ts.map +1 -0
- package/dist/commands/versions.js +30 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +24 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +103 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# mobile-best-practices
|
|
2
|
+
|
|
3
|
+
CLI to install Mobile Best Practices skill for AI coding assistants.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g mobile-best-practices
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cd /path/to/your/project
|
|
15
|
+
|
|
16
|
+
# Android-focused (Jetpack Compose)
|
|
17
|
+
mobile-best-practices init --ai claude --platform android
|
|
18
|
+
|
|
19
|
+
# iOS-focused (SwiftUI)
|
|
20
|
+
mobile-best-practices init --ai claude --platform ios
|
|
21
|
+
|
|
22
|
+
# Flutter-focused (Dart/BLoC)
|
|
23
|
+
mobile-best-practices init --ai cursor --platform flutter
|
|
24
|
+
|
|
25
|
+
# React Native-focused (TypeScript)
|
|
26
|
+
mobile-best-practices init --ai copilot --platform react-native
|
|
27
|
+
|
|
28
|
+
# All platforms (unified)
|
|
29
|
+
mobile-best-practices init --ai claude --platform all
|
|
30
|
+
|
|
31
|
+
# All AI assistants + Android
|
|
32
|
+
mobile-best-practices init --ai all --platform android
|
|
33
|
+
|
|
34
|
+
# Interactive mode (prompts for both)
|
|
35
|
+
mobile-best-practices init
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Commands
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
mobile-best-practices init # Install skill for your AI assistant
|
|
42
|
+
mobile-best-practices update # Check for updates
|
|
43
|
+
mobile-best-practices versions # List versions and changelog
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Platform-Specific Skills
|
|
47
|
+
|
|
48
|
+
Each platform gets a focused SKILL.md with:
|
|
49
|
+
- Platform-specific default stack and code examples
|
|
50
|
+
- Targeted search commands (auto-filters by platform)
|
|
51
|
+
- Platform-specific anti-patterns and checklist
|
|
52
|
+
- Focused code generation rules
|
|
53
|
+
|
|
54
|
+
| Platform | Default Stack |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `android` | MVVM + Hilt + Room + Retrofit + Coil + Compose + Material3 |
|
|
57
|
+
| `ios` | MVVM + SwiftUI + Combine + async/await + SwiftData + Kingfisher |
|
|
58
|
+
| `flutter` | BLoC + Dio + GoRouter + Drift + CachedNetworkImage |
|
|
59
|
+
| `react-native` | Redux Toolkit + Axios + React Navigation + MMKV + FastImage |
|
|
60
|
+
| `all` | Unified skill covering all 4 platforms |
|
|
61
|
+
|
|
62
|
+
## Supported AI Assistants
|
|
63
|
+
|
|
64
|
+
Claude Code, Cursor, Windsurf, GitHub Copilot, Kiro, Codex CLI, Gemini CLI, Roo Code, Continue, OpenCode, Qoder, CodeBuddy, Trae, Antigravity
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Name,Platform,Category,Severity,Keywords,Description,Bad Example,Good Example,Why Bad,Fix,Reference URL
|
|
2
|
+
God Activity,Android,Architecture,Critical,god activity massive class monolith,Activity with 1000+ lines handling UI business logic and data,class MainActivity { fun fetchData() { db.query() } fun updateUI() },Split into ViewModel + Repository + Composable screens,Violates SRP unmaintainable untestable,Extract ViewModel for logic Repository for data,https://developer.android.com/topic/architecture
|
|
3
|
+
Massive ViewController,iOS,Architecture,Critical,massive viewcontroller mvc god class,ViewController handling all responsibilities,class HomeVC { func callAPI() func parseJSON() func updateUI() },Use MVVM-C with separate ViewModel and Coordinator,Untestable unmaintainable violates SRP,Extract ViewModel Coordinator for navigation,https://developer.apple.com/documentation/swiftui
|
|
4
|
+
Business Logic in Widget,Flutter,Architecture,High,logic widget bloc provider build,Business logic directly in widget build method,Widget build() { final data = http.get(...); return Text(data); },Use BLoC or Provider for business logic separation,Tight coupling impossible to test re-fetches on rebuild,Move logic to BLoC/Cubit inject via BlocProvider,https://bloclibrary.dev/
|
|
5
|
+
Prop Drilling,React Native,Architecture,High,prop drilling passing props deep nesting,Passing props through many component layers,<A data={d}><B data={d}><C data={d}><D data={d}/></C></B></A>,Use Context or state management library,Makes refactoring painful components tightly coupled,Use React Context or Zustand/Redux for shared state,https://react.dev/learn/passing-data-deeply-with-context
|
|
6
|
+
Circular Dependencies,All,Architecture,High,circular dependency import cycle module,Module A depends on B depends on A,moduleA imports moduleB; moduleB imports moduleA,Use dependency inversion interface abstraction,Build failures unclear ownership infinite loops,Introduce interface in shared module,
|
|
7
|
+
Skip Layers in Clean Arch,All,Architecture,Medium,skip layer clean architecture shortcut domain,Presentation layer directly accessing data layer,ViewModel calls Repository bypassing UseCase,Always go through domain layer UseCases,Defeats purpose of clean architecture hard to test,Create UseCase for each business operation,https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
|
|
8
|
+
Singleton Abuse,All,Architecture,Medium,singleton global state shared instance anti,Using singletons for everything,object AppState { var user; var cart; var settings },Use proper DI with Hilt/Koin/Swinject,Hidden dependencies hard to test race conditions,Use dependency injection framework,
|
|
9
|
+
No Dependency Injection,All,Architecture,High,no di manual instantiation tight coupling,Creating dependencies manually inside classes,class MyVM { val repo = UserRepository(ApiService()) },Use Hilt Koin Swinject or manual constructor DI,Tight coupling impossible to mock or test,Inject dependencies via constructor,https://developer.android.com/training/dependency-injection
|
|
10
|
+
Anemic Domain Model,All,Architecture,Medium,anemic domain model no logic data class,Domain models with only data no behavior,data class User(val name: String) // all logic in service,Add domain logic to models: User.isValid() User.fullName,Domain logic scattered across services,Put behavior with the data it operates on,
|
|
11
|
+
Feature Envy,All,Architecture,Medium,feature envy wrong class responsibility,Class heavily uses another class methods/data,class OrderService { fun calc(cart: Cart) = cart.items.sumOf { it.price } },Move calculation logic to Cart class,Wrong responsibility assignment tight coupling,Move method to class whose data it uses most,
|
|
12
|
+
setState Everywhere,Flutter,State,High,setstate everywhere rebuild widget state,Using setState for all state management,setState(() { _items = await api.fetchItems(); _loading = false; }),Use BLoC Cubit or Riverpod,Unnecessary rebuilds poor separation unmaintainable,Adopt proper state management solution,https://bloclibrary.dev/
|
|
13
|
+
Mutable Shared State,All,State,Critical,mutable shared state race condition thread,Sharing mutable state across threads/isolates,var sharedList = mutableListOf<Item>() // multiple coroutines,Use StateFlow/LiveData or immutable state,Race conditions crashes unpredictable behavior,Use immutable state + state management pattern,
|
|
14
|
+
Re-render Hell,React Native,State,High,rerender performance usememo usecallback memo,Unnecessary re-renders from poor state management,const App = () => { const [count setCount] = useState(0); return <ExpensiveList /> },Use React.memo useMemo useCallback properly,Jank dropped frames battery drain,Memoize expensive components and callbacks,https://react.dev/reference/react/memo
|
|
15
|
+
State in Wrong Place,All,State,Medium,state wrong scope local global misplaced,Putting local state in global store or vice versa,Redux store: { modalOpen: false buttonHover: false },Keep UI state local share only what needs sharing,Unnecessary complexity and re-renders,Local state for UI global for shared business data,
|
|
16
|
+
No Single Source of Truth,All,State,High,duplicate state sync inconsistent ssot,Same data stored in multiple places,var cachedUser in VM; var savedUser in Repo; var displayUser in UI,Single source of truth with reactive streams,Data gets out of sync inconsistent UI,Use Room/CoreData as SSOT observe with Flow/Combine,https://developer.android.com/topic/architecture/data-layer
|
|
17
|
+
Direct State Mutation,All,State,High,direct mutation state modify side effects,Modifying state objects directly,_state.items.add(newItem); notifyListeners(),_state = _state.copyWith(items: [..._state.items newItem]),Side effects lost change history broken equality,Always create new state objects via copy/copyWith,
|
|
18
|
+
Missing Error State,All,State,High,no error handling state loading empty,Not handling loading error and empty states,if (data != null) showData(data),sealed class UiState { Loading Success Error Empty },Users see blank screen on error no feedback,Use sealed class/enum for all possible UI states,
|
|
19
|
+
Storing Derived State,All,State,Medium,derived computed state redundant duplicate,Storing values that can be computed,var items; var filteredItems; var itemCount,Compute filteredItems and count from items,State sync issues stale data extra storage,Use computed properties or selectors,
|
|
20
|
+
Blocking Main Thread,All,UI,Critical,main thread ui anr freeze jank block,Doing heavy work on the main/UI thread,fun onCreate() { val data = database.queryAll() },Use coroutines/async with Dispatchers.IO,ANR dialog frozen UI dropped frames,Move heavy work to background thread/coroutine,https://developer.android.com/kotlin/coroutines
|
|
21
|
+
Hardcoded Strings,All,UI,Medium,hardcoded string i18n localization resource,Hardcoding user-facing strings in code,"Text(""Welcome back!"")",Text(stringResource(R.string.welcome_back)),Cannot localize accessibility issues,Use string resources for all user-facing text,https://developer.android.com/guide/topics/resources/string-resource
|
|
22
|
+
Hardcoded Colors,All,UI,Medium,hardcoded color hex theme design system,Using hex colors directly instead of theme,Box(modifier = Modifier.background(Color(0xFF2196F3))),Box(modifier = Modifier.background(MaterialTheme.colorScheme.primary)),No dark mode support inconsistent theming,Use theme system colors,https://developer.android.com/develop/ui/compose/designsystems/material3
|
|
23
|
+
Nested Scrolling Conflict,All,UI,High,nested scroll recyclerview scrollview conflict jank,ScrollView inside ScrollView without coordination,ScrollView { RecyclerView { } },Use NestedScrollView or single LazyColumn,Janky scroll stolen gestures broken UX,Use single scrollable container,https://developer.android.com/develop/ui/compose/lists
|
|
24
|
+
Missing Loading States,All,UI,High,no loading state blank screen async,Not showing loading indicators,if (data != null) show(data) // nothing while loading,Show skeleton/shimmer while loading,Users think app is broken,Always show loading feedback for async operations,
|
|
25
|
+
Layout Shift on Load,All,UI,Medium,layout shift cls jump content pop,Content jumping when images/data loads,Image loads and pushes text down,Reserve space with fixed aspect ratio or placeholder,Disorienting UX accidental taps,Use fixed dimensions or aspect ratio containers,
|
|
26
|
+
Ignoring Safe Area,All,UI,High,safe area notch cutout inset system bars,Content behind notch or system bars,Content goes behind status bar,Respect safe area insets on all edges,Content hidden behind system UI,Use SafeArea/safeAreaInset/WindowInsets,https://developer.android.com/develop/ui/compose/layouts/insets
|
|
27
|
+
No Image Caching,All,Performance,High,image cache memory network reload bandwidth,Loading images from network every time,Image.network(url) // no caching,CachedNetworkImage(imageUrl: url placeholder: shimmer),Wasted bandwidth slow loading,Use Coil/Glide/Kingfisher/CachedNetworkImage,
|
|
28
|
+
Memory Leak in Callback,All,Memory,Critical,memory leak callback listener retain register,Registering listeners without cleanup,onStart() { EventBus.register(this) } // never unregistered,Unregister in onStop/dispose/cleanup,Memory grows app crashes OOM,Always unregister in corresponding lifecycle method,
|
|
29
|
+
Unnecessary Recomposition,Android,Performance,High,recomposition compose unstable lambda key,Compose recomposing when it should not,LazyColumn { items(list) { Button(onClick = { doSomething(it) }) } },Use remember/derivedStateOf stable lambdas and keys,Wasted CPU jank poor battery life,Use key parameter stable lambdas Immutable annotations,https://developer.android.com/develop/ui/compose/performance
|
|
30
|
+
Large Bundle Size,React Native,Performance,Medium,bundle size hermes ram assets tree shake,App bundle too large,import _ from 'lodash' // entire library,import debounce from 'lodash/debounce',Slow download slow install,Tree-shake imports enable Hermes optimize assets,https://reactnative.dev/docs/hermes
|
|
31
|
+
No Pagination,All,Performance,High,no pagination load all memory oom list,Loading entire dataset at once,val allItems = api.getAllItems() // 10000 items,Use Paging3/pagination load 20 at a time,OOM crash slow response,Implement cursor/offset pagination,https://developer.android.com/topic/libraries/architecture/paging/v3-overview
|
|
32
|
+
Synchronous Network Call,All,Performance,Critical,synchronous network main thread block anr,Making network calls on main thread,val response = URL(apiUrl).readText() // blocks,withContext(Dispatchers.IO) { api.fetch() },ANR frozen UI app killed by system,Always use async/await coroutines or callbacks,https://developer.android.com/kotlin/coroutines
|
|
33
|
+
Widget Rebuild Storm,Flutter,Performance,High,widget rebuild unnecessary build frequent,Entire widget tree rebuilding on minor change,setState(() { _title = newTitle; }) // rebuilds everything,Use BLoC/Consumer/Selector to scope rebuilds,Poor performance janky scrolling,Scope rebuilds to affected widgets only,https://docs.flutter.dev/perf/best-practices
|
|
34
|
+
Not Handling Lifecycle,Android,Lifecycle,Critical,lifecycle activity fragment destroy recreate rotation,Not handling config changes and lifecycle,Store data in Activity fields lost on rotation,Use ViewModel to survive configuration changes,Data loss on rotation crash on backgrounding,Use ViewModel + SavedStateHandle,https://developer.android.com/topic/libraries/architecture/viewmodel
|
|
35
|
+
Retain Cycle,iOS,Memory,Critical,retain cycle strong reference memory leak arc closure,Strong reference cycle between objects,closure = { self.doWork() } // strong capture,Use [weak self] or [unowned self] in closures,Memory never freed app memory grows,Use [weak self] in closures that capture self,https://docs.swift.org/swift-book/documentation/the-swift-programming-language/automaticreferencecounting/
|
|
36
|
+
Not Disposing Controllers,Flutter,Lifecycle,High,dispose controller textediting animation scroll leak,Not calling dispose on controllers,final ctrl = TextEditingController(); // no dispose,@override void dispose() { ctrl.dispose(); super.dispose(); },Memory leak resource leak potential crashes,Override dispose() clean up all controllers,https://api.flutter.dev/flutter/widgets/State/dispose.html
|
|
37
|
+
Missing Cleanup in useEffect,React Native,Lifecycle,High,useeffect cleanup subscription listener return,useEffect without cleanup function,useEffect(() => { socket.connect(); }),useEffect(() => { socket.connect(); return () => socket.disconnect(); }),Memory leak zombie listeners stale callbacks,Always return cleanup function from useEffect,https://react.dev/reference/react/useEffect
|
|
38
|
+
Ignoring App Lifecycle,All,Lifecycle,Medium,background foreground app lifecycle pause resume,Not handling app going to background/foreground,Keep timers and connections running in background,Pause work on background resume on foreground,Battery drain wasted resources,Use LifecycleObserver/AppDelegate/WidgetsBindingObserver,https://developer.android.com/guide/components/activities/activity-lifecycle
|
|
39
|
+
Deep Nesting Navigation,All,Navigation,Medium,deep nesting navigation back stack levels,Deeply nested navigation stacks 6+ levels,Screen A -> B -> C -> D -> E -> F,Use flat navigation with tabs max 3-4 levels,Confusing UX user gets lost,Flatten navigation use tabs or modal for side flows,
|
|
40
|
+
No Deep Link Support,All,Navigation,Medium,deep link universal link app link url,App has no deep linking support,Only navigate via taps inside the app,Support deep links for all major screens,Cannot share content poor marketing,Implement deep linking from the start,https://developer.android.com/training/app-links
|
|
41
|
+
Losing Navigation State,All,Navigation,High,navigation state lost backstack destroy death,Navigation state lost on process death,Navigate back and screens are blank,Save and restore navigation state,Users lose their place,Use SavedStateHandle/StateRestoration,https://developer.android.com/topic/libraries/architecture/saving-states
|
|
42
|
+
Hard-coded Routes,All,Navigation,Medium,hardcoded route string navigation typo,Using raw strings for navigation routes,navigator.push('/home/profile/123'),Use typed routes or route constants with type safety,Typo-prone no compile-time safety,Use type-safe navigation,https://developer.android.com/guide/navigation/design/type-safety
|
|
43
|
+
No Back Handler,Android,Navigation,High,back handler predictive back gesture exit,Not handling system back properly,System back closes app from any screen,Use BackHandler or predictive back API,Users accidentally exit app,Handle back press with confirmation,https://developer.android.com/develop/ui/views/touch-and-input/gestures/predictive-back
|
|
44
|
+
No Offline Support,All,Network,Medium,offline cache first network connection,App completely unusable without network,if (!isConnected) showError('No internet'),Cache data locally show cached + sync online,Unusable on poor connection,Implement offline-first with local cache,
|
|
45
|
+
No Request Retry,All,Network,Medium,retry exponential backoff network failure,No retry logic for failed requests,val response = api.getData() // fails once gives up,Implement exponential backoff retry max 3 attempts,Transient failures shown as errors,Add retry with exponential backoff,
|
|
46
|
+
Ignoring HTTP Errors,All,Network,High,http error status code ignore 4xx 5xx,Not handling non-200 HTTP status codes,val data = response.body() // assumes always 200,Check status code handle 4xx and 5xx properly,Silent failures corrupted data,Handle all HTTP status codes,
|
|
47
|
+
No Request Cancellation,All,Network,Medium,cancel request dispose viewmodel navigate away,Not cancelling requests when leaving screen,API calls continue after user navigates away,Cancel requests in onCleared/dispose/cleanup,Wasted resources updating destroyed UI,Tie request lifecycle to screen lifecycle,
|
|
48
|
+
Trusting Server Data,All,Network,High,trust server validation input sanitize null,Blindly trusting all data from server,val name = response.name!!; textView.text = name,Validate and sanitize all server responses,Crashes on null/malformed data,Validate all fields handle missing data,
|
|
49
|
+
No Unit Tests,All,Testing,High,no tests unit test coverage regression,No automated tests in the project,Ship code without any tests,Write unit tests for ViewModels repositories logic,Regression bugs fear of refactoring,Start with ViewModel/BLoC tests then expand,https://developer.android.com/training/testing
|
|
50
|
+
Hardcoded API Keys,All,Security,Critical,api key hardcoded secret exposed source,API keys committed to source code,const val API_KEY = 'sk-abc123...',Use BuildConfig/xcconfig/env vars and .gitignore,Keys exposed in decompiled APK/IPA,Store in local.properties/xcconfig never commit,https://owasp.org/www-project-mobile-top-10/
|
|
51
|
+
No SSL Pinning,All,Security,High,ssl pinning certificate mitm attack,No certificate pinning for API calls,OkHttpClient() // trusts any valid cert,Implement certificate/public key pinning,Man-in-the-middle attacks,Pin server certificate or public key,https://developer.android.com/privacy-and-security/security-config#CertificatePinning
|
|
52
|
+
Storing Sensitive in Prefs,All,Security,Critical,sharedpreferences userdefaults plaintext sensitive token,Storing tokens/passwords in plain preferences,SharedPreferences.putString('token' jwt),Use EncryptedSharedPreferences/Keychain/flutter_secure_storage,Tokens readable by rooted device,Use platform secure storage,https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences
|
|
53
|
+
No Input Validation,All,Security,High,input validation xss injection sanitize,Not validating user input,textView.text = userInput // direct usage,Validate sanitize and escape all user inputs,XSS injection SQL injection crashes,Validate format length content of all inputs,
|
|
54
|
+
No ProGuard R8,Android,Security,Medium,proguard r8 obfuscation minify shrink,Not enabling code shrinking,minifyEnabled false // in build.gradle,minifyEnabled true with proper proguard-rules.pro,Larger APK reverse engineering easy,Enable R8 with proper keep rules,https://developer.android.com/build/shrink-code
|
|
55
|
+
Logging Sensitive Data,All,Security,High,log sensitive password token pii debug production,Logging passwords tokens or PII,Log.d(TAG 'User token: $token'),Never log sensitive data use redaction in production,Credentials leaked via logs,Strip debug logs in release configure log levels,
|
|
56
|
+
Composable Side Effects,Android,Compose,Critical,compose side effect launched disposable remember coroutine,Running side effects directly in composable body without LaunchedEffect,@Composable fun Screen() { api.fetchData() // runs on every recomposition },@Composable fun Screen() { LaunchedEffect(Unit) { api.fetchData() } },Runs on every recomposition; infinite network calls; crashes,Use LaunchedEffect DisposableEffect or rememberCoroutineScope,https://developer.android.com/develop/ui/compose/side-effects
|
|
57
|
+
State Hoisting Failure,Android,Compose,High,compose state hoisting remember mutablestateof local,Keeping state local in child composable instead of hoisting to parent,@Composable fun Search() { var query by remember { mutableStateOf('') } },@Composable fun Search(query: String onQueryChange: (String) -> Unit),Parent cannot observe or control child state; breaks unidirectional flow,Hoist state to lowest common ancestor; pass state down events up,https://developer.android.com/develop/ui/compose/state#state-hoisting
|
|
58
|
+
Remember with Wrong Key,Android,Compose,High,compose remember key recomposition stale cache invalidate,Using remember without keys causing stale cached values,val data = remember { expensiveCompute(input) } // stale when input changes,val data = remember(input) { expensiveCompute(input) } // recomputes on change,Cached value never updates when inputs change; shows stale data,Pass keys to remember that trigger recomputation,https://developer.android.com/develop/ui/compose/side-effects#remember
|
|
59
|
+
derivedStateOf Misuse,Android,Compose,Medium,compose derivedstateof unnecessary overhead recomposition filter,Using derivedStateOf for values that change with every state change,val text = remember { derivedStateOf { input.value } } // unnecessary,val filteredList = remember { derivedStateOf { list.filter { it.isActive } } },derivedStateOf adds overhead; only useful when result changes less often than input,Use derivedStateOf only when output changes less frequently than input,https://developer.android.com/develop/ui/compose/side-effects#derivedstateof
|
|
60
|
+
Unstable Lambda in Compose,Android,Compose,High,compose lambda recomposition unstable capture remember callback,Passing unstable lambdas causing unnecessary recompositions,LazyColumn { items(list) { Button(onClick = { viewModel.select(it) }) } },val onSelect = remember { { item: Item -> viewModel.select(item) } },Unstable lambda prevents skipping recomposition of items; janky scrolling,Use remember for lambdas or enable Strong Skipping Mode,https://developer.android.com/develop/ui/compose/performance/stability
|
|
61
|
+
GlobalScope Coroutine,Android,Coroutine,Critical,globalscope coroutine launch leak lifecycle cancel fire forget,Using GlobalScope instead of viewModelScope or lifecycleScope,GlobalScope.launch { api.fetchData() },viewModelScope.launch { api.fetchData() },Never cancelled; outlives component; memory leak; ignores lifecycle,Use viewModelScope lifecycleScope or custom CoroutineScope,https://developer.android.com/kotlin/coroutines/coroutines-best-practices
|
|
62
|
+
runBlocking on Main,Android,Coroutine,Critical,runblocking main thread anr block coroutine bridge,Using runBlocking on Main thread to bridge sync and async code,fun getData() = runBlocking { api.fetch() } // blocks main thread,suspend fun getData() = api.fetch() // or use viewModelScope.launch,ANR after 5 seconds; frozen UI; app killed by system,Never use runBlocking on main; use suspend functions or launch,https://developer.android.com/kotlin/coroutines/coroutines-best-practices
|
|
63
|
+
Collecting Flow in ViewModel init,Android,Coroutine,High,flow collect init viewmodel launch stateflow repeatonlifecycle,Collecting Flow in ViewModel init without proper scoping,init { viewModelScope.launch { repo.data.collect { _state.value = it } } },val state = repo.data.stateIn(viewModelScope SharingStarted.WhileSubscribed(5000) initial),Flow collected even when UI not visible; wasted resources,Use stateIn with WhileSubscribed for lifecycle-aware collection,https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
|
|
64
|
+
Not Using repeatOnLifecycle,Android,Lifecycle,High,repeatonlifecycle flow collect lifecycle started activity fragment,Collecting Flow in Activity/Fragment without lifecycle awareness,lifecycleScope.launch { viewModel.state.collect { updateUI(it) } },lifecycleScope.launch { repeatOnLifecycle(STARTED) { viewModel.state.collect { updateUI(it) } } },Collects in background wasting resources; potential crashes on destroyed views,Use repeatOnLifecycle or collectAsStateWithLifecycle in Compose,https://developer.android.com/topic/libraries/architecture/coroutines#lifecycle-aware
|
|
65
|
+
ViewModel Factory Boilerplate,Android,Architecture,Medium,viewmodel factory provider deprecated assistedinject creationextras,Writing manual ViewModel factory instead of using Hilt or CreationExtras,class MyVMFactory(val repo: Repo) : ViewModelProvider.Factory { override fun <T> create() },@HiltViewModel class MyVM @Inject constructor(val repo: Repo) : ViewModel(),Unnecessary boilerplate; error-prone; manual dependency wiring,Use @HiltViewModel or CreationExtras (AGP 2.5+),https://developer.android.com/training/dependency-injection/hilt-android
|
|
66
|
+
Hilt Missing EntryPoint,Android,DI,High,hilt entrypoint inject contentprovider broadcastreceiver workmanager,Not using @EntryPoint for non-standard Hilt injection targets,class MyReceiver : BroadcastReceiver() { val repo = UserRepository() // manual },@AndroidEntryPoint class MyReceiver : BroadcastReceiver() @Inject lateinit var repo: Repo,Manual instantiation; missing initialization; test-unfriendly,Use @EntryPoint for WorkManager ContentProvider BroadcastReceiver,https://developer.android.com/training/dependency-injection/hilt-android#not-supported
|
|
67
|
+
Exposing MutableStateFlow,Android,State,High,mutablestateflow expose public private backing field viewmodel,Exposing MutableStateFlow publicly from ViewModel,val state = MutableStateFlow(Initial) // public mutable,private val _state = MutableStateFlow(Initial); val state: StateFlow<X> = _state.asStateFlow(),Views can modify ViewModel state directly; breaks UDF,Use private MutableStateFlow with public StateFlow accessor,https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
|
|
68
|
+
SwiftUI Body Heavy Computation,iOS,SwiftUI,High,swiftui body computed property heavy performance view,Doing expensive work in SwiftUI body property,var body: some View { let filtered = items.filter { expensive($0) }; List(filtered) },@State private var filtered = []; func updateFilter() { filtered = items.filter { } },Body runs on every re-render; expensive filter runs repeatedly,Compute in onChange or task; cache results in @State,https://developer.apple.com/documentation/swiftui
|
|
69
|
+
ObservableObject Over-Publishing,iOS,SwiftUI,High,observableobject published objectwillchange unnecessary rerender,Too many @Published properties causing unnecessary view updates,class VM: ObservableObject { @Published var a; @Published var b; @Published var c },Use @Observable macro (iOS 17+) for granular tracking,Every @Published change triggers all observing views to re-render,Use @Observable or split into multiple ObservableObjects,https://developer.apple.com/documentation/observation/observable()
|
|
70
|
+
Force Unwrapping Optionals,iOS,Swift,Critical,force unwrap optional bang crash nil unexpected,Using ! to force unwrap optionals that might be nil,let name = user.name! // crashes if nil,guard let name = user.name else { return },Runtime crash if value is nil; common source of production crashes,Use guard let if let or ?? with defaults,https://docs.swift.org/swift-book/documentation/the-swift-programming-language/optionalchaining/
|
|
71
|
+
setState with API Call,Flutter,State,High,setstate api call network widget build futurebuilder,Calling API directly in widget with setState for result,setState(() { data = await api.fetch(); }) // in initState,Use BLoC/Riverpod/FutureBuilder for async data,Mixed concerns; can't test; race conditions on rapid rebuilds,Separate data fetching from UI using state management,https://docs.flutter.dev/data-and-backend/state-mgmt/options
|
|
72
|
+
BuildContext Across Async Gap,Flutter,Architecture,Critical,buildcontext async gap mounted scaffold navigator context,Using BuildContext after await when widget might be unmounted,await api.fetch(); ScaffoldMessenger.of(context).showSnackBar(snack),if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar(snack),Widget may be unmounted; context invalid; crash or wrong behavior,Check mounted before using context after await,https://dart.dev/tools/linter-rules/use_build_context_synchronously
|
|
73
|
+
Provider Without Select,Flutter,Performance,Medium,provider select watch read consumer unnecessary rebuild,Using context.watch when only one field needed causing full rebuilds,final state = context.watch<AppState>(); // rebuilds on any change,final name = context.select<AppState String>((s) => s.name);,Entire widget rebuilds when any AppState field changes,Use select to pick specific fields; minimizes rebuilds,https://pub.dev/packages/provider
|
|
74
|
+
Inline Styles in RN,React Native,UI,Medium,inline style stylesheet create performance object allocation,Creating style objects inline in render causing re-allocation,<View style={{flex: 1 backgroundColor: 'red'}} />,<View style={styles.container} />; const styles = StyleSheet.create({container: {flex: 1}}),New object allocated every render; breaks PureComponent memo,Use StyleSheet.create outside component,https://reactnative.dev/docs/stylesheet
|
|
75
|
+
Console.log in Production,React Native,Performance,Medium,console log production performance bridge debug remove strip,Leaving console.log statements in production build,console.log('user data:' JSON.stringify(userObject)),if (__DEV__) console.log('debug info'); // or use babel-plugin-transform-remove-console,Serialization overhead; sensitive data exposure; bridge congestion,Use babel plugin to strip console in production,https://reactnative.dev/docs/performance
|
|
76
|
+
Uncontrolled re-renders in List,React Native,Performance,High,flatlist rerender key extractor item separator optimization,FlatList items re-rendering on every state change,<FlatList data={items} renderItem={({item}) => <Item data={item} store={entireStore} />} />,<FlatList data={items} renderItem={renderItem} keyExtractor={keyExtractor} getItemLayout={getItemLayout} />,Entire list re-renders; dropped frames; janky scrolling,Use React.memo keyExtractor getItemLayout; minimize item props,https://reactnative.dev/docs/flatlist
|
|
77
|
+
Async Storage for Sensitive Data,React Native,Security,Critical,asyncstorage sensitive token password plaintext unencrypted,Storing tokens or passwords in AsyncStorage (unencrypted),await AsyncStorage.setItem('token' jwtToken),await Keychain.setGenericPassword('user' token {service: 'auth'}),AsyncStorage is plaintext; readable on rooted devices,Use react-native-keychain for sensitive data,https://github.com/oblador/react-native-keychain
|
|
78
|
+
Platform Channel in Hot Path,Flutter,Performance,High,platform channel method invocation hot path loop frequent native,Calling platform channels in loops or animations,for (item in items) { await methodChannel.invokeMethod('process' item); },final results = await methodChannel.invokeMethod('processBatch' items);,Each call has ~0.5ms overhead; 100 calls = 50ms; jank during animation,Batch platform channel calls; use Pigeon for type-safe interface,https://docs.flutter.dev/platform-integration/platform-channels
|
|
79
|
+
No Error Boundary,React Native,Architecture,High,error boundary crash fallback react native component tree,No error boundaries causing entire app crash on JS error,// No ErrorBoundary; one component crash takes down entire app,class ErrorBoundary extends React.Component { static getDerivedStateFromError(e) { return {hasError: true} } },Single component error crashes entire React tree,Wrap screen-level and critical components in ErrorBoundary,https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary
|
|
80
|
+
Magic Numbers,All,Code Quality,Medium,magic number constant named value meaning readability,Using unexplained numeric literals in code,if (retryCount > 3) { delay(2000) },if (retryCount > MAX_RETRIES) { delay(RETRY_DELAY_MS) },Unclear intent; hard to change; scattered duplicate values,Extract to named constants with descriptive names,
|
|
81
|
+
Magic Numbers,All,Clean Code,Medium,magic number constant named hardcoded value readability,Hardcoded numeric values with no explanation scattered through code,if (retryCount > 3) { delay(5000) },companion object { const val MAX_RETRIES = 3; const val RETRY_DELAY_MS = 5000L }; if (retryCount > MAX_RETRIES) delay(RETRY_DELAY_MS),Unreadable; changing value requires finding all instances; no context for why 3 or 5000,Extract to named constants with meaningful names,https://developer.android.com/kotlin/style-guide
|
|
82
|
+
God ViewModel,Android,Clean Code,Critical,god viewmodel massive 1000 lines srp single responsibility bloated,ViewModel handling 10+ responsibilities: auth + navigation + analytics + UI state + validation + caching,class CheckoutViewModel { fun processPayment(); fun validateCard(); fun applyDiscount(); fun updateCart(); fun loadAddress(); fun trackEvent(); fun refreshUser() },Split: CartViewModel + PaymentViewModel + AddressViewModel; Use UseCases for business logic,Untestable; impossible to reason about; merge conflict magnet; 1500+ lines,Extract UseCases; split by screen/feature; ViewModel orchestrates not implements,https://developer.android.com/topic/architecture/ui-layer
|
|
83
|
+
Primitive Obsession,All,Clean Code,Medium,primitive obsession string int type safety wrapper value class,Using raw String/Int where domain types provide safety,fun processOrder(orderId: String customerId: String productId: String amount: Int),@JvmInline value class OrderId(val value: String); @JvmInline value class CustomerId(val value: String); fun processOrder(orderId: OrderId customerId: CustomerId),Easy to swap orderId and customerId accidentally; no compile-time safety; bugs at runtime,Use Kotlin value classes or typealiases for domain primitives,https://kotlinlang.org/docs/inline-classes.html
|
|
84
|
+
Callback Hell,All,Clean Code,High,callback hell nested pyramid async completion handler indentation,Deeply nested callbacks making code unreadable and error-prone,api.login { user -> api.getProfile(user.id) { profile -> api.getOrders(profile.id) { orders -> updateUI(orders) } } },val user = api.login(); val profile = api.getProfile(user.id); val orders = api.getOrders(profile.id); updateUI(orders) // suspend functions,Pyramid of doom; error handling at each level; impossible to follow flow; can't cancel,Use suspend functions (Kotlin); async/await (Swift/JS); or Flow/Combine,https://developer.android.com/kotlin/coroutines
|
|
85
|
+
Stringly Typed APIs,All,Clean Code,Medium,string typed enum sealed navigation route key preference magic string,Using raw strings as identifiers instead of enums or sealed types,"navController.navigate(""detail/123""); prefs.getString(""theme""); when (status) { ""loading"" -> ...","@Serializable data class DetailRoute(val id: String); navController.navigate(DetailRoute(""123"")); enum class Theme { LIGHT DARK }",Typos cause runtime crashes; no refactoring safety; no exhaustive when; find-and-replace breaks,Use enums sealed interfaces or @Serializable data classes for type safety,https://developer.android.com/guide/navigation/design/type-safety
|
|
86
|
+
Long Parameter List,All,Clean Code,Medium,long parameter list function arguments config builder data class,Functions with 5+ parameters; hard to remember order; easy to swap arguments,fun createUser(name: String email: String age: Int city: String country: String bio: String avatar: String premium: Boolean),data class CreateUserRequest(val name: String val email: String val age: Int val city: String); fun createUser(request: CreateUserRequest),Arguments easily swapped; hard to read at call site; adding new param requires changing all callers,Group into data class or builder pattern; use named arguments in Kotlin,https://developer.android.com/kotlin/style-guide
|
|
87
|
+
Feature Envy,All,Clean Code,Medium,feature envy method class responsibility data access encapsulation,Method that uses more data from another class than its own,fun OrderViewModel.calculateTotal() { val items = cart.items; val tax = cart.taxRate; val discount = cart.discount; return items.sumOf { it.price } * (1 + tax) - discount },fun Cart.calculateTotal(): Double { return items.sumOf { it.price } * (1 + taxRate) - discount }; // Method belongs in Cart,Breaks encapsulation; changes to Cart internals require ViewModel changes; tight coupling,Move method to the class whose data it primarily uses,
|
|
88
|
+
No Error Handling Strategy,All,Maintainability,Critical,error handling strategy result either sealed exception crash production,Inconsistent error handling; mix of try-catch exceptions Result and nullable returns,fun getUser(): User = api.getUser() // Throws; fun getOrders(): List<Order>? // Nullable; fun getCart(): Result<Cart> // Result,Consistent: suspend fun getUser(): Result<User>; // Always Result; ViewModel handles fold(onSuccess onFailure),Unpredictable API surface; callers don't know what to expect; crashes in production,Adopt consistent strategy: Result<T> or sealed class or Arrow Either across entire codebase,https://developer.android.com/kotlin/coroutines/coroutines-best-practices
|
|
89
|
+
Tight Coupling to Framework,All,Maintainability,High,tight coupling framework dependency inversion testability android context,Business logic directly depending on Android framework classes,class UserRepository(private val context: Context) { fun save(user: User) { context.getSharedPreferences(...).edit().putString(user.json).apply() } },interface UserStorage { suspend fun save(user: User) }; class SharedPrefUserStorage(context: Context) : UserStorage; class UserRepository(private val storage: UserStorage),Can't unit test without Android; business logic untestable; migration impossible,Dependency inversion: depend on interfaces not implementations,https://developer.android.com/training/dependency-injection
|
|
90
|
+
Missing Mapper Layer,All,Maintainability,High,mapper dto entity domain model separation layer boundary clean,Domain models directly using API DTOs or database entities; tightly coupled,"@Entity data class User(@PrimaryKey val id: String @Json(name = ""first_name"") val firstName: String) // Used everywhere",Separate: UserDto (API) + UserEntity (DB) + User (domain); fun UserDto.toDomain() fun User.toEntity(),API change breaks UI; database schema change requires UI update; no boundary isolation,Create mapper functions at layer boundaries; domain model is source of truth,https://developer.android.com/topic/architecture/data-layer
|
|
91
|
+
No Logging Strategy,All,Maintainability,Medium,logging strategy timber debug release production strip sanitize,Inconsistent logging; Log.d everywhere; sensitive data in production logs,"Log.d(""TAG"" ""User password: $password""); Log.d(""TAG"" ""Token: $token"")","Timber.d(""Login attempt for %s"" username); // Stripped in release; no sensitive data; structured",Sensitive data leaked in production logs; inconsistent tags; no way to strip debug logs,Use Timber; configure release tree; strip debug logs with R8; never log PII,https://github.com/JakeWharton/timber
|
|
92
|
+
Hardcoded Strings in UI,All,Maintainability,Medium,hardcoded string ui localization i18n l10n translation resource,Hardcoded UI strings making localization impossible,"Text(""Welcome back!""); Button(""Submit Order"")","Text(stringResource(R.string.welcome_back)); // or LocalizedStringKey(""welcome_back"") in SwiftUI",Can't translate app; changing copy requires code change and redeploy; no RTL support,Extract all user-visible strings to resources; use string formatting for dynamic content,https://developer.android.com/guide/topics/resources/localization
|
|
93
|
+
Ignoring Code Formatting,All,Maintainability,Low,code formatting ktfmt ktlint spotless detekt lint consistent style,Inconsistent code formatting; tabs vs spaces; brace style wars; messy PRs,Mixed formatting: some files use 2-space indent others 4-space; trailing whitespace; no linting,"// build.gradle.kts: plugins { id(""com.diffplug.spotless"") }; spotless { kotlin { ktfmt().googleStyle() } }; // Enforced in CI",Noisy diffs; style debates in PRs; inconsistent codebase appearance,Configure ktfmt/ktlint with Spotless plugin; enforce in CI pre-commit hook,https://developer.android.com/kotlin/style-guide
|
|
94
|
+
No Dependency Injection,All,Scalability,Critical,dependency injection di hilt koin manual creation testability coupling,Manually creating dependencies everywhere; tight coupling; untestable,class UserViewModel { val repo = UserRepository(ApiClient() AppDatabase.getInstance().userDao()) },@HiltViewModel class UserViewModel @Inject constructor(private val repo: UserRepository) : ViewModel(),Can't substitute test doubles; changing dependency requires modifying every consumer; circular deps,Use Hilt (Android) or Koin; constructor injection; interface bindings,https://developer.android.com/training/dependency-injection/hilt-android
|
|
95
|
+
Shared Mutable State,All,Scalability,Critical,shared mutable state global singleton concurrency race condition thread safety,Global mutable state accessed from multiple threads without synchronization,object AppState { var currentUser: User? = null; var cartItems = mutableListOf<Item>() }; // Modified from any thread,private val _user = MutableStateFlow<User?>(null); val user: StateFlow<User?> = _user.asStateFlow() // Thread-safe; single writer,Race conditions; data corruption; impossible to reproduce bugs; crashes under load,Use StateFlow/LiveData for reactive state; Mutex for critical sections; immutable data classes,https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
|
|
96
|
+
Monolithic Navigation,All,Scalability,High,monolithic navigation graph single navgraph nested module scale route,Single navigation graph with all 50+ screens; merge conflicts; can't modularize,"NavHost { composable(""home"") { }; composable(""search"") { }; composable(""profile"") { }; ... 50 more routes in one file }",// Each feature module exposes navigation: fun NavGraphBuilder.homeGraph() { composable<HomeRoute> { HomeScreen() } }; // Root: NavHost { homeGraph(); searchGraph(); profileGraph() },Monolithic file; every team edits same navigation; can't parallelize feature development,Nested nav graphs per feature module; each module owns its routes,https://developer.android.com/guide/navigation/design/nested-graphs
|
|
97
|
+
No Tests,All,Testing,Critical,no test coverage untested unit integration ship pray,Shipping code with zero automated tests,func updatePrice(newPrice: Decimal) { product.price = newPrice; notifyObservers() } // No tests anywhere,@Test fun updatePrice_updatesValue() { viewModel.updatePrice(9.99); assertEquals(9.99 viewModel.product.value.price) },One bug fix breaks 3 other features; regression on every release; fear of refactoring,Write tests for critical business logic first; aim for 80%+ coverage on domain layer,https://developer.android.com/training/testing
|
|
98
|
+
Testing Implementation Details,All,Testing,High,test implementation detail brittle fragile mock verify internal,Tests that verify HOW code works instead of WHAT it does; break on refactor,verify(exactly = 1) { repo.save(any()) }; // Tests internal call; breaks if implementation changes,val result = viewModel.submitOrder(order); assertEquals(OrderStatus.CONFIRMED result.status) // Tests behavior,Tests break on every refactor even when behavior unchanged; zero confidence; test maintenance hell,Test public behavior and outputs; don't verify internal method calls unless side-effect is the contract,https://testing.googleblog.com/2013/08/testing-on-toilet-test-behavior-not.html
|
|
99
|
+
Flaky Tests in CI,All,Testing,High,flaky test intermittent fail pass ci unreliable timing race condition,Tests that randomly pass/fail; team starts ignoring CI results,@Test fun testNetworkCall() { Thread.sleep(5000); assertTrue(result.isSuccess) } // Timing dependent,@Test fun testNetworkCall() = runTest { val result = fakeRepo.getData(); assertTrue(result.isSuccess) } // Deterministic,Team ignores CI failures; broken code merges; flaky tests erode trust in entire test suite,Use fakes instead of mocks; use TestCoroutineDispatcher; avoid Thread.sleep; deterministic tests,https://developer.android.com/training/testing/fundamentals
|
|
100
|
+
No Single Source of Truth,All,Data,Critical,single source truth ssot cache api database stale inconsistent duplicated,Same data stored in multiple places; becomes inconsistent,var cachedUser: User? = null; fun getUser(): User { cachedUser = api.getUser(); return cachedUser!! } // Also in Room; also in ViewModel,fun getUser(): Flow<User> = userDao.observe().onStart { refreshFromNetwork() } // Room is SSOT,Stale data shown; user sees different info on different screens; cache invalidation bugs,Make local database (Room) single source of truth; network refreshes database; UI observes database,https://developer.android.com/topic/architecture/data-layer#source-of-truth
|
|
101
|
+
Repository Returns Entity,All,Data,Medium,repository room entity dto leak domain layer boundary separation,Repository exposing Room entities or API DTOs directly to ViewModel/UI,fun getUsers(): Flow<List<UserEntity>> // Room entity with @ColumnInfo annotations leaked to UI,fun getUsers(): Flow<List<User>> // Clean domain model; mapped in repository; UI decoupled from DB schema,Database schema change forces UI update; API response change ripples through entire app,Map Entity → Domain model in repository; UI never sees database annotations or API field names,https://developer.android.com/topic/architecture/data-layer
|
|
102
|
+
Fire and Forget Coroutine,Android,Coroutine,High,fire forget coroutine launch exception lost crash silent scope,Launching coroutine without handling exceptions; silent failures,viewModelScope.launch { api.saveData(data) } // Exception silently swallowed by default handler,viewModelScope.launch { runCatching { api.saveData(data) }.onFailure { _error.emit(it.message) } } // Error handled and shown,Errors silently swallowed; data loss; user thinks action succeeded but it failed,Always handle exceptions in coroutines; use CoroutineExceptionHandler or runCatching,https://developer.android.com/kotlin/coroutines/coroutines-best-practices
|
|
103
|
+
Collecting Flow in Wrong Scope,Android,Coroutine,High,flow collect lifecycle repeatonlifecycle started launchwhenstrated leak,Collecting Flow in onCreate without lifecycle awareness; processes events when app backgrounded,lifecycleScope.launch { flow.collect { updateUI(it) } } // Collects even in background; wasted resources,lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { flow.collect { updateUI(it) } } },Processes events in background; battery drain; potential crashes updating invisible UI,Use repeatOnLifecycle(STARTED) or collectAsStateWithLifecycle() in Compose,https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
|
|
104
|
+
Business Logic in UI,All,Architecture,Critical,business logic ui composable view activity fragment viewmodel separation,Business logic (validation calculation) directly in Composable/View,@Composable fun Checkout() { val total = items.sumOf { it.price * it.qty } * (1 - discount); if (total > 100) freeShipping = true },@Composable fun Checkout(viewModel: CheckoutViewModel) { val state by viewModel.state.collectAsStateWithLifecycle(); TotalText(state.formattedTotal) },Untestable; duplicated logic across platforms; UI test required for business rule verification,Extract all business logic to ViewModel or UseCase; UI only renders state,https://developer.android.com/topic/architecture/ui-layer
|
|
105
|
+
Exposing MutableState,Android,State,High,expose mutablestateflow mutablelivedata encapsulation internal state viewmodel,ViewModel exposing MutableStateFlow/MutableLiveData to UI; breaking encapsulation,val state = MutableStateFlow(UiState()) // UI can mutate ViewModel state directly,private val _state = MutableStateFlow(UiState()); val state: StateFlow<UiState> = _state.asStateFlow(),UI can modify ViewModel state bypassing business logic; unintended state mutations; untraceable bugs,Expose read-only StateFlow; keep MutableStateFlow private; mutate only through ViewModel functions,https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
|
|
106
|
+
buildSrc Slowing Builds,Android,Build,Medium,buildsrc build logic slow invalidation convention plugin composite,Using buildSrc which invalidates all build caches on any change,// buildSrc/build.gradle.kts: any tiny change invalidates ENTIRE project cache,// build-logic/convention module: changes only invalidate convention plugin consumers; 80% faster incremental,buildSrc change = full project rebuild; no incremental; 5min rebuild from scratch,Move build logic to included build (build-logic) with composite builds,https://developer.android.com/build/migrate-to-catalogs
|
|
107
|
+
Unused Dependencies,All,Build,Medium,unused dependency dead code classpath bloat size apk ipa bundle,Dependencies added but never used; bloating app size and build time,// 50 dependencies; 20 unused; +8MB APK size; +30s build time; security surface increased,// ./gradlew buildHealth; // Identifies unused declared and used-undeclared dependencies,Add libraries 'just in case'; never remove; 50 deps but only 30 used,Zero unused dependencies,https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin
|
|
108
|
+
No Loading Feedback,All,UX,High,loading feedback indicator spinner skeleton progress perceived performance,No loading indicator; user thinks app is frozen or broken,"// Button(onClick = { api.submit() }) { Text(""Post"") } // No loading state; user taps 5 times; 5 submissions","PostButton(onClick = { isLoading = true; viewModel.submit() } enabled = !isLoading) { if (isLoading) CircularProgressIndicator() else Text(""Post"") }",Blank screen during network call; no visual feedback; user taps button multiple times,Instant loading feedback,
|
|
109
|
+
Destructive Action Without Confirmation,All,UX,Medium,destructive action confirmation delete dialog undo irreversible,Delete/irreversible actions with no confirmation; accidental data loss,// IconButton(onClick = { dao.delete(item) }) // Immediately deletes; no confirmation; no undo; data lost,"AlertDialog(title = { Text(""Delete this item?"") } confirmButton = { TextButton(onClick = { delete() }) { Text(""Delete"" color = MaterialTheme.colorScheme.error) } })",Swipe-to-delete with no confirmation; tap 'Delete Account' instantly deletes,Confirm before destructive actions,
|
|
110
|
+
Ignoring Keyboard,All,UX,Medium,keyboard ime soft input adjustment scroll overlap textfield focus,Keyboard overlapping input fields; form fields hidden behind keyboard,// TextField behind keyboard; user types blind; can't see input or errors,// Scaffold(modifier = Modifier.imePadding()); // Or: BringIntoViewRequester for focused field,Form field hidden behind keyboard; user can't see what they're typing,Fields visible above keyboard,https://developer.android.com/develop/ui/compose/layouts/insets
|
|
111
|
+
Large SwiftUI View Body,iOS,SwiftUI,High,swiftui body large refactor extract subview performance,View body with 200+ lines; impossible to understand and slow to compile,// var body: some View { VStack { /* 400 lines of nested HStack VStack Group ForEach if-else */ } } // Unreadable; slow compile,struct OrderScreen: View { var body: some View { VStack { HeaderSection(); ItemsList(); TotalSection(); CheckoutButton() } } } // 4 lines,500-line body with nested conditionals; 30s build time for one file,< 30 lines per body,
|
|
112
|
+
Not Using @MainActor,iOS,Swift,Medium,mainactor swift concurrency sendable actor isolation ui thread,Updating UI from background thread causing crashes in Swift 6,// class ViewModel: ObservableObject { @Published var items: [Item] = []; func load() { Task { items = await api.fetch() } } } // Off-main update,@MainActor class HomeViewModel: ObservableObject { @Published var items: [Item] = []; func load() async { items = try await api.fetch() } },Update @Published properties from background thread; crash in Swift 6 strict concurrency,@MainActor for UI code,https://developer.apple.com/documentation/swift/mainactor
|
|
113
|
+
Not Using Keys in Lists,Flutter,Performance,Medium,flutter key widget list rebuild globalkey valuekey uniquekey identity,Missing keys in dynamic lists; incorrect widget recycling; state bugs,// ListView.builder(itemBuilder: (ctx i) => UserTile(user: users[i])) // No key; state mixup on reorder; wrong checkbox checked,ListView.builder(itemBuilder: (ctx i) => UserTile(key: ValueKey(users[i].id) user: users[i])),No keys; widgets recycled incorrectly; TextField in wrong row after reorder,Keys for stateful list items,https://api.flutter.dev/flutter/foundation/Key-class.html
|
|
114
|
+
Nested MediaQuery,Flutter,Performance,Medium,flutter mediaquery nested rebuild context unnecessary of,Using MediaQuery.of in deep widgets; unnecessary rebuilds on any media change,// MediaQuery.of(context).size.width; // Rebuilds on padding textScaleFactor orientation AND size changes,final width = MediaQuery.sizeOf(context).width; // Only notifies when size changes,MediaQuery.of(context) deep in tree; widget rebuilds on every keyboard show/hide,Use specific MediaQuery methods,https://api.flutter.dev/flutter/widgets/MediaQuery-class.html
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
Name,Platform,Complexity,Team Size,Keywords,Best For,Tech Stack,Layers,Structure,Anti Patterns,Notes,Reference URL
|
|
2
|
+
MVVM,Android,Medium,2-5,mvvm viewmodel compose hilt room retrofit kotlin,Standard modern Android apps with Compose UI,Jetpack Compose|Hilt|Room|Retrofit|Coroutines|Navigation Compose,3,ui/screens|ui/viewmodel|data/repository|data/local|data/remote|di,God ViewModel|Exposing mutable state|Business logic in View|Skipping repository,Default recommended architecture by Google. ViewModel survives config changes.,https://developer.android.com/topic/architecture
|
|
3
|
+
Clean Architecture,Android,High,5+,clean architecture usecases domain multi-module separation,Enterprise apps requiring strict separation and testability,Kotlin|Hilt|Room|Retrofit|Coroutines|Flow|JUnit|MockK,4,app|domain/usecases|domain/model|data/repository|data/datasource|presentation/viewmodel|presentation/ui,Overengineering small apps|Unnecessary UseCases|Domain depending on data|Leaking framework types,Best for large teams needing strict boundaries. Domain layer must have zero Android deps.,https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
|
|
4
|
+
MVI,Android,High,3-8,mvi state intent reducer kotlin flow unidirectional side effects,Apps with complex state management and deterministic UI,Kotlin|Compose|Flow|StateFlow|Hilt|Room|Retrofit,3,ui/screens|feature/state|feature/intent|feature/reducer|feature/sideeffect|data/repository,State explosion|Mutable state outside reducer|Blocking main thread in reducer,Single source of truth for UI state. State is immutable updated through intents via reducer.,https://developer.android.com/topic/architecture/ui-layer
|
|
5
|
+
MVP,Android,Medium,2-5,mvp presenter view contract legacy java,Legacy Android apps or teams migrating from Java,Java or Kotlin|Dagger2|SQLite or Room|Retrofit|RxJava,3,ui/activities|ui/fragments|presenter|contract|model/repository|model/datasource,Massive Presenter|Tight coupling View-Presenter|Lifecycle leaks|Not detaching view,Considered legacy. Still in older codebases. Presenter holds View reference creating lifecycle issues.,https://developer.android.com/topic/architecture
|
|
6
|
+
MVVM + Repository,Android,Medium,2-5,mvvm repository livedata flow viewmodel hilt room,Most modern Android apps following Google recommended arch,Kotlin|ViewModel|StateFlow|Hilt|Room|Retrofit|Navigation,3,ui/screens|ui/viewmodel|data/repository|data/local|data/remote|di,Repository becoming God class|Not mapping DTOs|Exposing Room entities to UI,Most commonly adopted modern Android pattern. Repository is single source of truth.,https://developer.android.com/topic/architecture/data-layer
|
|
7
|
+
Multi-Module Clean,Android,High,10+,multi-module feature modules clean modularization gradle,Large-scale apps with multiple feature teams,Kotlin|Hilt|Room|Retrofit|Navigation|Gradle Convention Plugins|Flow,5,app|core/common|core/network|core/database|core/ui|feature/home|feature/search,Circular module deps|Shared mutable state|God core module|Tight coupling features,Enables parallel builds and independent feature development. Improves build times.,https://developer.android.com/topic/modularization
|
|
8
|
+
Redux-like (Orbit MVI),Android,High,3-8,orbit mvi redux unidirectional middleware side effect container,Predictable state with middleware and side effect management,Kotlin|Orbit MVI|Compose|Hilt|Coroutines|Flow,3,ui/screens|feature/viewmodel|feature/state|feature/sideeffect|data/repository|middleware,Over-dispatching actions|Not using middleware for async|Navigation in reducer,Orbit provides Container hosting state and side effects. Built-in testing DSL.,https://orbit-mvi.org/
|
|
9
|
+
Compose-first,Android,Medium,2-5,compose state hoisting remember composable kotlin material3,New Android apps built entirely with Jetpack Compose,Compose|Material3|Hilt|Room|Retrofit|Navigation Compose|Coroutines,3,ui/screens|ui/components|ui/theme|ui/navigation|viewmodel|data/repository,Business logic in composables|Not hoisting state|Overusing remember|Recomposition issues,Compose-first means entirely declarative UI. No XML layouts or Fragments needed.,https://developer.android.com/develop/ui/compose
|
|
10
|
+
MVVM-C,iOS,Medium,3-8,mvvm coordinator swiftui combine navigation ios,Modern iOS apps needing decoupled navigation,SwiftUI|Combine|Swift Concurrency|SwiftData|URLSession|SPM,3,Coordinators|Views|ViewModels|Models|Services|Networking,Navigation logic in ViewModel|Coordinator retaining views|Massive Coordinator,Coordinators handle navigation keeping ViewModels free of routing logic.,https://developer.apple.com/documentation/swiftui
|
|
11
|
+
VIPER,iOS,High,10+,viper interactor presenter entity router ios enterprise,Large enterprise iOS apps with big teams,UIKit or SwiftUI|Swift|CoreData|URLSession|Swinject|Quick Nimble,5,View|Interactor|Presenter|Entity|Router|DataManager|NetworkService,Massive boilerplate|Unnecessary abstraction|Tight coupling|Protocol explosion,Each screen has 5 components. Very testable but extremely verbose.,https://github.com/infinum/iOS-VIPER-Xcode-Templates
|
|
12
|
+
TCA,iOS,High,3-8,tca composable pointfree reducer effect state swiftui,Composable and testable state management with SwiftUI,SwiftUI|TCA|Swift Concurrency|Dependencies|SPM,4,Feature/Reducer|Feature/View|Feature/State|Feature/Action|SharedModels|Clients,Overcomplicating simple features|Not scoping stores|Large monolithic reducers,Created by Point-Free. Every feature is a Reducer with State Action Effect.,https://github.com/pointfreeco/swift-composable-architecture
|
|
13
|
+
MVC,iOS,Low,1-3,mvc model view controller uikit storyboard ios,Small iOS apps or prototypes,UIKit|Storyboard|CoreData|URLSession|Swift,2,Controllers|Views|Models|Helpers|Extensions|Resources,Massive View Controller|Business logic in controller|Not separating networking,Apple original pattern. Simple but leads to Massive View Controller problem.,https://developer.apple.com/documentation/uikit
|
|
14
|
+
MVVM + Router,iOS,Medium,2-5,mvvm router swiftui navigation combine async await ios,Modern SwiftUI apps with programmatic navigation,SwiftUI|Combine|Swift Concurrency|SwiftData|NavigationStack|SPM,3,Views|ViewModels|Routers|Models|Services|Networking,Navigation scattered across VMs|Router God object|Not using NavigationPath,Routers handle navigation through NavigationStack. VMs focus on business logic.,https://developer.apple.com/documentation/swiftui/navigationstack
|
|
15
|
+
Clean Swift (VIP),iOS,High,5+,vip clean swift interactor presenter worker router ios,iOS apps following Uncle Bob Clean Architecture,UIKit or SwiftUI|Swift|CoreData|URLSession|XCTest,4,Scenes/View|Scenes/Interactor|Scenes/Presenter|Scenes/Router|Scenes/Worker|Services,Excessive boilerplate|Request Response ViewModel bloat|Workers doing too much,Each scene follows unidirectional VIP cycle. Highly testable.,https://clean-swift.com/
|
|
16
|
+
RIBs,iOS,High,10+,ribs router interactor builder uber ios modular,Very large iOS apps with deep dependency trees,UIKit|Swift|RxSwift|Needle DI|XCTest,4,RIB/Router|RIB/Interactor|RIB/Builder|RIB/View|RIB/Component|Services,Deep RIB tree complexity|Viewless RIBs overuse|Builder God class,Created by Uber. Business logic in Interactors. Builders handle DI.,https://github.com/uber/RIBs
|
|
17
|
+
BLoC,Flutter,Medium,3-8,bloc cubit event state stream flutter dart,Structured event-driven state management for Flutter,Flutter|Dart|flutter_bloc|equatable|freezed|dio|get_it,3,lib/bloc|lib/data/repository|lib/data/model|lib/presentation/pages|lib/core,BLoC for trivial state|Not closing streams|Emitting in constructor|Nested BlocBuilders,Separates business logic from UI using Events and States. Cubit is simplified version.,https://bloclibrary.dev/
|
|
18
|
+
Provider + Clean,Flutter,Medium,2-5,provider changenotifier clean architecture flutter dart,Small to medium Flutter apps,Flutter|Dart|provider|dio|sqflite|get_it|json_serializable,3,lib/domain/entities|lib/domain/usecases|lib/data/repositories|lib/presentation/providers|lib/core,ChangeNotifier God class|Not disposing|Calling notifyListeners too often,Provider is Flutter recommended simple state management. Scales for medium apps.,https://pub.dev/packages/provider
|
|
19
|
+
Riverpod + Clean,Flutter,High,3-8,riverpod clean architecture code generation flutter dart freezed,Modern Flutter apps wanting compile-safe DI and state,Flutter|Dart|flutter_riverpod|riverpod_generator|freezed|dio|drift|go_router,4,lib/features/home/domain|lib/features/home/data|lib/features/home/presentation|lib/core,Provider spaghetti|Not using autoDispose|Circular provider deps,Riverpod is Provider successor with compile-time safety. No BuildContext dependency.,https://riverpod.dev/
|
|
20
|
+
GetX,Flutter,Low,1-3,getx controller reactive bindings flutter dart all-in-one,Small Flutter apps or rapid prototypes,Flutter|Dart|get|get_storage|get_connect,2,lib/modules/home/controller|lib/modules/home/view|lib/modules/home/binding|lib/data|lib/routes,Tight coupling to GetX|God controller|Not disposing|Overusing .obs,All-in-one package. Easy to learn but creates vendor lock-in. Not for large apps.,https://pub.dev/packages/get
|
|
21
|
+
Stacked (MVVM),Flutter,Medium,2-5,stacked mvvm viewmodel service flutter dart filledstacks,Medium Flutter apps wanting structured MVVM,Flutter|Dart|stacked|stacked_services|get_it|injectable|dio,3,lib/ui/views|lib/ui/widgets|lib/viewmodels|lib/services|lib/models|lib/app,VM doing network calls directly|Not using services|Navigation in views,Created by FilledStacks. Structured MVVM with navigation and dialog services.,https://pub.dev/packages/stacked
|
|
22
|
+
Redux Toolkit,React Native,High,5+,redux toolkit slice thunk rtk query react native typescript,Large RN apps with complex global state,React Native|TypeScript|Redux Toolkit|RTK Query|React Navigation|Axios|Jest,3,src/store/slices|src/store/middleware|src/screens|src/components|src/services|src/navigation,Everything in global state|Not using createSlice|Massive reducers|Not normalizing state,Redux Toolkit simplifies Redux. RTK Query handles data fetching and caching.,https://redux-toolkit.js.org/
|
|
23
|
+
Context + Hooks,React Native,Low,1-3,context hooks usestate usereducer react native lightweight,Small RN apps with limited shared state,React Native|TypeScript|React Navigation|Axios|AsyncStorage,2,src/context|src/hooks|src/screens|src/components|src/services|src/navigation,Overusing context for frequent updates|Provider hell|Not memoizing context values,Built into React no extra deps. Performance degrades with frequent context updates.,https://react.dev/reference/react/useContext
|
|
24
|
+
Zustand,React Native,Medium,2-5,zustand store middleware persist react native typescript minimal,Medium RN apps wanting simple scalable state,React Native|TypeScript|Zustand|React Navigation|Axios|MMKV|Jest,3,src/stores|src/screens|src/components|src/services|src/hooks|src/navigation,Single monolithic store|Not using selectors|Mutating outside set,Minimal and unopinionated. No providers needed. Supports middleware.,https://zustand-demo.pmnd.rs/
|
|
25
|
+
MobX,React Native,Medium,3-8,mobx observable action computed reaction react native typescript,RN apps with complex domain models and reactive needs,React Native|TypeScript|MobX|mobx-react-lite|React Navigation|Axios,3,src/stores|src/models|src/screens|src/components|src/services|src/navigation,Observable mutation outside actions|Not using computed|Circular store deps,Transparent reactive programming. Observables auto-track deps and update UI.,https://mobx.js.org/
|
|
26
|
+
React Query + Context,React Native,Medium,2-5,react query tanstack context server state cache react native,RN apps primarily server-state driven,React Native|TypeScript|TanStack React Query|React Navigation|Axios|Zod|MMKV,3,src/api/queries|src/api/mutations|src/context|src/screens|src/components|src/hooks,Using React Query for client state|Not setting stale times|Duplicate query keys,Separates server state (React Query) from client state (Context). Handles caching.,https://tanstack.com/query/latest
|
|
27
|
+
KMP Shared Logic,Cross-platform,High,5+,kmp kotlin multiplatform shared logic expect actual compose,Cross-platform apps sharing business logic with native UI,Kotlin Multiplatform|Compose Multiplatform|Ktor|SQLDelight|Koin|Kotlin Serialization,4,shared/commonMain|shared/androidMain|shared/iosMain|androidApp|iosApp|shared/domain|shared/data,Sharing UI prematurely|Platform-specific code in common|Ignoring expect/actual|Monolithic shared module,Share domain and data layers; keep platform UI native or use Compose Multiplatform for UI.,https://www.jetbrains.com/kotlin-multiplatform/
|
|
28
|
+
Compose Multiplatform,Cross-platform,High,3-8,compose multiplatform desktop ios android web jetbrains kotlin,Cross-platform apps with shared Compose UI,Compose Multiplatform|Kotlin|Ktor|SQLDelight|Koin|Navigation,3,composeApp/commonMain|composeApp/androidMain|composeApp/iosMain|shared|server,Ignoring platform differences|Not testing on all targets|Overusing expect/actual for UI,JetBrains framework sharing Compose UI across Android iOS Desktop Web.,https://www.jetbrains.com/compose-multiplatform/
|
|
29
|
+
Circuit,Android,High,3-8,circuit slack presenter ui screen overlay navigation cashapp,Compose-first architecture with Presenter and UI separation,Circuit|Compose|Dagger/Anvil|Kotlin|Coroutines|Flow,3,screens/presenter|screens/ui|di|services|models|navigation,Presenter doing UI work|Not using CircuitContent|Tight coupling presenters,Created by Slack. Presenters produce state; UI renders it. Clean separation.,https://slackhq.github.io/circuit/
|
|
30
|
+
Decompose,Cross-platform,High,3-8,decompose lifecycle navigation component kmp arkivanov multiplatform,Lifecycle-aware business logic components for KMP,Kotlin Multiplatform|Decompose|Compose|Essenty|Kotlin Coroutines,3,shared/components|shared/models|composeApp/ui|shared/navigation|shared/data,Components doing UI work|Not managing lifecycle|Ignoring back handling,Multiplatform lifecycle-aware components. Business logic survives config changes across platforms.,https://arkivanov.github.io/Decompose/
|
|
31
|
+
Server-Driven UI,All,High,10+,server driven ui sdui backend config dynamic layout json,Apps requiring frequent UI changes without app updates,JSON Schema|Compose/SwiftUI renderers|Backend CMS|GraphQL|Feature flags,4,backend/schemas|backend/cms|app/renderers|app/models|app/parsers|app/fallbacks,No fallback for unknown types|Trusting server blindly|No schema validation|No caching,UI defined by server JSON. Enables A/B testing and instant updates without app releases.,
|
|
32
|
+
Feature Module Architecture,Android,Medium,5+,feature module dynamic delivery modularization gradle convention,Large apps split into independent feature modules,Kotlin|Hilt|Navigation|Gradle Convention Plugins|Dynamic Delivery,4,app|core/common|core/network|core/ui|feature/home|feature/settings|feature/onboarding,Circular module deps|Shared mutable state|Feature depending on feature|God core,Each feature is an independent module with its own DI testing and navigation. Enables parallel development.,https://developer.android.com/topic/modularization
|
|
33
|
+
Offline-First Architecture,All,High,3-8,offline first local database sync queue conflict resolution,Apps that must work without network connectivity,Room/CoreData/SQLDelight|WorkManager/BGTask|Sync Engine|Conflict Resolution,4,local/database|sync/queue|sync/resolver|remote/api|domain/repository|ui,Ignoring conflicts|No sync queue|Optimistic UI without rollback|No connectivity monitoring,Local database is source of truth. Changes queued and synced when online. Conflict resolution required.,https://developer.android.com/topic/architecture/data-layer/offline-first
|
|
34
|
+
Feature Flags Architecture,All,Medium,3+,feature flag toggle remote config ab test gradual rollout,Apps needing gradual feature rollout and A/B testing,Firebase Remote Config|LaunchDarkly|Statsig|Kotlin|Sealed Class,3,flags/definitions|flags/provider|flags/evaluation|features|analytics,Boolean-only flags|No default fallback|Flag debt accumulation|Not cleaning up old flags,Decouple deployment from release. Enable features gradually. Clean up flags after full rollout.,https://firebase.google.com/docs/remote-config
|
|
35
|
+
Modular Navigation,Android,Medium,3-8,navigation module compose route typesafe deep link graph,Type-safe modular navigation across feature modules,Navigation Compose|Kotlin Serialization|Hilt|Type-safe routes,3,navigation/routes|navigation/graph|feature/screens|feature/viewmodel|core/navigation,String-based routes|Navigation in ViewModel|Shared navigation state|Circular nav deps,Type-safe navigation with @Serializable routes. Each module defines its own nav graph.,https://developer.android.com/guide/navigation/design/type-safety
|
|
36
|
+
Unidirectional Data Flow,All,Medium,2-5,udf unidirectional data flow state action effect single source truth,Apps needing predictable state management,StateFlow/Combine/BLoC|Sealed Class/Enum|Immutable State,3,state|actions|reducers|effects|ui|repository,Bidirectional state|Mutable exposed state|Side effects in reducer|State mutation outside flow,State flows in one direction: UI -> Action -> Reducer -> State -> UI. Predictable and testable.,https://developer.android.com/topic/architecture/ui-layer#udf
|
|
37
|
+
Dependency Injection Patterns,All,Medium,2+,di dependency injection hilt koin swinject constructor service locator,All apps needing testable decoupled components,Hilt|Koin|Swinject|get_it|InversifyJS,2,di/modules|di/qualifiers|di/scopes|providers|consumers,Service Locator antipattern|Manual DI in large apps|Leaking scoped dependencies|Circular deps,Constructor injection preferred. Hilt for Android; Koin for KMP; Swinject for iOS; get_it for Flutter.,https://developer.android.com/training/dependency-injection
|
|
38
|
+
Repository Pattern,All,Low,1+,repository pattern data source local remote cache single source truth,All apps needing data layer abstraction,Interface|Room/CoreData|Retrofit/URLSession|Cache Strategy,3,data/repository|data/local|data/remote|data/mapper|domain/interface,Repository as God class|Not mapping DTOs|Exposing DB entities|No caching strategy,Repository abstracts data sources. Single source of truth. Maps between DTOs and domain models.,https://developer.android.com/topic/architecture/data-layer
|
|
39
|
+
Micro-Frontend Mobile,All,High,10+,micro frontend mini app super app module federation dynamic,Super-apps with independently deployable feature modules,Dynamic Feature Modules|Module Federation|React Native|Kotlin,5,host-app|mini-app-1|mini-app-2|shared-sdk|bridge|routing,Tight coupling between mini-apps|Shared mutable state|Version conflicts|No isolation,Each feature team owns a mini-app. Loaded dynamically. Independent releases. Common in super-apps.,
|
|
40
|
+
Event-Driven Architecture,All,High,5+,event driven architecture eventbus mediator cqrs message,Complex apps with many loosely coupled components,EventBus|SharedFlow|Combine|RxDart|Mediator Pattern,3,events/definitions|events/publishers|events/subscribers|handlers|mediator,Event spaghetti|No event ordering|Lost events|Circular event chains|Debugging difficulty,Components communicate through events. Decoupled but requires careful event design and tracing.,
|
|
41
|
+
Clean Architecture + MVI,Android,High,5+,clean mvi architecture state intent unidirectional domain usecase,Enterprise Android apps needing both clean layers and predictable state,Kotlin|Compose|Hilt|Room|Retrofit|Flow|StateFlow,5,presentation/ui|presentation/mvi|domain/usecase|domain/model|data/repository|data/source,Overengineering|4-layer boilerplate|Unnecessary UseCases|State explosion,Combines Clean Architecture layers with MVI state management. Maximum testability and predictability.,https://developer.android.com/topic/architecture
|
|
42
|
+
SwiftUI + SwiftData,iOS,Medium,2-5,swiftui swiftdata observation macro model swift6 modern,Modern iOS apps with SwiftUI and SwiftData persistence,SwiftUI|SwiftData|Observation|Swift Concurrency|NavigationStack|SPM,3,Models|Views|ViewModels|Services|Navigation|DataAccess,@Model in views directly|No migration strategy|Heavy queries in view body|Not using @Query,SwiftData replaces CoreData. @Observable replaces ObservableObject. Native Swift concurrency.,https://developer.apple.com/documentation/swiftdata
|
|
43
|
+
SwiftUI + TCA,iOS,High,3-8,tca composable architecture swiftui reducer state action effect dependencies,Highly testable and composable iOS apps,SwiftUI|TCA|Dependencies|Swift Concurrency|NavigationStack,4,Features/Reducer|Features/View|Features/State|Features/Action|SharedModels|Clients|Dependencies,Overcomplicating simple screens|Monolithic reducers|Not scoping stores|Ignoring effects,Point-Free's TCA with scope-based composition. Every feature is independently testable.,https://github.com/pointfreeco/swift-composable-architecture
|
|
44
|
+
Expo Router,React Native,Medium,2-5,expo router file-based navigation layout tab stack react native,Modern React Native apps with file-based routing,Expo|Expo Router|TypeScript|React Navigation|NativeWind|Zustand,3,app/(tabs)|app/(auth)|app/[id]|components|hooks|stores|services,Not using layouts|Deep nesting|No error boundaries|Ignoring platform differences,File-based routing inspired by Next.js. Layouts replace tab/stack config. Deep linking automatic.,https://docs.expo.dev/router/introduction/
|
|
45
|
+
Kotlin Multiplatform + Compose,Cross-platform,High,5+,kmp compose multiplatform mobile desktop ios android shared ui,Full cross-platform apps with shared UI and logic,Kotlin|Compose Multiplatform|Ktor|SQLDelight|Koin|Voyager/Decompose,4,composeApp/commonMain/ui|shared/domain|shared/data|composeApp/androidMain|composeApp/iosMain,Not handling platform APIs|Monolithic commonMain|Ignoring iOS conventions|Poor Swift interop,Full UI sharing with Compose Multiplatform. Platform-specific APIs via expect/actual or Koin.,https://www.jetbrains.com/kotlin-multiplatform/
|
|
46
|
+
Vapor + iOS Full-Stack,iOS,High,3-5,vapor swift server fullstack ios backend shared models,Swift full-stack with shared models between server and iOS,Vapor|SwiftUI|Shared Swift Package|Fluent ORM|Swift Concurrency,4,server/Sources|shared/Models|ios/App|ios/Services|server/Migrations|server/Routes,Coupling server and client deploys|Shared mutable models|No API versioning,Share Swift models between Vapor backend and iOS app via Swift Package.,https://vapor.codes/
|
|
47
|
+
Kotlin Multiplatform + SwiftUI,Cross-platform,High,,kmp kotlin multiplatform swiftui ios shared logic native ui,Share business logic in Kotlin; native SwiftUI for iOS and Compose for Android UI,Shared: Domain + Data + Use Cases; Platform: UI + Platform APIs,,Teams wanting shared logic with fully native UI per platform,Shared business logic; native UI; reduced code duplication; type safety across platforms,Steep learning curve; debugging shared code on iOS; swift-kotlin interop limitations,https://kotlinlang.org/docs/multiplatform-mobile-getting-started.html
|
|
48
|
+
Modular Monolith,Android,Medium,,modular monolith convention plugins build-logic feature module gradle,Single app with strict module boundaries but no microservices complexity,build-logic/ (conventions) + core/ (data ui network) + feature/ (home search profile),,Growing teams needing modularity without microservice overhead,Clear boundaries; fast builds; shared build logic via convention plugins; team ownership per module,Initial setup effort; module boundary enforcement; potential circular deps without strict rules,https://developer.android.com/topic/modularization
|
|
49
|
+
MVI with Compose,Android,Medium,,mvi compose model view intent unidirectional orbit state reduce side effect,Full MVI with unidirectional data flow in Compose; Intent→ReducerState→UI,Intent → Reducer → State → UI; SideEffects channel for one-shot events,,Complex screens with many user actions; when state traceability is critical,Predictable state; easy debugging; time-travel; testable reducers; fits Compose model,Boilerplate for simple screens; learning curve; over-engineering for CRUD apps,https://orbit-mvi.org/
|
|
50
|
+
Repository + Mediator,Android,Medium,,repository mediator network bound resource cache strategy offline,Repository pattern with NetworkBoundResource mediator for cache-then-network,DataSource (Remote + Local) → Repository (mediator logic) → UseCase → ViewModel,,Apps needing robust offline support with stale-while-revalidate,Offline-first; responsive UI; single source of truth; automatic cache refresh,Complex mediator logic; cache invalidation bugs; testing cache strategies,https://developer.android.com/topic/architecture/data-layer/offline-first
|