Solo Mobile Dev, Three-Person Output: 12 Battle-Tested AI Prompts for Flutter, React Native and Kotlin Workflows

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:

  1. 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.
  2. 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.
  3. Never paste secrets. No API keys, no signing certificates, no .env contents. 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 CircleAvatar fallback), a name, a verified badge, a stats row (followers / following / posts), and a scrollable list of recent activity cards. Requirements: use StatelessWidget where possible, extract reusable sub-widgets, use const constructors everywhere legal, respect MediaQuery text scaling, and add Semantics labels 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 FlatList with keyExtractor, getItemLayout if item heights are fixed, and React.memo on row components. Show typing indicator state, send-button disabled state, and keyboard avoidance via KeyboardAvoidingView with platform-specific behavior. Do not use ScrollView for the message list. Explain why getItemLayout matters 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 + InheritedWidget for 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.IO for network and disk, expose a single Flow<Result<List<Article>>>, and handle retry with exponential backoff. Do not use GlobalScope. Show how the ViewModel collects it with repeatOnLifecycle. 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 name app/battery, invoked on the platform's main thread, result returned on the main thread, errors returned via result.error with a code and message, and Dart-side null-safety. Show the Kotlin side using configureFlutterEngine, the Swift side using FlutterMethodChannel in AppDelegate, and the Dart side. Then list the three most common causes of MissingPluginException and 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 codegenConfig entry for package.json, the Kotlin implementation, and the ReactPackage registration. Explain the difference between a TurboModule and a legacy ReactContextBaseJavaModule, 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, ListView without itemExtent when heights are fixed, expensive work in build(), Opacity instead of AnimatedOpacity, and saveLayer calls from ClipRRect with antiAlias. For each issue, give the DevTools timeline evidence you would look for and the fix. Do not suggest RepaintBoundary unless 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, avoid kapt where KSP is possible, remove unused annotation processors, and check android.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 stale Podfile.lock. Give the exact commands to run in order (including pod deintegrate, pod cache clean --all, and rm -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 Fastfile for a Flutter project that: builds a signed Android App Bundle with bundle exec fastlane supply, uploads to the Play internal track, builds and uploads an iOS build to TestFlight with pilot, and bumps the build number using increment_build_number. Use environment variables for credentials — never hardcode them. Add a lane :ci that runs both platforms. Explain the difference between supply and deliver, 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.

← All posts

Comments