Skip to content

React Native on iPhone Duo: what breaks and what works

Ingenious Techlab TeamUpdated 2026-09-1410 min read

Contents · 15 sections
  1. React Native iPhone Duo checklist
  2. Why the baseline is better than you would expect
  3. Break one: cached dimensions
  4. Break two: orientation locking
  5. Break three: collapsed safe area insets
  6. What you cannot reach
  7. What you get for free that is worth using
  8. Split View, and the freeze bug
  9. Navigation: let the system move your tab bar
  10. Camera: test a live session across the fold
  11. Testing before you have the device
  12. App Store screenshots
  13. A pragmatic migration
  14. Using Expo, or an AI app builder?
  15. What would change this analysis

Most React Native apps will work on iPhone Duo, because flexbox is inherently adaptive. A handful of specific patterns break, and awareness of the hinge is out of reach without native code. The checklist below covers all of it, and each item links to the detail.

React Native iPhone Duo checklist

  1. Build with Xcode 27.1. Only the iOS 27.1 SDK lets your app reach the screen edge; older builds run at a familiar, letterboxed size.
  2. Replace module-scope Dimensions.get('window') with useWindowDimensions(), so layouts recalculate on fold, unfold, rotation and Split View.
  3. Remove portrait locks. The inner display ignores supported interface orientations, so choose layouts by width instead.
  4. Pad left and right separately. Apply insets.left and insets.right on their own; on iPhone Duo the two differ.
  5. Branch on width, not device type. A width >= 600 check fires on the 626 pt inner display, while Platform.isPad stays false.
  6. Keep media playing while visible. Pause on background, not inactive — an app in Split View can be on screen yet inactive.
  7. Use a native tab bar. System bars move to the side on iPhone Duo; a tab bar drawn in JavaScript stays at the bottom.
  8. Test the camera across a fold. Confirm a live preview survives folding and unfolding with the camera library you use.
  9. Keep controls off the fold. The hinge has no JavaScript API, so a canvas, editor or game board needs a native module.
  10. Rethink full-screen 16:9 video. On a 1.42 display it letterboxes heavily; put related content beneath the player instead.
  11. Test at 466 and 626 points before hardware arrives, with snapshot tests and an iPad simulator in Split View.
  12. Treat App Store screenshots as optional for now. Apple lists iPhone Duo sizes, but uploads open later this year.

Meta has published no iPhone Duo guidance, so the React Native side of this is our analysis. If you also target Android foldables, the platform comparison covers what carries across.

Why the baseline is better than you would expect

Under the hood, a React Native view hierarchy is a native view hierarchy. When iPhone Duo unfolds, UIKit resizes the root view, and Yoga relayouts everything inside it. An app built with flex ratios rather than fixed pixel values adapts without a single line of change.

That is genuinely most apps. Which makes the failures worth knowing precisely, because they are narrow.

Break one: cached dimensions

This is the big one, and it is nearly universal.

// Broken on iPhone Duo — evaluated once, at module load
const { width } = Dimensions.get('window');

const styles = StyleSheet.create({
  card: { width: width - 32 },
});

That width was captured at launch. On iPhone Duo it becomes wrong when the user unfolds the device, folds it closed, rotates it, or resizes Split View. The style object is created once and never recomputed, so the card keeps its launch-time width forever.

The fix is the hook, which re-renders on change:

function Card({ children }) {
  const { width } = useWindowDimensions();
  return <View style={{ width: width - 32 }}>{children}</View>;
}

Worth searching for specifically, since the module-scope form is invisible in review:

grep -rn "Dimensions.get" src/

Every hit outside a component render is suspect. Note that Dimensions.addEventListener is a partial fix at best — it fires, but a StyleSheet.create object built at module load will not be rebuilt by it.

There is a subtler variant worth checking: percentage-of-screen constants like const CARD = width * 0.45. These read as responsive and are not.

Break two: orientation locking

Many React Native apps lock to portrait, in Info.plist or through a library. Apple states the inner display does not honor supported interface orientations.

So the lock silently stops working, and your app is laid out in configurations it was never designed for. If your layout assumed width is always less than height, that assumption is gone.

The replacement is not another lock. It is a layout that works at any aspect ratio:

const { width, height } = useWindowDimensions();
const isWide = width > 600;

return isWide ? <TwoColumn /> : <SingleColumn />;

A width of 600 is a reasonable dividing line here: the inner display is 626 points wide and the outer is 466.

Break three: collapsed safe area insets

react-native-safe-area-context reports the real insets. The problem is what application code does with them.

// Common, and now wrong
const insets = useSafeAreaInsets();
<View style={{ paddingHorizontal: Math.max(insets.left, insets.right) }} />

Apple is explicit that safe areas are asymmetric on iPhone Duo. Taking the max, or applying one horizontal value to both edges, was harmless when the two matched. It now over-pads one side, and content drifts off-centre.

<View style={{ paddingLeft: insets.left, paddingRight: insets.right }} />

SafeAreaView handles this correctly on its own. The bugs are in hand-rolled inset math.

What you cannot reach

Here is the honest limitation. These have no JavaScript bindings today:

  • ReservedRegion — where the hinge divides the display
  • ArrangementView — pose-aware primary/secondary placement
  • onHingeChange — hinge angle
  • Scene accessories — content on the outer display while the app runs on the inner
  • The vertical toolbar APIs — axisBehavior, visibilityPriority, and the rest

Reaching any of them means a native module wrapping the Swift API and bridging values into JS. For reserved regions that is a moderate piece of work: a native view that queries reservedRegions(kind:), observes changes, and emits frames as props.

Until someone ships that, a React Native app can be correct on iPhone Duo but not hinge-aware. It can lay out properly at any size; it cannot avoid placing a button on the fold.

For most content apps — feeds, commerce, messaging, media — correctness is the whole job, and the fold falls in a place users tolerate. For a canvas, an editor, a drawing app, or a game board, the fold matters and you should budget for native work.

What you get for free that is worth using

The inner display is regular-width in both dimensions, with room for a sidebar. If your app has a tablet layout behind a breakpoint, it will now appear on a phone, and it is probably the right layout. Check that your breakpoint is driven by live dimensions rather than by a device-type check:

// Wrong — Platform.isPad is false on iPhone Duo
const isTablet = Platform.OS === 'ios' && Platform.isPad;

// Right
const { width } = useWindowDimensions();
const isWide = width >= 600;

Any device-info library used to pick a layout has this same problem.

Split View, and the freeze bug

All apps participate in side-by-side multitasking on iPhone Duo — there is no opt-in. Two things to check:

Continuous resize. Dragging the Split View divider changes your width continuously. useWindowDimensions handles it; cached values do not.

AppState. In Split View your app can be visible but not active. Code that stops video, timers, or animation on AppState changing to inactive will look frozen to a user who can still see the window. This pattern is common in React Native for battery reasons, and it is worth revisiting for this device specifically.

On iPhone Duo, toolbars, tab bars and navigation controls move to the side on the closed outer display and on the inner display in landscape. Only the inner display in portrait keeps horizontal bars. Apple applies this to standard system components automatically.

That makes the tab bar a React Native decision. React Navigation’s default createBottomTabNavigator draws its tab bar with React Native views, so there is nothing for the system to move: yours stays at the bottom while system apps put theirs at the side. React Navigation 7 also offers a native variant backed by UITabBarController on iOS. It is marked unstable, and needs React Native 0.79 and react-native-screens 4.25 or later:

import { createNativeBottomTabNavigator } from
  '@react-navigation/bottom-tabs/unstable';

const Tabs = createNativeBottomTabNavigator();

We expect a UITabBarController-backed tab bar to receive the same side placement as a native app built with the iOS 27.1 SDK, but that is not yet verified on the device, so check it in the simulator before you commit. If you keep a JavaScript tab bar, design it on purpose for a short, wide outer display rather than inheriting a layout made for a tall phone.

Camera: test a live session across the fold

Folding iPhone Duo can change which camera faces the user mid-session. Apple’s native answer is AVCaptureDeviceDirectionCoordinator. React Native camera libraries wrap AVFoundation themselves, so whether that coordination happens depends on the library, not on your JavaScript.

Until your library documents iPhone Duo support, test it directly: start a preview or a recording, then fold and unfold the device. Watch for a black preview, a frozen frame, or the wrong lens staying active.

Testing before you have the device

Xcode 27.1 adds Device Hub, with controls to open, close, rotate and fold a simulated iPhone Duo. Until you have it, two cheap checks catch most layout bugs:

  • Run the app on an iPad simulator in Split View and drag the divider through its full range. Continuous resizing exposes every cached dimension.
  • Snapshot-test key screens at 466 × 678 points (outer) and 626 × 890 points (inner).

Neither exercises the hinge or the side bars, so keep a manual pass for those once Device Hub is available. More in how to test without the device.

App Store screenshots

Apple’s screenshot specifications list iPhone Duo with outer display screenshots at 1398 × 2034 pixels and inner display screenshots at 2007 × 2853 pixels, plus their landscape equivalents. Apple sets no requirement for them. The required iPhone screenshots are unchanged, a 6.9-inch set or, failing that, a 6.5-inch set, and Apple says uploading iPhone Duo assets in App Store Connect will be available later this year. See do I need iPhone Duo App Store screenshots?

A pragmatic migration

  1. grep -rn "Dimensions.get" — replace every module-scope call with useWindowDimensions
  2. Remove orientation locks and fix whatever they were hiding
  3. Audit useSafeAreaInsets consumers for symmetric math
  4. Replace device-type layout checks with width checks
  5. Test the Split View divider through its full range
  6. Verify AppState handling does not freeze visible content
  7. Move to a native tab bar, and test the camera across a fold
  8. Decide whether the fold matters enough for a native module

Steps 1 to 4 are a day’s work in most codebases and account for nearly all of the visible improvement.

Using Expo, or an AI app builder?

Expo adds three decisions of its own: the EAS build image, the app.json portrait lock, and native versus JavaScript tabs. They are covered in Expo apps on iPhone Duo. If an AI tool such as Rork, Bolt or Replit Agent generated your app, why vibe-coded apps break on iPhone Duo covers the extra patterns those apps tend to contain.

What would change this analysis

If React Native ships a useDisplayFeatures-style API bridging Apple’s reserved regions, the last section becomes obsolete and hinge-aware layout becomes reachable in JS. Nothing has been announced. We will update this post if that changes — it is dated and versioned above.

React Native on iPhone Duo

No first-party support. Flexbox layout adapts, but cached dimensions, orientation locking and safe-area assumptions all need attention.

Read the React Native guide

Related

Free evaluation of your app

Run the checklist — the blockers are enough — send it to us, and we will reply with your outstanding items prioritised and a realistic effort estimate. No call, no obligation.