Skip to main content

React Native engineer system design interview questions

10 questions on system design for react native engineer candidates. Expect prompts such as “Design offline sync for a React Native app” and “System design: real-time chat with offline support in React Native”, each with a worked answer outline and the follow-ups interviewers push on.

Questions

Showing 1 to 10 of 10 system design questions.

As asked

Design offline support for a React Native field app where users create inspections without network access and sync them later. How do you handle conflicts and retries?

Sample answer outline

Use a local durable store such as SQLite or WatermelonDB for inspection records and an outbox table for pending mutations. Each mutation needs an idempotency key so retries after app restarts or flaky networks do not duplicate server state. Conflict handling depends on domain rules: last-write-wins is rarely acceptable for inspections, so prefer field-level merge, server validation, or explicit user resolution. Sync should be resumable, ordered where required, and observable through local status per record. Weak answers hide conflict resolution behind a generic queue and never define the server contract.

Expect these follow-ups

  • How do you sync attached photos without exhausting device storage?
  • What does the server need to store for idempotency?
  • How do you test a week of offline edits?
offlinesyncmobile-data

As asked

Design the client architecture for a WhatsApp-style chat app. Users send messages while offline, see delivery and read receipts, and sync history on reconnect. What local database, sync protocol, and WebSocket management strategy would you use?

Sample answer outline

Local DB (WatermelonDB or SQLite) stores messages with status (pending, sent, delivered, read) and a localId. On send, the message is written locally as pending, queued for sync. WebSocket connection is managed with exponential reconnect; when connected, pending messages are flushed. The server acknowledges each message and returns a serverId; the local record is updated. Read receipts come as WebSocket events that update status. On cold start, the app fetches the last 50 messages per conversation from REST and reconciles against local DB by serverId. A strong answer considers push notifications for background messages, message ordering by server timestamp vs local insertion order, and encryption at rest.

Expect these follow-ups

  • How do you handle message ordering when two offline users sync at the same time?
  • How do you implement end-to-end encryption in this architecture?
system-designchatofflinewebsocketsqlite

As asked

You have a React Native app with an unauthenticated flow (onboarding, login), a tab bar with 5 tabs each containing nested stacks, and deep links that can target any screen. Design the navigation architecture to handle cold-start deep links, protected routes, and tab state persistence.

Sample answer outline

The root navigator switches between AuthStack and AppStack based on auth state (read from persisted storage on startup). Deep links are parsed by React Navigation's Linking config, which maps URL patterns to screen names. Cold-start deep links are handled by getInitialURL awaiting before rendering the navigator, or by React Navigation's linking prop which handles the initial URL internally. Tab state persistence uses React Navigation's state persistence API (AsyncStorage). Protected routes inside the app are handled by checking auth state in the navigator (not in individual screens), redirecting to Login if a deep link targets a protected screen. A strong answer also covers modal navigators for full-screen modals, and how bottom sheet navigators fit in.

Expect these follow-ups

  • How do you handle a deep link to a screen that requires user setup to be completed first?
  • How do you implement a 'back to app after login' redirect after a deep link triggers an auth wall?
system-designnavigationdeep-linksauthreact-navigation

As asked

Design the complete biometric authentication flow for an RN app, from first enable to daily use. Cover key storage, fallback to PIN, re-enrollment after a failed biometric attempt, and what happens when the user adds a new fingerprint on the device.

Sample answer outline

On first enable, the app prompts biometric auth to confirm enrollment, then stores the auth token or encryption key in the Keychain (iOS) or Keystore (Android) with biometric binding. On daily use, the app calls the platform biometric API to unlock the Keychain item and retrieves the token. After N failed attempts (platform-enforced), the platform falls back to device PIN which also unlocks biometric-protected Keychain items. When the user adds a new fingerprint, iOS invalidates Keychain items created with kSecAccessControlBiometryCurrentSet but not kSecAccessControlBiometryAny; the app must detect invalidation, prompt re-login, and re-store the key. A strong answer uses react-native-keychain with biometryType detection and handles LAErrorBiometryLockout.

Expect these follow-ups

  • How do you differentiate between 'biometrics not enrolled' and 'biometrics not available on device'?
  • What is the risk of storing a long-lived token in the Keychain versus using biometrics only for local authentication?
system-designbiometricskeychainauthsecurity

As asked

Design an RN app that runs a TFLite or CoreML model on each camera frame to detect objects in real time at 30fps. Where does the ML inference run, how do you move frames from the camera to the model without crossing the JS bridge, and how do you display bounding boxes synchronized with the preview?

Sample answer outline

Camera frames must never cross the bridge; they should be processed entirely in native code. VisionCamera (react-native-vision-camera) with a Frame Processor plugin lets you write Swift/Kotlin that receives each CMSampleBuffer (iOS) or ImageProxy (Android), runs the TFLite/CoreML model natively, and returns inference results (bounding boxes) as a JS-friendly object. Bounding boxes are overlaid on the preview using an SVG or Canvas layer on the JS side, updated via shared values or a JS state update from the frame processor result. At 30fps the frame processor must complete in under 33ms; the ML model should be quantized (INT8) to fit that budget on mid-range hardware.

Expect these follow-ups

  • How do you throttle inference to every Nth frame to reduce CPU load?
  • How do you benchmark inference latency per frame on a real device?
system-designcameramachine-learningvision-cameraperformance

As asked

Design the encryption architecture for a note-taking app where notes are encrypted on-device before sync and the server never sees plaintext. Walk me through key generation, key storage, sync, and what happens when the user signs in on a new device.

Sample answer outline

Each note is encrypted with a symmetric key (AES-256-GCM). The symmetric key is encrypted with the user's asymmetric public key. The private key is derived from the user's password using PBKDF2 or Argon2 and stored locally in the Keychain (never uploaded). The server stores only ciphertext (note body + encrypted symmetric key). On a new device, the user enters their password to derive the private key locally and decrypts the symmetric keys from the server. A strong answer addresses key rotation (re-encrypting all note keys with a new derived key), secure erasure of keys from memory, and the UX trade-off of password-only recovery vs a backup recovery key.

Expect these follow-ups

  • How do you handle sharing a note with another user in this architecture?
  • What is the risk of deriving the encryption key from the login password versus using a separate passphrase?
system-designencryptione2esecuritykeychain

As asked

Design an RN app that tracks a delivery driver's location every 30 seconds in the background and uploads it to a server. Address battery optimization, OS restrictions, what happens when the app is killed by the OS, and how you keep the upload reliable.

Sample answer outline

On iOS, background location requires the NSLocationAlwaysAndWhenInUseUsageDescription entitlement and a Location Updates background mode. Significant Location Changes API wakes a killed app but fires only on cell tower changes. For 30-second intervals, a foreground service with a persistent notification is needed on Android. The app must use a foreground service on Android (react-native-background-geolocation handles this) to prevent the OS from killing it under Doze mode. Location updates are written to a local queue (MMKV or SQLite) first, then a background upload worker sends them to the server with retry. On iOS, if the app is killed, only significant-change events fire. A strong answer acknowledges the App Store and Play Store policies around always-on location and the required disclosure.

Expect these follow-ups

  • How do you reduce GPS battery drain while maintaining 30-second accuracy?
  • What do you do when the server is unreachable and the queue is filling up faster than it drains?
system-designlocationbackground-tasksbatteryios-android

As asked

Design the server-side and client-side architecture for a notification system that sends 10 million push notifications per day across iOS (APNS) and Android (FCM), handles token rotation, and tracks delivery and open rates. Focus on the client integration points.

Sample answer outline

Server side: a notification service batches sends through APNS and FCM, using their batch APIs. Device tokens are stored with a user ID and platform flag; stale tokens (APNS 410 response) trigger deletion. On the client, the app registers for push on launch, sends the token to the server via an authenticated API call, and re-registers on token refresh (@react-native-firebase/messaging onTokenRefresh callback). Delivery tracking uses FCM delivery receipts and APNS acked status. Open-rate tracking uses an onNotificationOpenedApp listener that fires a server event with the notification ID and action. A strong answer discusses the notification permission prompt timing (not on cold start), quiet notifications for background data sync, and per-user notification preference settings stored server-side.

Expect these follow-ups

  • How do you prevent a notification permission prompt from appearing at the worst possible moment?
  • How do you handle a user who is logged in on three devices and should only get one notification?
system-designpush-notificationsapnsfcmscalability

As asked

A user selects a 500 MB video to upload. Design the upload flow: chunked upload, resumable on failure, progress UI, background upload when the user leaves the screen, and cleanup on cancel.

Sample answer outline

Chunked upload (5 MB chunks) with a session ID from the server. Each chunk is uploaded sequentially or in parallel (3 concurrent). The upload state (session ID, last uploaded chunk index) is persisted in MMKV so uploads survive app restarts. On iOS, background URLSession handles uploads even when the app is backgrounded (react-native-background-upload uses this). On Android, a foreground service with a notification keeps the upload alive. Progress is reported via upload progress callbacks to a shared state (Zustand) and displayed in the UI. On cancel, the client calls a server endpoint to delete the upload session and cleans up the temp file from the cache directory. A strong answer mentions presigned S3 URLs (client uploads directly to S3, avoiding server bandwidth), MD5 checksum verification per chunk, and exponential retry per failed chunk.

Expect these follow-ups

  • How do you handle the case where the server already has chunks 1 to 10 and the app restarts?
  • How do you show upload progress for multiple concurrent uploads?
system-designmedia-uploadbackground-taskss3chunked-upload

As asked

Design a feature flag and A/B testing system for your React Native app. The flags must be available immediately on cold start (no network delay blocking the UI), updateable without a new release, and auditable per user.

Sample answer outline

Flags are fetched from a remote config service (LaunchDarkly, Firebase Remote Config, or a custom endpoint) and persisted locally in MMKV. On cold start, the app reads the cached flags synchronously before rendering, then fetches fresh flags in the background and updates MMKV for the next session. The local cache has a staleness TTL (e.g., 1 hour). Flag evaluation is done client-side by user ID bucket hashing for A/B assignment. Audit events (flag name, value, user ID, timestamp) are sent to an analytics endpoint. A strong answer mentions kill switches (a flag that is always false in emergencies), flag targeting by OS version or app version, and the risk of a React Native CodePush update conflicting with a server-side flag change.

Expect these follow-ups

  • How do you prevent a 'flag flicker' where the user briefly sees variant A then switches to variant B?
  • How do you handle flag evaluation for a user who is not yet authenticated?
system-designfeature-flagsab-testingremote-configanalytics