Solo Mobile Dev, Three-Person Output: 12 Battle-Tested AI Prompts for Flutter, React Native and Kotlin Workflows
A solo mobile developer in 2026 is not really one person anymore — they are a product owner, a UI engineer, a native-module plumber, a build engineer, and a release manager. The bottleneck is rarely typing speed. It is context switching: jumping from a Dart widget tree to a Swift bridge to a Gradle config to an App Store Connect rejection email, all before lunch.
Well-structured prompts are the cheapest way to compress that switching cost. Not "write me an app" prompts — those produce plausible-looking code that fails on device. The prompts that actually save hours are narrow, opinionated, and ask the model to reason inside a specific toolchain: Flutter's RenderObject pipeline, React Native's New Architecture (Fabric/TurboModules), Kotlin coroutines, Android's R8, iOS's bitcode-free build settings.
Below are 12 prompts organized into three tiers — basic, advanced, expert — each with the task it targets, the prompt text, and an example result. Everything is grounded in official documentation: Flutter docs (docs.flutter.dev), React Native docs (reactnative.dev), Android developer guides (developer.android.com), Apple's Human Interface Guidelines, and the official Fastlane documentation. Where I cite statistics, I keep them general rather than inventing numbers, because inflated stats are the fastest way to lose a technical reader.
How to use these prompts (read this first)
Three rules that separate a useful prompt from a hallucination generator:
- Pin the version. Flutter has been on the 3.x line for years; React Native has been on 0.7x. Always state the exact version and the platform target (iOS 17+, Android 14+). API surfaces change between minor releases.
- Demand the failure mode. Ask the model not only for code but for "what breaks this" — null safety edge cases, thread-safety on the platform channel, ProGuard rules for reflection-based libraries.
- Never paste secrets. No API keys, no signing certificates, no
.envcontents. Prompts about release pipelines should reference placeholder paths only.
| Tier | Prompts | Typical time saved per task |
|---|---|---|
| Basic | 1–4 | 30–90 minutes |
| Advanced | 5–9 | 2–6 hours |
| Expert | 10–12 | Half a day to a full sprint |
Basic tier: screens, state, and boilerplate
Prompt 1 — Generate a Flutter screen from a design description
Task: You have a Figma frame or a written spec and need a production-ready Flutter widget, not a toy Column.
Prompt:
You are a senior Flutter engineer. Generate a single-file Flutter screen for Flutter 3.x, Dart 3, targeting iOS 17+ and Android 14+. The screen is a profile page with: an avatar (network image with a
CircleAvatarfallback), a name, a verified badge, a stats row (followers / following / posts), and a scrollable list of recent activity cards. Requirements: useStatelessWidgetwhere possible, extract reusable sub-widgets, useconstconstructors everywhere legal, respectMediaQuerytext scaling, and addSemanticslabels for screen readers. Do not add any third-party packages. After the code, list every place where the layout could overflow on a small screen (320dp width) and how to fix it.
Example result (excerpt):
class ProfileScreen extends StatelessWidget {
const ProfileScreen({super.key, required this.user});
final User user;
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
SliverToBoxAdapter(child: _ProfileHeader(user: user)),
SliverList.builder(
itemCount: user.activities.length,
itemBuilder: (context, i) =>
ActivityCard(activity: user.activities[i]),
),
],
),
);
}
}
The model also flags the classic overflow trap: a fixed-width Row for the stats row breaks at 320dp — the fix is Wrap or Flexible with FittedBox. That single note is worth the prompt.
Prompt 2 — React Native screen with the New Architecture in mind
Task: Generate a React Native screen that will not silently degrade when the New Architecture (Fabric renderer, TurboModules) is enabled. Meta's docs describe the New Architecture as the default path going forward, so prompts should assume it.
Prompt:
You are a senior React Native engineer. Write a TypeScript functional component for a chat thread screen using React Native 0.7x with the New Architecture enabled. Use
FlatListwithkeyExtractor,getItemLayoutif item heights are fixed, andReact.memoon row components. Show typing indicator state, send-button disabled state, and keyboard avoidance viaKeyboardAvoidingViewwith platform-specific behavior. Do not useScrollViewfor the message list. Explain whygetItemLayoutmatters on Fabric and when it is unsafe to use it.
Example result: The model produces a FlatList with initialNumToRender={15}, windowSize={7}, and a note that getItemLayout is unsafe when messages have variable heights (rich text, images) because it desynchronizes the scroll offset. That nuance is exactly what a junior prompt omits.
Prompt 3 — State management decision matrix
Task: Pick a state solution without a three-day architecture debate.
Prompt:
Compare Riverpod, Bloc, and plain
ChangeNotifier+InheritedWidgetfor a Flutter app with: 20 screens, offline-first sync, and a team of one. Give a table with columns: learning curve, testability, boilerplate per feature, suitability for offline sync, and risk of over-engineering. Then recommend one and write the minimal folder structure. Do not recommend a package you cannot justify with a concrete scenario.
Example result:
| Criterion | Riverpod | Bloc | ChangeNotifier |
|---|---|---|---|
| Learning curve | Medium | High | Low |
| Testability | High (pure providers) | High (event-driven) | Medium |
| Boilerplate | Low | High | Very low |
| Offline sync fit | Strong | Strong | Weak |
| Over-engineering risk | Low | Medium | Low |
Recommendation for a solo dev: Riverpod, because providers are testable without a widget tree and the compile-time safety catches refactor mistakes.
Prompt 4 — Kotlin data layer with coroutines
Task: Generate a repository layer that respects structured concurrency instead of leaking GlobalScope.
Prompt:
You are a senior Android engineer. Write a Kotlin repository using coroutines and Flow for a news app. Use
Dispatchers.IOfor network and disk, expose a singleFlow<Result<List<Article>>>, and handle retry with exponential backoff. Do not useGlobalScope. Show how the ViewModel collects it withrepeatOnLifecycle. Explain what happens to the Flow if the ViewModel is cleared mid-emission.
Example result: The model returns a NewsRepository with a flow { } builder and retryWhen, plus the crucial explanation: when the ViewModel is cleared, repeatOnLifecycle cancels the collection, which propagates cancellation upstream and stops the network call — provided the repository uses the caller's scope, not its own.
Advanced tier: native bridges, performance, and builds
Prompt 5 — Platform channel between Flutter and Kotlin/Swift
Task: You need a native capability (e.g., a hardware sensor or a vendor SDK) exposed to Dart. This is where most solo devs lose days to MissingPluginException and thread crashes.
Prompt:
Generate a Flutter MethodChannel plugin exposing a native function
getBatteryHealth()on both Android (Kotlin) and iOS (Swift). Requirements: channel nameapp/battery, invoked on the platform's main thread, result returned on the main thread, errors returned viaresult.errorwith a code and message, and Dart-side null-safety. Show the Kotlin side usingconfigureFlutterEngine, the Swift side usingFlutterMethodChannelinAppDelegate, and the Dart side. Then list the three most common causes ofMissingPluginExceptionand how to verify the registration order.
Example result (Kotlin side, excerpt):
class MainActivity : FlutterActivity() {
private val channel = "app/battery"
override fun configureFlutterEngine(engine: FlutterEngine) {
super.configureFlutterEngine(engine)
MethodChannel(engine.dartExecutor.binaryMessenger, channel)
.setMethodCallHandler { call, result ->
if (call.method == "getBatteryHealth") {
result.success(readBatteryHealth())
} else result.notImplemented()
}
}
}
The model's diagnostic list is the real value: missing GeneratedPluginRegistrant call, channel name typo (invisible because it is a string), and calling result from a background thread.
Prompt 6 — React Native TurboModule in Kotlin
Task: Write a TurboModule (the New Architecture's typed native module) instead of the legacy bridge.
Prompt:
Write a React Native TurboModule for Android in Kotlin that returns the device's total RAM. Include the TypeScript spec file, the
codegenConfigentry forpackage.json, the Kotlin implementation, and theReactPackageregistration. Explain the difference between a TurboModule and a legacyReactContextBaseJavaModule, and when codegen runs during the build.
Example result: The model produces a spec file NativeDeviceInfo.ts with TurboModuleRegistry.getEnforcing, and correctly notes that codegen runs as a Gradle task (generateCodegenArtifactsFromSchema) before compilation — so a stale schema causes a build that compiles but crashes at runtime.
Prompt 7 — Flutter performance audit
Task: Find jank before users do. Flutter's own guidance says to measure with DevTools before optimizing — a prompt should enforce that discipline.
Prompt:
Act as a Flutter performance engineer. Given this widget tree [paste tree], identify likely causes of jank on a 60Hz device. Check for: rebuilds caused by non-const constructors,
ListViewwithoutitemExtentwhen heights are fixed, expensive work inbuild(),Opacityinstead ofAnimatedOpacity, andsaveLayercalls fromClipRRectwithantiAlias. For each issue, give the DevTools timeline evidence you would look for and the fix. Do not suggestRepaintBoundaryunless the subtree actually repaints independently.
Example result: A prioritized list. The top item is usually an Opacity wrapping a large subtree — the fix is AnimatedOpacity or baking opacity into the color, because Opacity triggers saveLayer and offscreen compositing.
Prompt 8 — Android build time reduction
Task: Gradle builds that take minutes kill flow. The Android team's own guidance recommends the build analyzer and configuration cache.
Prompt:
You are an Android build engineer. Given this
build.gradle.kts[paste], propose changes to reduce build time: enable Gradle configuration cache, enable build cache, avoidkaptwhere KSP is possible, remove unused annotation processors, and checkandroid.enableR8.fullMode. For each change, state the expected effect and the risk. Warn about any change that breaks incremental builds or reflection-based libraries.
Example result:
// gradle.properties
org.gradle.configuration-cache=true
org.gradle.caching=true
android.enableR8.fullMode=true
The model flags the classic trap: full-mode R8 is stricter about reflection, so libraries like Gson or Retrofit need explicit -keep rules or they break in release only.
Prompt 9 — iOS build and pod troubleshooting
Task: The pod install / Xcode signing loop that eats afternoons.
Prompt:
You are an iOS build engineer for a Flutter/React Native project. Here is the error [paste]. Diagnose it. Cover these categories: CocoaPods version mismatch,
use_frameworks!vs static libraries, Xcode deployment target lower than a pod's minimum, and stalePodfile.lock. Give the exact commands to run in order (includingpod deintegrate,pod cache clean --all, andrm -rf Pods Podfile.lock) and explain what each one changes. Warn me before any destructive command.
Example result: The model orders the steps from least to most destructive and explains that pod deintegrate removes CocoaPods integration from the Xcode project without deleting your code — the safest reset before a nuclear rm -rf Pods.
Expert tier: release, compliance, and shipping
Prompt 10 — App Store rejection triage
Task: Turn an opaque rejection into a fix plan. Apple's App Review Guidelines are public and specific; a good prompt maps your rejection to a numbered guideline.
Prompt:
You are an App Store review specialist. Here is my rejection text [paste]. Map it to the specific Apple App Review Guideline number and section. Then give: the likely root cause, the code or metadata change required, and a draft reply to App Review. Common areas to consider: Guideline 2.1 (app completeness), 2.3 (accurate metadata), 3.1.1 (in-app purchase), 4.2 (minimum functionality), and 5.1.1 (data collection and privacy). Do not guess if the rejection text is ambiguous — list the two most likely guidelines and how to tell them apart.
Example result: For a typical "app is too simple / repackaged website" rejection, the model maps it to Guideline 4.2 (Minimum Functionality) and suggests adding native value — offline mode, push notifications, or device integration — rather than cosmetic changes.
Prompt 11 — Google Play Data Safety and policy compliance
Task: The Play Console Data Safety form is a legal declaration. Getting it wrong risks removal. Play's policy requires accurate disclosure of data collection and sharing.
Prompt:
You are a Google Play compliance engineer. My app uses these SDKs and permissions [list]. Produce a Data Safety form draft: for each data type collected, state whether it is collected, shared, optional, and encrypted in transit. Flag any SDK that collects data I might not have declared. Also check my permissions against Play's sensitive-permission policy (e.g.,
QUERY_ALL_PACKAGES, background location,MANAGE_EXTERNAL_STORAGE). Give me the exact declaration questions I must answer in the Play Console.
Example result: The model commonly flags advertising and analytics SDKs as under-declared — they collect device identifiers that must appear in the form. It also warns that QUERY_ALL_PACKAGES requires a Play-approved use case or the app is rejected at review.
Prompt 12 — Automated release pipeline with Fastlane
Task: One command to build, sign, and upload to both stores. Fastlane is the de facto standard, and its docs cover supply (Play) and deliver/pilot (App Store).
Prompt:
Write a Fastlane
Fastfilefor a Flutter project that: builds a signed Android App Bundle withbundle exec fastlane supply, uploads to the Play internal track, builds and uploads an iOS build to TestFlight withpilot, and bumps the build number usingincrement_build_number. Use environment variables for credentials — never hardcode them. Add alane :cithat runs both platforms. Explain the difference betweensupplyanddeliver, and where the Play service account JSON and App Store Connect API key should live.
Example result (excerpt):
default_platform(:android)
platform :android do
lane :beta do
gradle(task: "bundle", build_type: "Release")
upload_to_play_store(track: "internal")
end
end
platform :ios do
lane :beta do
increment_build_number
build_app(scheme: "Runner")
upload_to_testflight
end
end
The model correctly separates the two platform blocks and reminds you that the Play service account JSON must be kept out of version control (use a CI secret store).
Putting it together: a solo sprint in practice
A realistic week for a solo dev using this set looks like: Monday, generate screens (Prompts 1–2) and lock state (Prompt 3). Tuesday, wire the native bridge (Prompts 5–6). Wednesday, performance pass (Prompts 7–8). Thursday, build troubleshooting and CI (Prompts 9, 12). Friday, release prep and compliance (Prompts 10–11). That is the shape of a three-person sprint compressed into one calendar week — not because the AI writes the whole app, but because it removes the context-switch tax between five different toolchains.
The honest caveat: AI-generated code still needs a human who understands the platform. A prompt that produces a TurboModule you cannot debug, or a -keep rule you cannot explain, is technical debt with extra steps. Use these prompts to get to a working draft faster, then read the official docs for the parts that touch money, privacy, or the platform channel. The developers who ship solo in 2026 are not the ones who prompt the most — they are the ones who review the output like a senior engineer, because that is exactly what they have to be.
Comments