Skip to content

Mobile App Development Interview Questions & Answers

All 200 unique questions in one place — 56 easy, 103 medium, 41 hard — grouped by topic.

Practise by topic

Solved overallStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What is the difference between native, cross-platform and hybrid mobile apps?

Save to ▾
Show answer
Native apps are written in platform languages, Kotlin for Android and Swift for iOS, with full access to platform APIs and the best performance. Cross-platform frameworks like Flutter and React Native share one codebase and render native-feeling UI, saving time for two platforms. Hybrid apps, such as Ionic or Cordova, run web code inside a WebView. Choice depends on performance needs, team skills, budget and how much platform-specific UI is required.
02

When would you choose a cross-platform framework over native development?

Save to ▾
Show answer
Choose cross-platform when you need both Android and iOS quickly with a small team, the app is mostly forms, lists, content and API-driven screens, and design consistency across platforms is desired. Choose native when the app needs heavy graphics, deep hardware integration, advanced background processing, newest platform features on day one, or very tight performance. Many companies mix both, using native modules inside a cross-platform app.
03

What is the difference between a debug and release build in mobile apps?

Save to ▾
Show answer
Debug builds include debugging tools, hot reload, assertions and unoptimised code, so they are slower and larger. Release builds are compiled ahead of time, minified, optimised and signed with a release key. In Flutter, debug uses JIT while profile and release use AOT compilation; in React Native, release bundles minified JavaScript precompiled to Hermes bytecode. Always measure performance and test critical flows on release or profile builds.
04

What is hot reload and how is it different from hot restart?

Save to ▾
Show answer
Hot reload injects changed code into the running app and rebuilds the UI while keeping the current state, so you see changes in about a second. Hot restart reloads the whole app code and resets state, needed when changing initialisation logic, global variables or app startup. React Native offers Fast Refresh, similar to hot reload. Native code changes, such as new plugins or platform files, require a full rebuild.
05

What is a WebView and when is it appropriate to use one?

Save to ▾
Show answer
A WebView embeds a browser engine in your app to show web content. It suits help pages, terms, payment gateway pages or quickly reusing an existing web flow. It is not ideal for core app screens because it feels slower and less native. Restrict navigation to trusted domains, avoid exposing powerful JavaScript bridges to untrusted content, and handle back navigation. Flutter uses webview_flutter and React Native uses react-native-webview.
06

Your app works on Android but crashes immediately on iOS when the user taps the camera button. What is the likely cause?

Save to ▾
Show answer
The most common cause is a missing NSCameraUsageDescription key in Info.plist. iOS terminates the app when it requests a protected resource without a usage description string. Add descriptions for camera, photo library, microphone and location as required by the plugin, written clearly for the user. Also verify the plugin's iOS setup steps, run pod install, and test on a real device since simulators lack cameras.
07

Why do you want to work in mobile app development?

Save to ▾
Show answer
Answer with genuine motivation and proof. For example: I enjoy building things people use every day in their pocket, and mobile gives fast feedback from real users. I started by building an attendance app for my college, published it for classmates, and improved it from their reviews. That experience of seeing ratings and usage grow made me choose mobile development as my career.
08

What is the role of a mobile developer in an Agile team?

Save to ▾
Show answer
A mobile developer turns user stories and designs into working app features, estimates tasks in sprint planning, raises technical risks early, and collaborates with backend, design and QA. They join standups, demos and retrospectives, review peers' code and keep builds releasable. They also give input on platform constraints like store review times and OS limits, which affect release planning more than in web development.
09

How does Flutter render UI differently from React Native?

Save to ▾
Show answer
Flutter draws every pixel itself using its own rendering engine, Impeller, onto a canvas, so widgets look identical across platforms and do not depend on native UI components. React Native maps components like View and Text to real native views, so the UI uses platform controls. Flutter gives pixel consistency and predictable performance; React Native gives native look and easier reuse of native view libraries, plus web developer familiarity with JavaScript.
10

Explain the mobile app lifecycle states on Android and iOS.

Save to ▾
Show answer
Both platforms move apps between foreground active, inactive, background and terminated states. On iOS, an app goes inactive during interruptions like calls, then background, where it gets limited time before suspension. On Android, activities move through resumed, paused and stopped, and the process can be killed in background. Cross-platform apps observe these through AppLifecycleListener in Flutter or AppState in React Native to pause work and save data.
11

What are the main differences between Android and iOS that a cross-platform developer must know?

Save to ▾
Show answer
Navigation patterns differ: Android has a system back gesture while iOS relies on swipe-back and navigation bars. Permissions, notification setup, background execution limits, file systems and store review rules differ. iOS builds require a Mac and Xcode, with signing through certificates and provisioning profiles. Design guidelines differ between Material Design and Human Interface Guidelines, so good cross-platform apps adapt some UI per platform.
12

What are runtime permissions and how do they differ between platforms?

Save to ▾
Show answer
Both platforms require runtime approval for sensitive features like camera, location, contacts and notifications. Android requires declarations in AndroidManifest.xml and runtime requests for dangerous permissions; iOS requires usage description strings in Info.plist, and the app crashes if a description is missing when requesting. iOS allows asking only once; later the user must change settings. Plugins like permission_handler or react-native-permissions unify the API.
13

What is responsive design in mobile apps and how do you handle different screen sizes?

Save to ▾
Show answer
Responsive design means layouts adapt to screen width, orientation, foldables and tablets instead of using fixed sizes. Use flexible layouts, percentages or flex, and breakpoints for compact, medium and expanded widths. In Flutter use LayoutBuilder and MediaQuery.sizeOf; in React Native use flexbox and useWindowDimensions. Respect safe areas for notches and system bars, support text scaling for accessibility, and test on small budget phones.
14

How do deep links and universal links work?

Save to ▾
Show answer
Deep links open a specific screen in your app from a URL. Custom schemes like myapp://order/42 work but are not verified. Verified HTTPS links are App Links on Android, using assetlinks.json, and Universal Links on iOS, using an apple-app-site-association file on your domain. When verified, the link opens your app directly instead of the browser. The routing library, like go_router or React Navigation linking, maps URLs to screens.
15

How do you design a mobile app for users on low-end devices and poor networks?

Save to ▾
Show answer
Keep the app size small, avoid heavy animations on low-end phones, and load images at the right resolution with caching. Use pagination and compressed API responses, cache data locally so screens open offline, and show skeleton loaders and clear retry options. Defer non-critical SDK initialisation to speed up startup. Test on budget devices with 2 or 3 GB RAM and throttled networks, since many users in India use them.
16

What is accessibility in mobile apps and how do you implement it?

Save to ▾
Show answer
Accessibility makes apps usable by people with disabilities. Provide labels for icons and images so screen readers like TalkBack and VoiceOver can announce them, keep touch targets at least 44 to 48 points, support dynamic text sizes, ensure colour contrast, and avoid conveying information only by colour. Flutter uses Semantics widgets, and React Native uses accessibilityLabel and accessibilityRole. Test with screen readers enabled.
17

A startup asks you to choose between Flutter, React Native and native for their new delivery app. How do you decide?

Save to ▾
Show answer
I would ask about team skills, timeline, budget, required features and long-term plans. If the team knows JavaScript and has a web app, React Native allows code and skill sharing. If they want a consistent custom UI and fast development from scratch, Flutter is strong. Heavy background location and maps work well in both with plugins, but if the app depends deeply on platform features, native may be safer. I would prototype one key screen first.
18

The client wants the app to look exactly like iOS on iPhones and like Material on Android. How do you approach this in a cross-platform app?

Save to ▾
Show answer
Identify which elements truly need platform-specific behaviour: navigation transitions, back gestures, date pickers, switches and dialogs. In Flutter, use adaptive constructors like Switch.adaptive or Cupertino widgets based on Theme.of(context).platform. In React Native, many components are native already, and Platform.select handles differences. Keep shared business logic and most layout common, and limit platform branches to a component library so they stay manageable.
19

How would you structure the folder layout of a medium-sized cross-platform app?

Save to ▾
Show answer
Organise by feature rather than by type: features/auth, features/cart, features/profile, each containing UI, state logic and data code. Keep shared pieces in core folders such as core/network, core/storage, core/theme and core/widgets or components. Put configuration for environments separately. This keeps related code together, makes ownership clear and lets features be moved into packages later. Enforce the structure with lint rules and code review.
20

How do you set up multiple environments such as dev, staging and production in a mobile app?

Save to ▾
Show answer
Create build flavours on Android and schemes or configurations on iOS, each with its own app ID suffix, app name, icon and API base URL, so all can be installed side by side. In Flutter, use --flavor with --dart-define-from-file for config values; in React Native, use react-native-config or Expo app config with environment variables. Keep secrets out of the repo and set them in CI.
21

What questions would you ask before estimating a new mobile app project?

Save to ▾
Show answer
I would ask about target platforms and minimum OS versions, user types and key flows, design readiness, backend availability and API documentation, offline needs, payments, notifications, analytics, third-party SDKs, security or compliance requirements, languages to support, and release expectations including store accounts. I would also ask who maintains the app afterward. Then I break features into tasks, estimate with a buffer for store review and testing.
22

Tell me about a time you had to learn a new framework under a deadline.

Save to ▾
Show answer
Situation: my team decided to build a client app in Flutter, and I had only React Native experience. Task: deliver the login and dashboard screens in three weeks. Action: I completed the official codelabs in the first week, mapped concepts I knew like components and hooks to widgets and state, and asked for early code reviews. Result: the screens shipped on time, and I later wrote a short guide for other React Native developers moving to Flutter.
23

How do you balance speed and quality when a client wants features fast?

Save to ▾
Show answer
I agree on what quality means for this release, such as no crashes in key flows, working offline basics and tests for payment logic. I deliver the smallest useful version first, behind feature flags if needed, and avoid shortcuts in areas that are expensive to fix later, like data models and security. I make technical debt visible in the backlog with an estimate so it is planned rather than forgotten.
24

Users say the app does not work properly on foldable phones and tablets. What do you check?

Save to ▾
Show answer
Check whether orientation is locked, layouts use fixed widths, and screens assume phone dimensions. Make layouts adapt by width breakpoints with two-pane layouts on wide screens, handle configuration and size changes without losing state, and avoid hardcoding aspect ratios. Recent Android versions ignore orientation locks on large screens, so locking is no longer a fix. Test with resizable emulators, foldable postures and split-screen mode.
25

How do you think about mobile system design for a chat feature?

Save to ▾
Show answer
Start with requirements: one-to-one or group, media, read receipts, offline sending. The client keeps a local database as source of truth, shows sent messages instantly with a pending status, and syncs over a WebSocket while foregrounded, using push notifications in background. Handle reconnection, ordering by server timestamps, pagination of history, and retries with idempotent message IDs. Encrypt sensitive data and limit media size before upload.
26

What is Dart and why does Flutter use it?

Save to ▾
Show answer
Dart is a typed, object-oriented language created for client development. Flutter uses it because Dart supports JIT compilation for fast hot reload in development and AOT compilation to native machine code for fast release apps. Dart has sound null safety, async-await, isolates for concurrency, and a garbage collector optimised for many short-lived objects, which suits Flutter's frequent widget rebuilding.
27

Explain sound null safety in Dart.

Save to ▾
Show answer
Since Dart 3, all code is null safe. Types are non-nullable by default, so String cannot hold null while String? can. The compiler forces you to handle nulls with checks, the ?. and ?? operators, or the ! operator which throws if null. The late keyword declares a non-null variable initialised later. Sound means the compiler can trust non-null types completely, enabling optimisations and preventing many runtime null errors.
28

What is the difference between final and const in Dart?

Save to ▾
Show answer
final means a variable is assigned once at runtime and cannot be reassigned. const means the value is a compile-time constant and deeply immutable. In Flutter, const constructors like const Text("Hello") let the framework reuse the same widget instance across rebuilds, skipping unnecessary work. Use const wherever possible for widgets with fixed values; the linter rule prefer_const_constructors helps enforce it.
29

What is the difference between StatelessWidget and StatefulWidget?

Save to ▾
Show answer
A StatelessWidget has no mutable state; its build output depends only on constructor parameters and inherited data. A StatefulWidget creates a State object that persists across rebuilds and holds mutable data; calling setState marks it dirty so build runs again. Use stateful widgets for local UI state like animations, text controllers or toggles, and lift shared or business state into a state management solution.
30

How do Future, async and await work in Dart?

Save to ▾
Show answer
A Future represents a value that will be available later, like an HTTP response. Marking a function async lets it use await, which pauses that function until the Future completes without blocking the event loop. Errors are handled with try-catch. Dart runs on a single-threaded event loop per isolate, so awaiting network calls keeps the UI responsive. Use Future.wait to run independent futures concurrently.
31

Write a simple counter using StatefulWidget and setState.

Save to ▾
Show answer
class Counter extends StatefulWidget { const Counter({super.key}); @override State<Counter> createState() => _CounterState(); } class _CounterState extends State<Counter> { int _count = 0; @override Widget build(BuildContext context) => Column( mainAxisSize: MainAxisSize.min, children: [ Text('Count: $_count'), FilledButton( onPressed: () => setState(() => _count++), child: const Text('Add'), ), ], ); }
32

Explain Row, Column, Expanded and Flexible in Flutter layouts.

Save to ▾
Show answer
Row lays out children horizontally and Column vertically, with mainAxisAlignment and crossAxisAlignment controlling placement. Expanded forces a child to fill remaining space along the main axis, and Flexible lets a child take up to its share but be smaller. Using flex values divides space proportionally. A common error is an unbounded width or height, such as a ListView inside a Column without Expanded, which throws a layout exception.
33

What is the difference between ListView and ListView.builder?

Save to ▾
Show answer
The default ListView constructor builds all children at once, which is fine for a few items. ListView.builder builds items lazily as they scroll into view, using itemBuilder and itemCount, so it handles long or infinite lists efficiently. For mixed scrolling content like headers, grids and lists together, use CustomScrollView with slivers. For large lists, also set item extent or use prototypeItem to improve scroll performance.
34

A Flutter screen shows a yellow and black overflow stripe on small phones. How do you fix it?

Save to ▾
Show answer
The overflow stripe means content exceeds the available space, often a Row with long text or a Column taller than the screen. Wrap text in Expanded or Flexible with overflow ellipsis, make the screen scrollable with SingleChildScrollView or a ListView, use LayoutBuilder to adapt for narrow widths, and avoid fixed heights. Also handle the keyboard by allowing the content to scroll when it opens.
35

Write a Dart model class with fromJson and toJson.

Save to ▾
Show answer
class Product { const Product({required this.id, required this.name, required this.price}); final String id; final String name; final double price; factory Product.fromJson(Map<String, dynamic> json) => Product( id: json['id'] as String, name: json['name'] as String, price: (json['price'] as num).toDouble(), ); Map<String, dynamic> toJson() => {'id': id, 'name': name, 'price': price}; } // For larger apps use json_serializable or freezed to generate this.
36

Describe a time you helped a teammate who was stuck on a problem.

Save to ▾
Show answer
Situation: a new teammate spent two days on a Flutter layout that kept overflowing. Task: help without taking over. Action: I sat with them, showed how to use the widget inspector to see constraints, and explained the constraints go down, sizes go up rule with their own screen. Result: they fixed it in an hour and later solved similar issues alone. I also added the explanation to our team wiki.
37

What is BuildContext?

Save to ▾
Show answer
BuildContext is a handle to a widget's location in the element tree. It is used to look up inherited data like Theme.of(context), MediaQuery and Navigator, and providers. Each widget's build method gets its own context. Common mistakes are using a context from above a widget that provides data, or using a context after an async gap when the widget may be unmounted; check context.mounted before using it after await.
38

Explain the StatefulWidget lifecycle methods.

Save to ▾
Show answer
createState creates the State. initState runs once for setup like controllers and subscriptions; do not use inherited widgets there. didChangeDependencies runs after initState and when inherited data changes. build runs on every rebuild. didUpdateWidget runs when the parent rebuilds with new configuration. dispose runs when removed permanently, where you cancel streams, dispose controllers and timers to avoid memory leaks.
39

What are keys in Flutter and when do you need them?

Save to ▾
Show answer
Keys help Flutter match widgets to existing elements and state when the widget list changes. Without keys, Flutter matches by type and position, so reordering or removing items in a list of stateful widgets can attach state to the wrong item. Use ValueKey with a unique ID for list items, UniqueKey to force recreation, and GlobalKey rarely, for accessing state across the tree such as a Form.
40

What is a Stream in Dart and how is it used in Flutter?

Save to ▾
Show answer
A Stream delivers a sequence of asynchronous events, such as real-time database updates, location changes or WebSocket messages. You listen with listen() or await for, and transform with map, where and debounce from packages. Single-subscription streams allow one listener; broadcast streams allow many. In Flutter, StreamBuilder rebuilds UI on each event. Always cancel subscriptions in dispose to prevent leaks.
41

What are isolates and when should you use them?

Save to ▾
Show answer
Isolates are Dart's units of concurrency, each with its own memory and event loop, communicating by messages. Heavy CPU work like parsing a large JSON file, image processing or encryption on the main isolate causes jank. Use Isolate.run or compute to run such work in a separate isolate and return the result. For network or file I/O, async-await is enough because that work is not CPU-bound.
42

Write a Dart sealed class for API results and handle it with an exhaustive switch.

Save to ▾
Show answer
sealed class Result<T> {} class Success<T> extends Result<T> { Success(this.data); final T data; } class Failure<T> extends Result<T> { Failure(this.message); final String message; } Widget view(Result<List<String>> r) => switch (r) { Success(:final data) => ListView(children: [for (final s in data) Text(s)]), Failure(:final message) => Center(child: Text(message)), };
43

Write a Flutter screen that fetches a list from an API using FutureBuilder.

Save to ▾
Show answer
class UsersPage extends StatefulWidget { const UsersPage({super.key}); @override State<UsersPage> createState() => _UsersPageState(); } class _UsersPageState extends State<UsersPage> { late final Future<List<User>> _future = api.fetchUsers(); @override Widget build(BuildContext context) => FutureBuilder<List<User>>( future: _future, builder: (context, snap) { if (snap.connectionState != ConnectionState.done) { return const Center(child: CircularProgressIndicator()); } if (snap.hasError) return const Center(child: Text('Something went wrong')); final users = snap.data!; return ListView.builder( itemCount: users.length, itemBuilder: (_, i) => ListTile(title: Text(users[i].name)), ); }, ); }
44

After an API call finishes, the app throws an error about using BuildContext across async gaps or setState after dispose. How do you fix it?

Save to ▾
Show answer
The user left the screen before the Future completed, so the widget was unmounted. Before using context or calling setState after await, check if (!context.mounted) return; or if (!mounted) return; in State. Better still, move async logic out of widgets into a state management layer that the UI listens to, and cancel subscriptions or timers in dispose so no callbacks run on a dead widget.
45

Parsing a 10 MB JSON file freezes the Flutter UI for two seconds. How do you fix it?

Save to ▾
Show answer
JSON decoding is CPU-bound and runs on the main isolate, blocking frames. Move it to a background isolate with Isolate.run(() => parseProducts(jsonString)) or compute. Also consider whether the API can paginate or return less data, and parse lazily. Test in profile mode with DevTools performance view to confirm the frame time improvement, since debug mode exaggerates slowness.
46

How do you create reusable custom widgets in Flutter?

Save to ▾
Show answer
Extract repeated UI into a StatelessWidget class with clear constructor parameters, rather than helper methods that return widgets, because classes get their own element, can be const and rebuild independently. Accept callbacks for events, use the theme for colours and text styles, and provide sensible defaults. Group them into a shared widgets folder or design system package and document them with widget previews or a showcase screen.
47

How do you implement a form with validation in Flutter?

Save to ▾
Show answer
Wrap fields in a Form with a GlobalKey<FormState>, use TextFormField with a validator function that returns an error string or null, and call formKey.currentState!.validate() on submit. Use TextEditingController for values and dispose it, set keyboardType and textInputAction for each field, and autovalidateMode onUserInteraction to show errors as the user types. Keep validation rules in testable functions outside widgets.
48

Explain the three trees in Flutter: widget, element and render object.

Save to ▾
Show answer
Widgets are lightweight, immutable descriptions of UI created on every build. Elements are the mounted instances that hold a widget's position in the tree and link to State; they are reused when a new widget of the same type and key appears. RenderObjects handle layout, painting and hit testing, and are expensive, so Flutter updates them only when needed. This design makes frequent rebuilds cheap.
49

What are records and patterns in Dart 3?

Save to ▾
Show answer
Records are anonymous, immutable aggregates like (String, int) or ({String name, int age}), useful for returning multiple values without creating a class. Patterns let you destructure values and match shapes in switch expressions and if-case statements. Combined with sealed classes, switch can be exhaustive, so the compiler warns when a case is missing. They make state handling and parsing code shorter and safer.
50

How does Flutter's layout rule of constraints go down, sizes go up work?

Save to ▾
Show answer
A parent passes constraints, minimum and maximum width and height, to each child. The child chooses its size within those constraints and reports it up, then the parent positions the child. A widget cannot choose a size outside its constraints, which explains why a Container with width 100 may still fill the screen if forced by tight constraints. Understanding this rule solves most overflow and unbounded constraint errors.
51

Why do Flutter apps need a state management solution beyond setState?

Save to ▾
Show answer
setState works for local UI state inside one widget, but shared state like the logged-in user, cart or settings must be read and changed by many screens. Passing it through constructors becomes messy, and rebuilding large trees hurts performance. State management libraries separate business logic from UI, make state testable, rebuild only widgets that depend on changed data, and give a clear, predictable flow of updates.
52

How do you handle navigation in Flutter with go_router?

Save to ▾
Show answer
go_router is a declarative, URL-based routing package maintained by the Flutter team. You define GoRoute entries with paths like /product/:id, navigate with context.go or context.push, and read parameters from state.pathParameters. It supports nested navigation with ShellRoute for bottom tabs, redirects for authentication guards, and deep links on mobile and web. It wraps the Router API, which is complex to use directly.
53

How do you handle app-wide theming and dark mode in Flutter?

Save to ▾
Show answer
Define ThemeData for light and dark modes in MaterialApp, using ColorScheme.fromSeed to generate consistent Material 3 colours, and set themeMode from a settings state, saved in shared preferences. Widgets read Theme.of(context).colorScheme and textTheme instead of hardcoded colours. Add ThemeExtension classes for brand-specific tokens. This keeps the design consistent and makes switching themes a single state change.
54

How do you explain your architecture choices to a new team member?

Save to ▾
Show answer
I start with the problem each layer solves, using one real feature from our app to trace a user tap through widget, state notifier, repository and API, and back to the UI. I share a short diagram and the team's architecture document, then give them a small task touching every layer. I review their first pull request closely and invite questions so they understand the reasons, not only the rules.
55

What is InheritedWidget and how does Provider build on it?

Save to ▾
Show answer
InheritedWidget lets descendants read data efficiently via context and rebuild when it changes, which is how Theme and MediaQuery work. Writing it by hand is verbose. Provider wraps InheritedWidget with a simpler API: ChangeNotifierProvider exposes a ChangeNotifier, and widgets use context.watch to rebuild or context.read to call methods without rebuilding. It is simple and suitable for small to medium apps.
56

Compare Provider, Riverpod and Bloc.

Save to ▾
Show answer
Provider is simple and built on InheritedWidget but depends on BuildContext and can throw provider-not-found errors at runtime. Riverpod, from the same author, is compile-safe, independent of the widget tree, supports async providers and easy overrides for testing. Bloc uses events and states with streams, enforcing strict separation and traceability, popular in large teams and enterprises. Choose based on team familiarity and app complexity.
57

Explain the Bloc pattern and Cubit.

Save to ▾
Show answer
In Bloc, the UI adds events, the Bloc handles them with on<Event> handlers and emits new immutable states, and widgets rebuild with BlocBuilder or react with BlocListener. A Cubit is a simpler version where the UI calls methods directly and the Cubit emits states, without event classes. Use Cubit for straightforward logic and full Bloc when you need event transformations like debounce or detailed traceability.
58

Write a Cubit that loads products and emits loading, success and error states.

Save to ▾
Show answer
sealed class ProductState {} class ProductLoading extends ProductState {} class ProductLoaded extends ProductState { ProductLoaded(this.items); final List<Product> items; } class ProductError extends ProductState { ProductError(this.message); final String message; } class ProductCubit extends Cubit<ProductState> { ProductCubit(this._repo) : super(ProductLoading()); final ProductRepository _repo; Future<void> load() async { emit(ProductLoading()); try { emit(ProductLoaded(await _repo.fetchProducts())); } catch (_) { emit(ProductError('Could not load products')); } } }
59

Write a Riverpod provider that fetches data asynchronously and display it in a widget.

Save to ▾
Show answer
final productsProvider = FutureProvider.autoDispose<List<Product>>((ref) { final repo = ref.watch(productRepositoryProvider); return repo.fetchProducts(); }); class ProductsView extends ConsumerWidget { const ProductsView({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final products = ref.watch(productsProvider); return products.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => const Center(child: Text('Failed to load')), data: (items) => ListView(children: [for (final p in items) ListTile(title: Text(p.name))]), ); } }
60

What is clean architecture in a Flutter app?

Save to ▾
Show answer
Clean architecture separates code into presentation (widgets and state notifiers or blocs), domain (entities, use cases and repository interfaces) and data (repository implementations, API clients, local storage and DTOs). Dependencies point inward, so the domain knows nothing about Flutter or HTTP. It improves testability and lets you swap data sources. For small apps it may be heavy, so many teams keep presentation and data layers and add domain only when logic grows.
61

Write a go_router configuration with an auth redirect.

Save to ▾
Show answer
final router = GoRouter( initialLocation: '/', refreshListenable: authNotifier, redirect: (context, state) { final loggedIn = authNotifier.isLoggedIn; final goingToLogin = state.matchedLocation == '/login'; if (!loggedIn && !goingToLogin) return '/login'; if (loggedIn && goingToLogin) return '/'; return null; }, routes: [ GoRoute(path: '/', builder: (_, __) => const HomePage()), GoRoute(path: '/login', builder: (_, __) => const LoginPage()), GoRoute( path: '/product/:id', builder: (_, state) => ProductPage(id: state.pathParameters['id']!), ), ], );
62

What is dependency injection in Flutter and how is it done?

Save to ▾
Show answer
Dependency injection supplies objects like API clients and repositories from outside instead of creating them inside widgets or blocs. In Flutter it is commonly done with Riverpod providers, Provider or RepositoryProvider in Bloc, or a service locator like get_it, sometimes with injectable for code generation. It makes code testable because tests can override dependencies with fakes, and it centralises object lifetimes.
63

What is the freezed package used for?

Save to ▾
Show answer
freezed generates immutable data classes with copyWith, equality, toString and union types or sealed classes, and integrates with json_serializable for fromJson and toJson. It removes boilerplate when modelling state such as loading, data and error variants. You annotate a class, run build_runner, and get generated code in a part file. With Dart 3 sealed classes and records, some teams need it less, but it is still widely used.
64

How would you test a Bloc or Riverpod notifier?

Save to ▾
Show answer
Test business logic without widgets. For Bloc, the bloc_test package's blocTest builds the bloc with a fake repository, acts by adding events, and expects a list of emitted states. For Riverpod, create a ProviderContainer with overrides for repository providers, read the notifier, call methods and assert the state. Use mocktail for mocks and keep tests fast, deterministic and independent of the network.
65

The cart total shows stale values on the checkout screen after items are removed on the cart screen. How do you fix it?

Save to ▾
Show answer
Each screen probably holds its own copy of cart data. Move cart state into a single shared state object, such as a Riverpod notifier or a Cubit provided above both screens, and have both screens watch it. All mutations go through that object, which emits a new immutable state. Derived values like total should be computed from the state, not stored separately, so they can never become inconsistent.
66

Your Flutter codebase mixes setState, Provider and get_it randomly across screens. How would you clean it up?

Save to ▾
Show answer
Agree on one approach with the team, for example Riverpod for app state and setState only for local widget state, and document examples. Migrate gradually, starting with the most buggy or most changed features, and write tests before moving logic. Add lint rules and pull request checklists so new code follows the standard. Avoid a big-bang rewrite that blocks feature work for weeks.
67

How do you manage form state and validation across multiple steps in a Flutter onboarding flow?

Save to ▾
Show answer
Keep the onboarding data in one state object owned by a notifier or cubit scoped to the flow, with each step updating its part. Validate per step before moving forward and again on final submit. Save progress locally so users can resume if they leave. Keep validation rules in pure functions that are unit tested. Dispose the state when the flow completes so data does not leak into later sessions.
68

What is the difference between ref.watch, ref.read and ref.listen in Riverpod?

Save to ▾
Show answer
ref.watch subscribes to a provider and rebuilds the widget or recomputes the provider when it changes; use it in build methods. ref.read gets the current value once without subscribing; use it in callbacks like onPressed to call notifier methods. ref.listen runs a callback when a provider changes without rebuilding, useful for side effects like showing a snackbar or navigating after a state change.
69

Tell me about a technical decision you made that you later regretted, and what you learned.

Save to ▾
Show answer
Situation: on an earlier project I chose a lesser-known state management package because it looked simpler. Task: support the app as it grew. Action: when the package stopped being maintained, I led a migration to Riverpod feature by feature with tests. Result: the migration took three sprints. I learned to evaluate packages by maintenance activity, community size and testing support, not just initial simplicity, and to document decisions.
70

How do you avoid unnecessary rebuilds in a Flutter app with state management?

Save to ▾
Show answer
Rebuild only what depends on the changed data. Use selectors such as context.select, ref.watch(provider.select(...)) or BlocSelector to listen to one field, split big widgets into smaller ones, and use const constructors. Keep state objects immutable with proper equality so identical states do not trigger rebuilds. Use Flutter DevTools rebuild tracking to find widgets that rebuild more often than expected.
71

A Bloc emits the same state twice and the UI does not update. Why?

Save to ▾
Show answer
Bloc and Cubit skip emitting a state that is equal to the current one. If you mutate a list inside the existing state and emit the same object, equality holds and nothing rebuilds. Always emit a new state with copied collections, for example state.copyWith(items: [...state.items, newItem]), and implement equality with Equatable or freezed. Avoid mutable fields in state classes.
72

How do you handle a logout that must clear all user data across the app?

Save to ▾
Show answer
Centralise session state in an auth provider or bloc that other state depends on. On logout, clear secure tokens, wipe local databases or caches for that user, reset or invalidate dependent providers, for example by Riverpod providers watching the auth state, and redirect with the router guard to login. Cancel ongoing requests and background jobs. Test that no previous user's data appears after logging in as someone else.
73

The app needs a bottom navigation bar where each tab keeps its own navigation history. How do you implement it?

Save to ▾
Show answer
Use go_router's StatefulShellRoute.indexedStack, which creates a separate navigator branch for each tab and keeps their stacks alive with an IndexedStack. The scaffold shows a NavigationBar and switches branches with navigationShell.goBranch(index). This preserves scroll positions and nested pages when switching tabs, and deep links can open a specific tab and page. Handle tapping the active tab to pop to its root.
74

You are designing a large Flutter app for a bank with 30 developers. How do you structure it?

Save to ▾
Show answer
Split the app into feature packages in a monorepo managed with Melos or pub workspaces, plus core packages for networking, design system, analytics and security. Pick one state management approach, such as Bloc for strict traceability, with clear layer boundaries. Use code generation consistently, enforce lints and architecture tests in CI, and assign feature ownership. Add integration tests for critical journeys and strict security reviews for storage and network code.
75

Users lose their place in a long Flutter form when they get a phone call and the app is killed in background. How do you fix it?

Save to ▾
Show answer
The operating system may kill the app process in background, and in-memory state is lost. Save draft form data to local storage, such as shared_preferences, Hive or a SQLite table, as the user types with a short debounce, and restore it when the screen opens. Flutter's RestorationMixin and restorationScopeId can restore simple UI state like scroll position and text fields. Clear the draft after successful submission.
76

What is an Expo project and how does it differ from a bare React Native project?

Save to ▾
Show answer
Expo is a framework and toolset for React Native that provides prebuilt native modules, file-based routing with Expo Router, EAS cloud builds and over-the-air updates. With Continuous Native Generation, Expo creates the android and ios folders from app config and config plugins, so you rarely edit native code. A bare project manages native folders directly. Expo is now the officially recommended way to start React Native apps.
77

What is React Native and how does it work?

Save to ▾
Show answer
React Native lets you build mobile apps with React and JavaScript or TypeScript. You write components like View, Text and Image, and React Native renders them as real native views on Android and iOS. JavaScript runs on the Hermes engine, and with the New Architecture it communicates with native code directly through JSI rather than an asynchronous JSON bridge. Business logic and most UI code are shared between platforms.
78

Explain the core React Native components.

Save to ▾
Show answer
View is the basic container, like a div, supporting flexbox layout and styles. Text displays text, and all strings must be inside Text. Image shows images from network or local sources. TextInput handles keyboard input. Pressable handles touches with press states. ScrollView scrolls a small amount of content, while FlatList and SectionList render long lists virtually. SafeAreaView or the safe area context library keeps content away from notches.
79

How does styling and layout work in React Native?

Save to ▾
Show answer
Styles are JavaScript objects created with StyleSheet.create, using camelCase properties like backgroundColor. Layout uses flexbox through the Yoga engine, with flexDirection defaulting to column, unlike the web. Units are density-independent pixels without px. There is no CSS cascade, so styles are applied per component and composed with arrays. Libraries like NativeWind bring Tailwind-style classes, and themes are usually provided through context.
80

What is the difference between ScrollView and FlatList?

Save to ▾
Show answer
ScrollView renders all its children at once, which is fine for short content but uses lots of memory and slows rendering for long lists. FlatList virtualises, rendering only items near the viewport and recycling as you scroll, with props like keyExtractor, initialNumToRender and windowSize. For very large or complex lists, FlashList offers better recycling and performance. Never nest a FlatList inside a ScrollView of the same direction.
81

Explain useState and useEffect in React Native.

Save to ▾
Show answer
useState stores local state and returns the value and a setter; calling the setter re-renders the component. useEffect runs side effects after render, like fetching data or subscribing to events, with a dependency array controlling when it re-runs, and a returned cleanup function to unsubscribe. Missing dependencies cause stale values, while unstable dependencies cause loops. For data fetching, libraries like TanStack Query are usually better than raw useEffect.
82

Why is TypeScript recommended for React Native projects?

Save to ▾
Show answer
TypeScript adds static types to JavaScript, catching mistakes like wrong prop names, missing fields in API responses and undefined values at compile time. It improves editor autocomplete and makes refactoring safer in large codebases. New React Native and Expo templates use TypeScript by default, and Codegen for TurboModules and Fabric components uses typed specs. Combined with strict mode, it significantly reduces runtime crashes.
83

How do you handle platform-specific code in React Native?

Save to ▾
Show answer
Use Platform.OS checks or Platform.select({ ios: ..., android: ... }) for small differences in styles or behaviour. For larger differences, create files with platform extensions like DatePicker.ios.tsx and DatePicker.android.tsx, and the bundler picks the right one automatically. Keep platform branches inside small components so screens stay shared. Native platform differences, such as permissions setup, are configured in native files or Expo config plugins.
84

A React Native app shows a red screen error in development: Text strings must be rendered within a Text component. What does it mean?

Save to ▾
Show answer
React Native requires every string to be inside a Text component. The error usually appears when a string or a number is placed directly inside a View, or when a conditional like {count && <Badge />} renders 0 as text when count is zero. Wrap text in Text and use explicit conditions like {count > 0 ? <Badge /> : null} so falsy values are not rendered as raw strings.
85

How do you handle feedback that your code is not good enough?

Save to ▾
Show answer
I treat it as information, not a personal attack. I ask for specific examples and what better looks like, fix the issues, and look for patterns so I do not repeat them. Early in my career, a reviewer pointed out that my components were too large; I learned to split them and write small hooks, and my review comments dropped steadily after that. I also thank reviewers for their time.
86

What is Hermes and why is it the default engine?

Save to ▾
Show answer
Hermes is a JavaScript engine optimised for React Native. It compiles JavaScript to bytecode at build time, so the app does not parse and compile JavaScript on startup, which reduces time to interactive, memory use and app size. It is the default engine on Android and iOS. It supports debugging with Chrome DevTools-based tools and sampling profiling to find slow JavaScript.
87

What are useMemo, useCallback and React.memo used for?

Save to ▾
Show answer
React.memo skips re-rendering a component when its props are shallowly equal. useCallback keeps the same function reference between renders, and useMemo caches a computed value, both only changing when dependencies change. They help when passing callbacks to memoised list items or computing expensive values. Overusing them adds complexity with little gain; the React Compiler can now apply such memoisation automatically in supported projects.
88

Write a FlatList that shows products with pull-to-refresh and infinite scroll.

Save to ▾
Show answer
function ProductList({ items, loading, onRefresh, onEndReached }) { const renderItem = useCallback(({ item }) => <ProductRow product={item} />, []); return ( <FlatList data={items} keyExtractor={(item) => item.id} renderItem={renderItem} refreshing={loading} onRefresh={onRefresh} onEndReached={onEndReached} onEndReachedThreshold={0.5} ListEmptyComponent={!loading ? <Text>No products</Text> : null} /> ); }
89

Write a custom hook that fetches data with loading and error states.

Save to ▾
Show answer
function useFetch(url) { const [state, setState] = useState({ data: null, loading: true, error: null }); useEffect(() => { const controller = new AbortController(); fetch(url, { signal: controller.signal }) .then((r) => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }) .then((data) => setState({ data, loading: false, error: null })) .catch((e) => { if (e.name !== 'AbortError') setState({ data: null, loading: false, error: e.message }); }); return () => controller.abort(); }, [url]); return state; }
90

What is Metro?

Save to ▾
Show answer
Metro is the JavaScript bundler for React Native. It resolves modules, transforms code with Babel, and serves the bundle to the app during development with Fast Refresh. For release builds, it produces a minified bundle that is compiled to Hermes bytecode. It supports platform-specific extensions, asset handling and configuration in metro.config.js for things like SVG transformers or monorepo setups with watch folders.
91

How does the keyboard affect layouts in React Native and how do you handle it?

Save to ▾
Show answer
When the keyboard opens it can cover inputs, especially at the bottom of the screen. Use KeyboardAvoidingView with behavior padding on iOS, and rely on Android's adjustResize window setting, or use react-native-keyboard-controller for consistent behaviour on both. Wrap forms in a ScrollView with keyboardShouldPersistTaps set to handled so buttons work while the keyboard is open, and dismiss the keyboard on submit.
92

A React Native list of 2000 items scrolls slowly and shows blank areas. How do you fix it?

Save to ▾
Show answer
Use FlatList or FlashList rather than ScrollView with map. Provide a stable keyExtractor, memoise row components with React.memo, avoid inline functions and heavy computation in renderItem, and use getItemLayout or fixed item sizes where possible. Tune windowSize and maxToRenderPerBatch, compress and cache images with a library like expo-image, and test a release build, since dev mode is much slower.
93

A screen re-renders every time the user types in a search box, making it laggy. How do you fix it?

Save to ▾
Show answer
Keep the search text state local to the search input component so only it re-renders, debounce the query before updating the list or calling the API, and memoise the list and row components. Avoid storing frequently changing values in a global store that many components subscribe to. Use the React DevTools profiler to confirm which components render, and useDeferredValue to keep typing responsive.
94

Your web team wants to reuse React code in the mobile app. How much can realistically be shared?

Save to ▾
Show answer
Business logic, API clients, validation, state management, types and utility hooks can be shared through a monorepo package. UI components usually cannot be shared directly because web uses DOM elements and mobile uses native components, unless you adopt React Native for Web or a universal design system. Navigation and storage differ too. Plan a shared core package and platform-specific UI to avoid forcing awkward compromises.
95

How do you debug a React Native app?

Save to ▾
Show answer
Use React Native DevTools, the default debugger since 0.76, for console logs, breakpoints, React component inspection and profiling. Inspect network requests with the network panel or a proxy. For native crashes, check Logcat in Android Studio and the Xcode console. Use the performance monitor overlay for frame rates, and add a crash reporting tool like Sentry or Crashlytics for production errors with source maps uploaded.
96

Describe a time you had to deliver a feature with incomplete requirements.

Save to ▾
Show answer
Situation: product asked for a referral feature with only a one-line description. Task: deliver in a sprint. Action: I listed open questions, met the product manager for 20 minutes to agree on core rules, built the agreed version with configurable reward values from the backend, and documented assumptions in the ticket. Result: we shipped on time, and later changes needed only config updates instead of a new release.
97

Write a React Native component that requests location permission and shows the coordinates using Expo.

Save to ▾
Show answer
import * as Location from 'expo-location'; export function MyLocation() { const [coords, setCoords] = useState(null); const [error, setError] = useState(null); useEffect(() => { (async () => { const { status } = await Location.requestForegroundPermissionsAsync(); if (status !== 'granted') { setError('Location permission denied'); return; } const pos = await Location.getCurrentPositionAsync({}); setCoords(pos.coords); })(); }, []); if (error) return <Text>{error}</Text>; if (!coords) return <ActivityIndicator />; return <Text>{coords.latitude}, {coords.longitude}</Text>; }
98

What is the React Native New Architecture?

Save to ▾
Show answer
The New Architecture, enabled by default since React Native 0.76, replaces the old asynchronous bridge. JSI lets JavaScript hold references to C++ objects and call native methods synchronously. Fabric is the new renderer supporting concurrent React features and synchronous layout. TurboModules load native modules lazily with typed interfaces generated by Codegen. Bridgeless mode removes the bridge entirely. Together they improve startup, responsiveness and type safety.
99

How do native modules work, and when do you write one?

Save to ▾
Show answer
A native module exposes platform code written in Kotlin, Java, Swift or Objective-C to JavaScript. With the New Architecture, you define a typed TypeScript spec, Codegen generates interfaces, and the TurboModule implements them natively. Expo Modules API offers a simpler way using Swift and Kotlin. You write one when no library supports a needed SDK or device feature, such as a specific payment or biometric SDK.
100

After upgrading React Native, a third-party library breaks on the New Architecture. What do you do?

Save to ▾
Show answer
Check the library's documentation and the React Native directory for New Architecture support, and update to the latest version, since many libraries added support. The interop layer often lets old-architecture modules work, so read the error carefully. If unsupported, look for a maintained alternative, contribute a fix or patch with patch-package, or temporarily keep the old architecture only if your version still allows it, while planning a replacement.
101

How does navigation work in React Native with React Navigation?

Save to ▾
Show answer
React Navigation provides navigators: native stack for push and pop screens using platform transitions, bottom tabs, drawer and material top tabs. You nest navigators, for example tabs inside a root stack with modal screens. Screens receive navigation and route props or use hooks like useNavigation and useRoute. Version 7 adds a static configuration API for better TypeScript inference and automatic deep link setup.
102

How do you pass parameters between screens and type them safely?

Save to ▾
Show answer
Pass small, serialisable params like IDs with navigation.navigate('Details', { id }), and read them with route.params. Define a param list type, such as type RootStackParamList = { Details: { id: string } }, and use it with the navigator and hooks for type checking. Avoid passing functions or large objects, which break state persistence and deep linking; fetch full data on the destination screen.
103

How do you stay productive when working with both Android and iOS platforms?

Save to ▾
Show answer
I test every feature on one Android device and one iPhone or simulator before raising a pull request, keep a checklist of common platform differences like permissions, keyboard and safe areas, and use CI builds for both platforms on each merge. I learn basic Kotlin and Swift so I can read native errors and logs. This avoids late surprises when QA tests the second platform.
104
Save to ▾
Show answer
Expo Router is a file-based router built on React Navigation. Files in the app directory become routes, so app/product/[id].tsx maps to /product/42. Layout files define stacks and tabs, and every screen is deep-linkable automatically on mobile and web. It supports typed routes, protected routes for auth, and API routes. It reduces navigation boilerplate and makes URL-based linking consistent across platforms.
105

Write a React Navigation setup with a stack containing a tab navigator and a details screen.

Save to ▾
Show answer
const Tab = createBottomTabNavigator(); const Stack = createNativeStackNavigator(); function HomeTabs() { return ( <Tab.Navigator> <Tab.Screen name="Feed" component={FeedScreen} /> <Tab.Screen name="Profile" component={ProfileScreen} /> </Tab.Navigator> ); } export default function App() { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Home" component={HomeTabs} options={{ headerShown: false }} /> <Stack.Screen name="Details" component={DetailsScreen} /> </Stack.Navigator> </NavigationContainer> ); }
106

Compare Redux Toolkit, Zustand and React Context for state in React Native.

Save to ▾
Show answer
Context is built in and fine for rarely changing values like theme or auth, but every consumer re-renders on change. Redux Toolkit gives a predictable global store with slices, middleware and excellent DevTools, suited to large teams, and RTK Query handles API caching. Zustand is small and simple, with selector-based subscriptions that limit re-renders. Server data is often better handled by TanStack Query than by any global store.
107

Why use TanStack Query for server state in mobile apps?

Save to ▾
Show answer
Server state, such as data fetched from APIs, has caching, refetching, staleness and retry concerns that client state libraries do not handle well. TanStack Query caches responses by query keys, deduplicates requests, refetches on focus or reconnect, supports pagination and infinite queries, optimistic updates and offline persistence. It removes large amounts of useEffect and loading-state code and keeps screens consistent.
108

Write a Redux Toolkit slice for a cart.

Save to ▾
Show answer
const cartSlice = createSlice({ name: 'cart', initialState: { items: [] }, reducers: { addItem(state, action) { const existing = state.items.find((i) => i.id === action.payload.id); if (existing) existing.qty += 1; else state.items.push({ ...action.payload, qty: 1 }); }, removeItem(state, action) { state.items = state.items.filter((i) => i.id !== action.payload); }, }, }); export const { addItem, removeItem } = cartSlice.actions; export const selectTotal = (s) => s.cart.items.reduce((t, i) => t + i.price * i.qty, 0);
109

How do you implement authentication flow screens in React Navigation?

Save to ▾
Show answer
Conditionally render screen groups based on auth state: if the user is signed out, the navigator shows login and signup; when signed in, it shows the app screens. Changing state automatically switches stacks and prevents going back to login with the back button. Restore tokens from secure storage on startup while showing a splash screen. Expo Router offers protected routes for the same pattern.
110

What are optimistic updates and how do you implement them?

Save to ▾
Show answer
An optimistic update changes the UI immediately as if the server request succeeded, such as liking a post, then rolls back if the request fails. It makes apps feel fast on slow networks. With TanStack Query, use onMutate to update the cache and save the previous value, onError to restore it, and onSettled to refetch. Use it for low-risk actions, not payments.
111

A global Redux store causes the whole app to re-render on every small change. How do you fix it?

Save to ▾
Show answer
Components are probably selecting large parts of state or creating new objects in selectors. Select only the fields each component needs with useSelector, memoise derived data with createSelector, and keep state normalised. Move server data to RTK Query or TanStack Query and local UI state back into components. Verify improvements with the React profiler, checking which components render after each action.
112

Deep links open the app but land on the home screen instead of the product page. How do you debug it?

Save to ▾
Show answer
Check that the link configuration maps the URL path to the right screen name, including nested navigators, and that path parameters match. Verify verified link setup on both platforms: assetlinks.json for Android and the associated domains entitlement plus the site association file for iOS. Test with adb shell am start and xcrun simctl openurl. Also handle links when the app is cold started versus already running.
113

The product team wants the same app on mobile and web from one codebase. What would you propose?

Save to ▾
Show answer
With React Native, Expo with Expo Router and React Native Web lets one codebase target Android, iOS and web, with file-based routes working as URLs. With Flutter, the web target exists but suits app-like experiences more than SEO-heavy pages. I would share business logic and most screens, keep SEO landing pages on a web framework, and plan for platform-specific tweaks like hover states and keyboard navigation.
114

How do you handle gestures such as swipe to delete in React Native?

Save to ▾
Show answer
Use react-native-gesture-handler, which processes gestures on the native side, often with Reanimated for smooth animations. For swipe to delete, the Swipeable or ReanimatedSwipeable component renders action buttons behind a row. Define gestures with the Gesture API, such as Gesture.Pan, and compose them when needed. Wrap the app root in GestureHandlerRootView. Provide an accessible alternative like a long-press menu for screen reader users.
115

How do you persist state in React Native between app launches?

Save to ▾
Show answer
For small key-value data use AsyncStorage or MMKV, which is much faster and synchronous. Persist Redux with redux-persist or Zustand with its persist middleware, choosing only the slices that need it. Store tokens in secure storage like expo-secure-store or Keychain and Keystore wrappers, never in plain storage. For larger structured data use SQLite through expo-sqlite or an ORM like WatermelonDB.
116

How do you handle error boundaries in a React Native app?

Save to ▾
Show answer
An error boundary is a class component, or a library like react-error-boundary, that catches rendering errors in its child tree and shows a fallback UI instead of crashing the whole app. Place one at the app root and around risky screens. They do not catch errors in event handlers or async code, so use try-catch there. Report caught errors to a crash reporting tool with context for debugging.
117

How would you migrate a large React Native app from JavaScript to TypeScript?

Save to ▾
Show answer
Enable TypeScript with allowJs so both coexist, start with a relaxed tsconfig, and convert shared code first: API types, models, utilities and navigation param lists. Then convert screens feature by feature, tightening strict options gradually. Add type checks to CI so new files must be TypeScript. Avoid using any to silence errors; use unknown and narrow. Track progress and celebrate milestones to keep momentum.
118

Tell me about a time you improved app performance in a cross-platform app.

Save to ▾
Show answer
Situation: our React Native order history screen took three seconds to render and scrolled poorly. Task: make it smooth. Action: I profiled with React Native DevTools, replaced ScrollView with FlashList, memoised rows, moved date formatting into the API layer and switched images to a caching library. Result: render time dropped below 600 milliseconds, and frame drops nearly disappeared on budget phones.
119

What would you do if you joined a project and found the codebase poorly structured?

Save to ▾
Show answer
I would first understand why it is that way, since deadlines and changing requirements often explain it. I would document the main pain points with examples, such as frequent bugs in a module, and propose small improvements tied to upcoming features rather than a rewrite. I would add tests around risky areas first. Showing measurable wins, like fewer bugs, builds trust for larger refactors later.
120

How do animations work in React Native and why use Reanimated?

Save to ▾
Show answer
The built-in Animated API can run animations on the native thread with useNativeDriver for transform and opacity, but not for layout properties. Reanimated runs animation logic in worklets on the UI thread, so animations stay smooth even if JavaScript is busy, and supports gestures, layout animations and shared element transitions. Combined with react-native-gesture-handler, it is the standard for complex interactive animations.
121

What are the JS thread and UI thread in React Native and why do they matter?

Save to ▾
Show answer
JavaScript, including React rendering and business logic, runs on the JS thread, while the native UI thread draws views and handles touches. If the JS thread is busy with heavy computation or large re-renders, taps and JS-driven animations lag even though the UI thread is free. Keep heavy work off the JS thread, move animations to the UI thread with Reanimated, and split expensive tasks into smaller chunks.
122

How do you write a Fabric native component or use one in React Native?

Save to ▾
Show answer
A Fabric component wraps a native view for use in JavaScript. You write a TypeScript spec using codegenNativeComponent with typed props, run Codegen to generate C++ and platform interfaces, and implement the view in Kotlin and Objective-C or Swift. With Expo, the Expo Modules API lets you define a native view in Kotlin and Swift with less boilerplate. Use this for maps, video players or custom SDK views.
123

The JS bundle grew large and startup is slow. How do you reduce startup time in React Native?

Save to ▾
Show answer
Measure time to interactive on a release build first. Make sure Hermes is enabled, remove unused dependencies and heavy libraries like full date or icon packs, and lazy-load screens and modules with inline requires. Defer non-critical SDK initialisation until after the first screen. Keep the initial screen light, avoid large synchronous storage reads at startup, and use the New Architecture for faster native module loading.
124

An animation stutters whenever the screen fetches data. How do you fix it?

Save to ▾
Show answer
The animation likely runs on the JS thread, and data parsing or re-renders block it. Move the animation to the UI thread with Reanimated or Animated with useNativeDriver, reduce the work done when data arrives by memoising components and normalising state updates, and delay heavy processing with InteractionManager or requestIdleCallback-style scheduling until the animation finishes. Profile with React Native DevTools to confirm.
125

Your app needs a third-party SDK that has only native Android and iOS libraries. How do you integrate it in React Native?

Save to ▾
Show answer
First check whether a maintained wrapper package exists. If not, create a native module using the Expo Modules API or a TurboModule with a typed spec, add the SDK through Gradle and CocoaPods or Swift Package Manager, and expose a small JavaScript API with promises and events. If using Expo, write a config plugin to apply native setup during prebuild. Test on both platforms and document the setup.
126

What backend options are common for mobile apps?

Save to ▾
Show answer
Teams build custom REST or GraphQL APIs with Node.js, Java Spring Boot, Python or Go, hosted on cloud platforms. Backend-as-a-Service options like Firebase and Supabase provide authentication, databases, storage, functions and push notifications without managing servers, which suits startups and MVPs. Larger apps often combine a custom backend for business logic with managed services for auth, analytics and messaging.
127

What is Firebase and which services do mobile apps commonly use?

Save to ▾
Show answer
Firebase is a mobile and web development platform. Commonly used services are Authentication for email, phone OTP and social logins; Cloud Firestore and Realtime Database for synced data; Cloud Storage for files; Cloud Functions for server code; Cloud Messaging for push notifications; Crashlytics for crash reports; Analytics; Remote Config for feature flags; and App Distribution for testers. FlutterFire and React Native Firebase provide SDKs.
128

What local storage options exist for Flutter and React Native apps?

Save to ▾
Show answer
For simple key-value settings, Flutter uses shared_preferences and React Native uses AsyncStorage or MMKV. For sensitive data, flutter_secure_storage or expo-secure-store use Keychain and Keystore. For structured data and queries, use SQLite via sqflite or drift in Flutter and expo-sqlite or WatermelonDB in React Native. Object stores like Isar, Hive or Realm also exist, but check maintenance status before choosing.
129

Where should you keep API keys and secrets in a mobile app?

Save to ▾
Show answer
Anything bundled in a mobile app can be extracted by decompiling, so never ship true secrets like payment secret keys or admin credentials. Keep them on your backend and let the app call your server. Public client keys, such as maps or Firebase config, are acceptable but should be restricted by app package name, bundle ID and certificate fingerprint. Use environment configuration in CI rather than committing keys to the repository.
130

How do you handle API errors gracefully in the UI?

Save to ▾
Show answer
Map errors into categories in the data layer: no internet, timeout, server error, unauthorised and validation errors with field messages. The UI shows a friendly message and a retry action for network issues, inline messages for validation, and redirects to login for unauthorised. Keep cached data visible when refresh fails. Log unexpected errors to crash reporting with request context but never sensitive data.
131

Tell me about a time you worked with a backend developer to fix an integration issue.

Save to ▾
Show answer
Situation: our app showed wrong prices after a discount launch. Task: find whether the app or API was at fault. Action: I captured the failing request and response with a proxy, shared it with the backend developer, and we found the API returned paise in one endpoint and rupees in another. We agreed on one format, updated the contract document and added a test. Result: the bug was fixed the same day.
132

What is the difference between a BaaS and a custom backend for a mobile startup?

Save to ▾
Show answer
A Backend-as-a-Service gives ready authentication, database, storage and functions, so a small team launches faster without managing servers, and costs stay low at small scale. A custom backend gives full control over business logic, data model, integrations and cost at large scale, but needs more engineering effort. Many startups begin with BaaS for the MVP and gradually move complex or expensive parts to custom services.
133

How do you secure Cloud Firestore data accessed directly from a mobile app?

Save to ▾
Show answer
Because the app talks to the database directly, security rules are the backend. Write rules that check request.auth for authentication and that users can read or write only their own documents, for example allow read, write: if request.auth.uid == userId. Validate fields and types in rules, never leave test mode rules open, and move sensitive operations like payments or role changes to Cloud Functions. Test rules with the emulator suite.
134

How does token-based authentication work in mobile apps?

Save to ▾
Show answer
The user signs in and the server returns a short-lived access token, often a JWT, and a longer-lived refresh token. The app stores them securely in Keychain or Keystore-backed storage and sends the access token in the Authorization header. When it expires, the app uses the refresh token to get a new one, retrying the failed request. On logout, tokens are deleted and ideally revoked on the server.
135

Write a Dart HTTP client using dio with an interceptor that adds an auth token.

Save to ▾
Show answer
final dio = Dio(BaseOptions( baseUrl: 'https://api.example.com', connectTimeout: const Duration(seconds: 10), receiveTimeout: const Duration(seconds: 15), )); dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) async { final token = await secureStorage.read(key: 'access_token'); if (token != null) options.headers['Authorization'] = 'Bearer $token'; handler.next(options); }, onError: (e, handler) { if (e.response?.statusCode == 401) authNotifier.logout(); handler.next(e); }, ));
136

How do push notifications work end to end?

Save to ▾
Show answer
The app registers with the platform push service, FCM on Android and APNs on iOS, often both through FCM, and receives a device token. The app sends this token to your backend, linked to the user. When an event happens, the backend sends a message to FCM or APNs with the token, which delivers it to the device. The app requests notification permission, handles taps to open the right screen, and refreshes tokens when they change.
137

What is the difference between REST and GraphQL for mobile clients?

Save to ▾
Show answer
REST exposes resources at fixed endpoints, which can lead to over-fetching or many round trips for one screen. GraphQL exposes one endpoint where the client asks exactly for the fields it needs, reducing payload size and requests, which helps on slow mobile networks. GraphQL adds complexity in caching, error handling and server performance. Clients like Apollo or graphql_flutter provide normalised caching and code generation.
138

How do you implement OTP login with a phone number?

Save to ▾
Show answer
The user enters a phone number, the backend or an auth service sends an OTP via SMS and returns a verification ID. The user enters the code, which is verified to issue session tokens. On Android, use the SMS Retriever or User Consent API to auto-read the code without SMS permissions; on iOS, set the text content type to one-time code for autofill. Rate-limit requests, expire codes quickly and protect against abuse.
139

Push notifications arrive on Android but not on iOS. How do you debug it?

Save to ▾
Show answer
Check that the push notifications capability and background modes are enabled in Xcode, that an APNs authentication key is uploaded to the push provider, and that notification permission was granted. Verify the app gets an APNs token and the provider token, and that the right environment, development or production, is used. Test on a real device, since simulators have limited push support, and check payload format.
140

The API responses are slow on mobile networks. What can the mobile team ask the backend team to change?

Save to ▾
Show answer
Ask for pagination with sensible page sizes, gzip or brotli compression, removing unused fields or providing screen-specific endpoints, and aggregated endpoints to avoid multiple sequential calls. Request proper cache headers and ETags so the client can reuse responses. Ask for resized images through a CDN and HTTP/2 or HTTP/3 support. Share measured timings from real devices to justify the requests.
141

How do you handle pressure when a production issue affects many users?

Save to ▾
Show answer
I stay calm and focus on reducing impact first: confirm the issue, communicate status to the team, and look for the fastest safe mitigation such as a remote config switch, server-side fix or pausing a rollout. Then I find the root cause, ship a proper fix and write a short postmortem. Clear, regular updates to stakeholders reduce panic and let others plan around the issue.
142

What is Supabase and how does it compare to Firebase?

Save to ▾
Show answer
Supabase is an open-source backend platform built on PostgreSQL, offering authentication, a relational database with auto-generated APIs, row level security, storage, edge functions and real-time subscriptions. Firebase uses NoSQL databases like Firestore. Supabase suits apps with relational data and SQL needs, and can be self-hosted, while Firebase has a richer mobile ecosystem including Crashlytics, Remote Config and FCM. Many apps combine them.
143

How do you design an offline-first mobile app?

Save to ▾
Show answer
Store data in a local database and render the UI from it, so the app works without network. Queue user changes locally with a pending status and sync them in the background when connectivity returns, using retries with backoff. Fetch server changes using timestamps or sync tokens and merge them. Resolve conflicts with clear rules like last write wins or server authority, and show sync status to users.
144

How do you integrate a payment gateway in a mobile app safely?

Save to ▾
Show answer
Create the order on your backend with the amount, get an order ID, and open the gateway's SDK checkout in the app with that ID. After payment, the SDK returns a payment ID and signature, which the app sends to the backend to verify with the secret key before marking the order paid. Rely on server-side webhooks as the final truth. Never keep secret keys in the app or trust client-side success alone.
145

Write a React Native function that uploads an image with progress using Expo FileSystem.

Save to ▾
Show answer
import * as FileSystem from 'expo-file-system'; export async function uploadImage(uri, token, onProgress) { const task = FileSystem.createUploadTask( 'https://api.example.com/upload', uri, { httpMethod: 'POST', uploadType: FileSystem.FileSystemUploadType.MULTIPART, fieldName: 'file', headers: { Authorization: `Bearer ${token}` }, }, ({ totalBytesSent, totalBytesExpectedToSend }) => onProgress(totalBytesSent / totalBytesExpectedToSend) ); const res = await task.uploadAsync(); if (res.status !== 200) throw new Error('Upload failed'); return JSON.parse(res.body); }
146

Users get logged out randomly. The access token refresh seems to fail sometimes. What could be wrong?

Save to ▾
Show answer
A common cause is a race condition: several requests receive 401 at once and each triggers a refresh, so later refreshes use an already rotated refresh token and fail, logging the user out. Fix it by allowing only one refresh at a time and queueing other requests until it completes, then retrying them with the new token. Also check device clock issues, token expiry settings and secure storage read failures.
147

The Firestore bill is growing fast because of too many reads. How do you reduce it?

Save to ▾
Show answer
Find screens that listen to large collections or re-read data on every rebuild. Paginate queries with limits, listen only to needed documents, detach listeners when screens close, and avoid starting listeners inside build methods. Denormalise data to reduce reads per screen, cache data locally with offline persistence, and use aggregate count queries instead of reading all documents to count. Monitor usage per collection.
148

A payment shows success in the app but the order is not created on the server. How would you fix the flow?

Save to ▾
Show answer
The app is probably treating the SDK's success callback as final and the verification call failed or was never sent, for example when the app was killed. Make the backend the source of truth: verify payments with the gateway's signature on the server and use webhooks to update orders even if the app never reports back. The app should poll order status after payment and show a pending state until confirmed.
149

Your app must show live delivery partner location on a map. How would you design it?

Save to ▾
Show answer
The partner app sends location updates every few seconds through a foreground service to the backend, which publishes them to a real-time channel like WebSockets or Firestore documents. The customer app subscribes only while the tracking screen is open and smoothly animates the marker between points. Throttle updates, reconnect on network changes, and fall back to polling. Stop tracking when the delivery completes to save battery.
150

Two users editing the same shared list offline create conflicting changes. How do you resolve conflicts?

Save to ▾
Show answer
Choose a strategy based on data. Last write wins, using server timestamps, is simple but can lose edits. Field-level merging keeps non-conflicting changes. For lists, treat each item as a separate record with its own version so edits rarely clash. For collaborative content, CRDT-based approaches merge automatically. Always let the server decide final order, and show users when their change was overwritten.
151

What types of tests do you write in Flutter?

Save to ▾
Show answer
Unit tests check pure Dart logic like validators, repositories and state notifiers. Widget tests render a single widget or screen in a test environment with WidgetTester, simulate taps and text entry, and assert what appears, running fast without a device. Integration tests, using the integration_test package, run the full app on a device or emulator for end-to-end flows. Golden tests compare widget screenshots to catch visual regressions.
152

Write a Flutter widget test that taps a button and checks the counter text.

Save to ▾
Show answer
testWidgets('increments counter on tap', (tester) async { await tester.pumpWidget(const MaterialApp(home: Scaffold(body: Counter()))); expect(find.text('Count: 0'), findsOneWidget); await tester.tap(find.text('Add')); await tester.pump(); expect(find.text('Count: 1'), findsOneWidget); });
153

How do you test React Native components?

Save to ▾
Show answer
Use Jest as the test runner with React Native Testing Library, which renders components and queries them the way users do, by text, role or label. Fire events like fireEvent.press or userEvent, then assert on output. Mock native modules and network calls with jest mocks or MSW. For end-to-end tests on real builds, use Detox or Maestro, which drive the app on emulators and simulators.
154

Write a React Native Testing Library test for a login button showing a validation error.

Save to ▾
Show answer
import { render, screen, fireEvent } from '@testing-library/react-native'; test('shows error when email is empty', () => { render(<LoginScreen onSubmit={jest.fn()} />); fireEvent.press(screen.getByRole('button', { name: 'Login' })); expect(screen.getByText('Email is required')).toBeTruthy(); });
155

How do you monitor crashes and performance in production?

Save to ▾
Show answer
Integrate a crash reporting tool like Firebase Crashlytics or Sentry, upload debug symbols, dSYMs and source maps so stack traces are readable, and record non-fatal errors with context. Track crash-free users, ANR rate, app start time, slow frames and network latency per release. Set alerts on spikes and review store vitals. Tag events with app version, device and OS so problems can be isolated quickly.
156

How do you make sure your code works before handing it to QA?

Save to ▾
Show answer
I test the happy path and edge cases myself on both Android and iOS, including no network, slow network, empty states, large text sizes and rotation. I write unit tests for logic and run the existing test suite. I review my own diff before raising the pull request and add clear testing notes for QA explaining what changed and what to check, which saves time for both of us.
157

What is Maestro and why do mobile teams use it?

Save to ▾
Show answer
Maestro is an open-source mobile UI testing framework where flows are written in simple YAML, such as launchApp, tapOn "Login" and assertVisible "Welcome". It works with native, Flutter and React Native apps on Android and iOS, handles waiting automatically, and reduces flakiness compared to many older tools. Teams use it for smoke tests of critical journeys in CI because tests are quick to write and readable by QA.
158

How do you measure performance in a Flutter app?

Save to ▾
Show answer
Run the app in profile mode on a real device, not debug or emulator. Use Flutter DevTools: the performance view shows frame build and raster times, the CPU profiler finds expensive functions, and the memory view tracks allocations and leaks. Target under about 16 milliseconds per frame for 60 fps. The performance overlay shows UI and raster thread graphs, and rebuild tracking highlights widgets rebuilding too often.
159

How do you reduce app size for Flutter and React Native apps?

Save to ▾
Show answer
Publish Android App Bundles so users download only their architecture and density resources. In Flutter, use --split-debug-info and --obfuscate, remove unused packages and fonts, compress images and use tree-shaken icons. In React Native, enable Hermes, R8 minification and resource shrinking, and remove heavy libraries. For both, analyse size with tools like flutter build --analyze-size or APK Analyzer and lazy-load large assets.
160

How do you detect and fix memory leaks in cross-platform apps?

Save to ▾
Show answer
Leaks usually come from subscriptions, timers, controllers and listeners that are never disposed, or global caches that grow without limits. In Flutter, dispose controllers and cancel stream subscriptions in dispose, and check the DevTools memory view for growing instances. In React Native, return cleanup functions from useEffect and remove event listeners. Repeatedly open and close a screen while profiling to confirm memory returns to baseline.
161

How do you set up CI/CD for a cross-platform mobile app?

Save to ▾
Show answer
On every pull request, run lint, formatting checks, unit and widget or component tests. On merge, build signed Android and iOS release artifacts using CI services such as GitHub Actions, Codemagic, Bitrise or EAS Build, with signing keys stored as secrets. Use fastlane or EAS Submit to upload to internal testing tracks and TestFlight. Automate version numbers, generate release notes and run smoke tests with Maestro.
162

Write a GitHub Actions workflow that runs Flutter tests on every pull request.

Save to ▾
Show answer
name: flutter-ci on: pull_request: branches: [main] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: channel: stable cache: true - run: flutter pub get - run: dart format --set-exit-if-changed . - run: flutter analyze - run: flutter test --coverage
163

What security practices should every mobile app follow?

Save to ▾
Show answer
Use HTTPS everywhere and consider certificate pinning for high-risk apps. Store tokens only in secure storage, never log sensitive data, and keep secrets on the server. Obfuscate release builds, validate all input on the server, and protect sensitive screens from screenshots where needed. Check device integrity with platform attestation APIs for high-risk actions, and follow the OWASP Mobile Application Security Verification Standard as a checklist.
164

Integration tests pass locally but fail randomly in CI. How do you make them reliable?

Save to ▾
Show answer
Flaky tests usually come from timing assumptions, shared state, network dependence or slow emulators. Replace fixed delays with waiting for specific conditions, mock or stub network calls with predictable responses, reset app data between tests, and use stable selectors like keys or test IDs instead of text that changes. Give CI emulators enough resources, retry only as a temporary measure, and track flaky tests separately to fix them.
165

After a release, crash reports show a spike only on one Android OS version. What steps do you take?

Save to ▾
Show answer
Pause the staged rollout to limit impact. Filter crash reports by OS version and device to find the top stack trace, and check behaviour changes for that version, such as permission, background or edge-to-edge rules. Reproduce on an emulator of that version, fix it, add a regression test and resume rollout with a hotfix. Add that OS version to the regular test device matrix.
166

Your team has no automated tests and frequent regressions. How would you introduce testing?

Save to ▾
Show answer
Start where bugs hurt most: write unit tests for business logic like pricing, validation and state transitions, and a few end-to-end smoke tests for login, checkout and payment flows with Maestro or integration tests. Run them in CI on every pull request so failures block merges. Require tests for bug fixes going forward. Show reduced regressions after a few sprints to build team support.
167

A security audit finds that the app stores the access token in plain shared preferences. How do you fix it?

Save to ▾
Show answer
Move tokens to secure storage backed by Keychain on iOS and Keystore on Android, such as flutter_secure_storage or expo-secure-store. Migrate existing users by reading the old value once, writing it securely and deleting the plain copy. Shorten access token lifetime, use refresh tokens, exclude sensitive files from backups, and clear tokens on logout. Retest with the audit team to confirm the issue is closed.
168

How do you decide which devices to test on for an Indian user base?

Save to ▾
Show answer
Use analytics from the existing app or market data to identify the most common manufacturers, OS versions, screen sizes and RAM levels among your users. Cover a budget device with 3 to 4 GB RAM, a mid-range phone, a recent flagship, an older OS version you still support, and at least one iPhone and tablet. Use cloud device farms for wider coverage and add devices that generate many crashes.
169

What is Impeller in Flutter?

Save to ▾
Show answer
Impeller is Flutter's rendering engine that replaced Skia as the default on iOS and on modern Android devices. It precompiles a smaller set of shaders at build time instead of compiling them at runtime, which removes the shader compilation jank that first-time animations used to cause. It provides more predictable frame times. Developers rarely interact with it directly, but they should test on real devices when upgrading Flutter.
170

A Flutter animation is smooth on a flagship phone but janky on a budget phone. How do you fix it?

Save to ▾
Show answer
Profile on the budget device in profile mode. Common fixes: wrap frequently repainting areas in RepaintBoundary, avoid expensive effects like Opacity on large subtrees, clipping and shadows in scrolling lists, use AnimatedBuilder with child so static parts do not rebuild, precache images and decode them at display size, and move heavy computation to isolates. Reduce animation complexity on low-end devices if needed.
171

The app takes six seconds to start on low-end phones. How do you improve it?

Save to ▾
Show answer
Measure cold start on a release or profile build and trace what runs before the first frame. Defer non-critical SDK initialisation such as analytics and ads, avoid large synchronous storage reads and network calls before showing UI, load the first screen with cached data, and lazy-load other features. In Flutter, keep main() light; in React Native, use Hermes and inline requires. Use a native splash screen to avoid a blank screen.
172

QA reports the app becomes slower the longer it is used. How do you investigate?

Save to ▾
Show answer
This suggests a memory leak or growing work. Reproduce by repeating a flow many times while profiling memory and CPU. Look for listeners, timers or subscriptions that accumulate, caches without limits, lists that keep growing, or screens kept in the navigation stack. Fix by disposing resources, limiting cache sizes and replacing screens instead of pushing endlessly. Confirm memory returns to baseline after fixes.
173

How would you set quality gates before a mobile release?

Save to ▾
Show answer
Define clear criteria: all automated tests pass, no open critical or high bugs, crash-free rate in beta above an agreed threshold like 99.5 percent, performance budgets for startup time and app size met, accessibility checks on new screens, and security review for sensitive changes. Run smoke tests on the release build on real devices. Release with a staged rollout and monitor metrics before expanding.
174

Tell me about a bug that was hard to reproduce and how you solved it.

Save to ▾
Show answer
Situation: some users reported a blank screen after login, but no one on the team could reproduce it. Task: find the cause. Action: I added breadcrumb logs and non-fatal error reports around the login flow, and found it happened when the device clock was wrong, making tokens appear expired. I changed expiry checks to rely on server responses. Result: reports stopped, and we kept the breadcrumbs for future debugging.
175

What is a performance budget and how do you enforce it?

Save to ▾
Show answer
A performance budget sets limits on metrics like cold start time, app download size, frame rendering time and memory usage. Enforce it by measuring in CI, for example tracking release build size per pull request and running startup benchmarks on a reference device, and failing or flagging builds that exceed limits. Budgets make performance a shared responsibility rather than something fixed only after users complain.
176

What are the steps to publish an app on the Play Store?

Save to ▾
Show answer
Create a Play Console developer account, create the app and fill in store listing details, screenshots, privacy policy, content rating, data safety and target audience forms. Build a signed release App Bundle with a unique application ID and increasing versionCode, and use Play App Signing. Upload to internal or closed testing first, then promote to production with a staged rollout. New personal accounts must complete a closed test with testers before production access.
177

What are the steps to publish an iOS app on the App Store?

Save to ▾
Show answer
Enrol in the developer program, create an App ID and the app record in App Store Connect, and set up signing with certificates and provisioning profiles, often managed automatically by Xcode or EAS. Archive the release build with an incremented build number, upload it, and test through TestFlight. Complete metadata, screenshots, privacy nutrition labels and age rating, then submit for review. After approval, release manually, automatically or in phased release.
178

What are versionName, versionCode and build numbers?

Save to ▾
Show answer
On Android, versionName is the user-visible version like 2.3.1 and versionCode is an integer that must increase with every upload. On iOS, CFBundleShortVersionString is the marketing version and CFBundleVersion is the build number, which must be unique per version upload. In Flutter, the pubspec version 2.3.1+45 sets both; in Expo, version and the platform build numbers are set in app config and can auto-increment with EAS.
179

What are TestFlight and Play testing tracks?

Save to ▾
Show answer
TestFlight distributes iOS beta builds to internal testers on your team and external testers, up to 10,000, after a light beta review. Play Console offers internal testing for quick distribution to up to 100 testers, closed testing for selected groups, and open testing for anyone to join. Using these tracks catches device-specific bugs and gathers feedback before production, and staged rollouts then limit risk further.
180

Write a release checklist for a mobile app update.

Save to ▾
Show answer
1. Bump version name and build number on both platforms. 2. Run full automated tests and smoke tests on release builds. 3. Verify signing, obfuscation and debug symbol upload. 4. Check new permissions and update store privacy declarations. 5. Update release notes and screenshots if UI changed. 6. Upload to internal track and TestFlight; QA sign-off. 7. Submit for review with reviewer notes and demo account. 8. Start staged rollout at 5 to 10 percent. 9. Monitor crashes, ANRs, reviews and key metrics. 10. Expand rollout or halt and hotfix.
181

Tell me about an app you published and what you learned from real users.

Save to ▾
Show answer
Situation: I published a notes app with a friend and got about 2,000 installs. Task: improve ratings stuck at 3.6. Action: I read every review, found users disliked losing notes when switching phones, added cloud backup and a clear onboarding screen, and fixed two crashes from Crashlytics. Result: rating rose to 4.4 in two months. I learned to prioritise what users actually complain about over features I assumed they wanted.
182

Why are you interested in this mobile developer role at our company?

Save to ▾
Show answer
Connect your skills to the role honestly. For example: your app serves millions of users in tier 2 and tier 3 cities, and I have focused on performance for budget phones and slow networks in my projects. I have shipped two cross-platform apps to both stores, and I want to work where release quality and user experience matter at scale. I also like that your team uses Flutter, which I enjoy and want to master.
183

What is app signing and why must you protect the keys?

Save to ▾
Show answer
Signing proves the app comes from you and that updates are from the same developer. On Android, you sign uploads with an upload key and Play App Signing re-signs with the app signing key held by the store; a lost upload key can be reset, but losing a self-managed app key meant you could never update the app. On iOS, signing uses certificates and provisioning profiles. Store keys in a secure vault and CI secrets, never in the repository.
184

What are over-the-air updates and what are their limits?

Save to ▾
Show answer
Over-the-air updates push new JavaScript bundles and assets to React Native apps without a store release, using services like EAS Update. They fix bugs quickly but can only change JavaScript and assets, not native code, permissions or SDK versions, which need a new build. Store policies allow them only if the app's core purpose does not change. Use runtime versions to ensure updates match compatible native builds, and roll out gradually.
185

What are privacy declarations required by the app stores?

Save to ▾
Show answer
The Play Store requires a data safety form describing what data is collected, shared, encrypted and deletable, plus a privacy policy link and account deletion option for apps with accounts. The iOS App Store requires privacy nutrition labels, a privacy manifest file for the app and listed third-party SDKs describing data use and required reason APIs, and App Tracking Transparency permission before tracking users across apps.
186

How do you build a release version of a Flutter app for both stores?

Save to ▾
Show answer
flutter build appbundle --release --obfuscate --split-debug-info=build/symbols # Output: build/app/outputs/bundle/release/app-release.aab flutter build ipa --release --obfuscate --split-debug-info=build/symbols # Output: build/ios/ipa/*.ipa, upload with Transporter or xcrun altool # Version comes from pubspec.yaml, for example: # version: 2.3.1+45 (name 2.3.1, build number 45)
187

Write an EAS configuration for development, preview and production builds.

Save to ▾
Show answer
{ "cli": { "version": ">= 12.0.0" }, "build": { "development": { "developmentClient": true, "distribution": "internal" }, "preview": { "distribution": "internal", "channel": "preview" }, "production": { "autoIncrement": true, "channel": "production" } }, "submit": { "production": {} } }
188

What is App Store Optimisation and what can a developer influence?

Save to ▾
Show answer
App Store Optimisation improves an app's visibility and conversion in store search. Key factors are the app title, subtitle or short description, keywords, long description, screenshots, preview videos, ratings and reviews. Developers influence it by keeping app size small, crash rates low and performance high, since store algorithms consider quality signals, by adding in-app review prompts at good moments, and by supporting localisation for regional languages.
189

How do you force users to update when an old version has a critical bug?

Save to ▾
Show answer
Keep a minimum supported version in remote config or an API endpoint, check it at startup and show a blocking update screen linking to the store. On Android, use the Play In-App Updates API with the immediate flow for critical updates and flexible flow for normal ones. Keep the backend compatible with older versions for a defined period, and use forced updates sparingly because they frustrate users.
190

Your iOS app was rejected for guideline 5.1.1 about data collection. What do you do?

Save to ▾
Show answer
Read the reviewer's message in App Store Connect carefully. Guideline 5.1.1 issues often involve requesting permissions without clear purpose strings, requiring sign-up for features that do not need an account, or missing account deletion. Fix the specific problem, for example improving usage description text or adding in-app account deletion, and reply in Resolution Center explaining the changes. Ask for clarification if the rejection is unclear.
191

Store review is delaying your launch date. How do you plan releases to avoid this?

Save to ▾
Show answer
Submit builds early, a few days before the planned date, and use manual release so you can publish the approved build at launch time. Ship the code behind a remote feature flag so the feature can be enabled on launch day without a new review. Keep a pre-approved build ready, follow store guidelines closely and include clear review notes and demo login details for reviewers.
192

A user reports that they cannot find your app in the store on their old phone. Why could this happen?

Save to ▾
Show answer
The app may not be available for their device because the minimum OS version is higher than theirs, the device lacks a required hardware feature declared in the manifest, the app is not released in their country, or the device architecture is excluded. Check the device catalogue in Play Console and the deployment target on iOS. Decide whether supporting that segment is worth lowering requirements.
193

How do you communicate a delayed release to stakeholders?

Save to ▾
Show answer
I inform them as soon as I know, not on the release day. I explain the reason briefly, such as a store rejection or critical bug, the impact, the new estimated date, and what we are doing to avoid repeating it. I offer options, like releasing other features first. Regular short updates until release keep trust, and I note learnings in the release retrospective.
194

How do you handle account deletion requirements in mobile apps?

Save to ▾
Show answer
Both major stores require apps that let users create accounts to also let them delete their account from within the app, and the Play Store also requires a web link for deletion requests. Implement a clear settings option, confirm the action, call a backend endpoint that deletes or anonymises user data according to retention rules, revoke tokens, clear local data and sign the user out. Document what is retained for legal reasons.
195

The Play Store flagged your app because a third-party SDK collects data not declared in the data safety form. How do you handle it?

Save to ▾
Show answer
Identify the SDK and what it collects using its documentation and the Play SDK Index. Update the data safety form to declare that data accurately, or configure the SDK to stop collecting it, or replace it if its behaviour is unacceptable. Update the privacy policy too. Then submit a new build if code changed. Keep an inventory of SDKs and their data practices to avoid future surprises.
196

A critical bug reaches production in a React Native app. How do you fix it quickly?

Save to ▾
Show answer
If the bug is in JavaScript, fix it, test on a preview channel, and publish an over-the-air update to production with a staged rollout, keeping it compatible with the current runtime version. If it needs native changes, build a hotfix release, submit it, and request expedited review on iOS if justified. Meanwhile disable the feature with a remote config flag if possible, and halt the store rollout.
197

Your company wants to publish the same app for five white-label clients. How do you manage builds and store listings?

Save to ▾
Show answer
Keep one codebase and create a configuration per client with app ID, name, icons, colours, API base URL and feature flags, using Android flavours and iOS targets or schemes, or dynamic Expo app config. Automate builds for each client in CI with fastlane or EAS. Each client usually needs its own store account or listing, so document signing keys and access per client and automate metadata uploads.
198

An over-the-air update crashed the app for users on an older native build. What went wrong and how do you prevent it?

Save to ▾
Show answer
The update probably used a native module or API that the older binary did not have, so JavaScript called missing native code. Prevent this by setting runtime versions tied to native code fingerprints, so updates only reach compatible builds. Roll out updates gradually, monitor crashes per update ID, and keep a rollback by republishing the previous update. Test updates on the oldest supported build before release.
199

How would you plan a staged rollout for a major redesign?

Save to ▾
Show answer
Release to internal testers and beta users first and collect feedback. Then roll out to 5 percent of production users, monitoring crash-free rate, ANRs, key conversion metrics and reviews for a few days, before moving to 20, 50 and 100 percent. Keep the redesign behind a remote flag to switch back without a release. Define rollback criteria in advance and communicate the plan to support teams.
200

How do you automate store submissions with fastlane?

Save to ▾
Show answer
fastlane defines lanes in a Fastfile, such as beta and release. A lane can increment build numbers, build the app with gradle or gym, sign with match, which stores iOS certificates encrypted in a private repository, upload to TestFlight with pilot or Play testing tracks with supply, and upload metadata and screenshots. Running lanes from CI makes releases repeatable and removes manual steps on a developer's machine.

Frequently asked questions

What jobs can I get after learning mobile app development?

You can apply for roles like Flutter Developer, React Native Developer, Mobile App Developer, Cross-Platform Engineer and Junior Mobile Engineer. With experience you can become a Senior Mobile Engineer, Mobile Architect or Mobile Tech Lead. Startups, e-commerce, fintech, edtech, healthtech, agencies and IT services companies all hire for these skills. Published apps on the Play Store or App Store make your profile stand out more than certificates alone.

Should I learn Flutter or React Native first?

If you already know JavaScript or React, start with React Native because your web skills transfer directly. If you are new to programming or want a consistent custom UI, Flutter with Dart is easy to start and has excellent tooling. Both have strong demand in India. This course covers both, so you can pick one to master first and still understand the other well enough for interviews and projects.

Who is eligible for this mobile app development course?

Students from B.Tech, BCA, MCA, B.Sc and diploma backgrounds, as well as working professionals from web development, testing or support, can join. Basic programming knowledge helps but the course starts from fundamentals. You need a laptop with 8 GB RAM or more; 16 GB is better for emulators. Building iOS apps locally needs a Mac, though cloud build services let you build iOS apps without owning one.

How long does it take to become job-ready as a mobile developer?

Most learners who practise two to three hours daily become ready for junior roles in about four to six months. The 16-week course covers core skills in both frameworks, backend integration and publishing, and the remaining time is for building and publishing two or three portfolio apps and preparing for interviews. Prior programming experience shortens this. Mastering architecture and performance takes one to two years of real projects.

Do I need a Mac to build iOS apps?

To build and run iOS apps locally with Xcode and the iOS simulator, you need a Mac. However, you can develop Flutter and React Native apps on Windows or Linux, test on Android, and use cloud build services such as EAS Build or Codemagic to build and submit iOS versions. For serious iOS work and debugging native issues, access to a Mac and a real iPhone is strongly recommended.

Is there a certification for Flutter or React Native developers?

There is no single official certification that employers require for Flutter or React Native. Companies judge mobile developers by their published apps, GitHub code quality, live coding rounds and technical discussions. A course completion certificate shows structured training, and some cloud platforms offer related credentials, but apps live on the stores with good reviews and clean code are the strongest proof of your skills.