Skip to content

React Native on iPhone Duo

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

iPhone Duo goes on sale 23 October 2026, running iOS 27.1. Anything you fix before then, your users never see broken. Start with what breaks first.

React Native iPhone Duo checklist

Most React Native apps work on iPhone Duo because flexbox adapts. Whether yours does comes down to the patterns below, and each blocker is drawn further down the page.

React Native on iPhone Duo: what works, what breaks

  • WorksFlexbox layoutYoga reflows when UIKit resizes the root view.
  • WorksuseWindowDimensions()Re-renders on unfold, fold, rotation and Split View.
  • BreaksDimensions.get('window') at module scopeCaptured once at launch; wrong after the first fold.
  • BreaksA portrait orientation lockThe inner display ignores supported orientations.
  • WorksSafeAreaViewApplies each edge separately.
  • BreaksMath.max(insets.left, insets.right)Insets are asymmetric; one side is over-padded.
  • WorksA width >= 600 breakpointFires on the 626 pt inner display, not the 466 pt outer.
  • BreaksPlatform.isPadFalse on iPhone Duo, so the tablet layout never appears.
  • BreaksPausing on AppState inactiveIn Split View a visible app can be inactive — it looks frozen.
  • Looks datedFull-screen 16:9 videoLetterboxes heavily on a 1.42 display.
  • Looks datedA tab bar drawn in JavaScriptStays at the bottom while system bars move to the side.
  • UnverifiedcreateNativeBottomTabNavigatorBacked by UITabBarController; expected to get side placement. Test it.
  • UnverifiedCamera libraries across a foldDepends on the library adopting Apple’s camera coordinators.
  • Needs nativeHinge, ArrangementView, vertical barsNo JavaScript bindings; needs a native module.

Why most React Native apps survive the unfold

A React Native view tree is a native view tree. When iPhone Duo opens, UIKit resizes the root view and Yoga lays out everything inside it again, so a screen built from flex ratios reflows with no changes at all.

What changes is the range of widths you receive. The closed outer display is 466 points wide. The open inner display is 626 points wide held upright and 890 held sideways, and Split View can hand you anything in between. A single width check covers every one of those cases, as long as it reads the width live.

iPhone Duo screen widths against a 600 point breakpointThree iPhone Duo screens at the same scale, each crossed by a dashed line at 600 points. The closed outer display is 466 points wide, so the line falls beyond its edge and the layout is one column. The open inner display is 626 points wide held upright and 890 held sideways; the line falls inside both, so both get a sidebar and a detail view.600 pt breakpoint466 ptclosed1 column626 ptopen2 columns890 ptopen, rotated2 columns
Drawn to scale. One check on useWindowDimensions().width, at 600 points, gives one column when closed and two when open, in either orientation. It also drops back to one column when Split View narrows the window, with no extra code. Apple’s advice for native apps is to target size classes rather than breakpoints; this framework has no size classes, so a single width check is our closest equivalent.

The blockers, drawn on iPhone Duo

Each figure shows the same screen twice on the inner display, at its real proportions. On the left is the pattern most apps ship today, and on the right is the same screen after the fix. Below each drawing is the code that produces it.

Built against an older SDK

This one is not a crash. An app built without the iOS 27 SDK runs at a familiar size and aspect ratio, with the rest of the display unused. The iOS 27.1 SDK is what lets it reach the screen edge, and several of the fixes below depend on it.

Older SDK: runs, but letterboxed versus iOS 27.1 SDK: reaches the edgeTwo iPhone Duo inner displays, 626 by 890 points. Left: an app built without the iOS 27 SDK runs in a 402-point-wide phone-shaped window with black bars either side. Right: the same app built with the iOS 27.1 SDK fills the display edge to edge with a two-column layout.402 pt626 pt

Left: Older SDK: runs, but letterboxed

xcrun --sdk iphoneos --show-sdk-version
# 26.x → a familiar size and ratio

Right: iOS 27.1 SDK: reaches the edge

xcrun --sdk iphoneos --show-sdk-version
# 27.1 → extends to the screen edge
The letterboxed window on the left is illustrative: Apple describes it only as "a familiar size and aspect ratio".How to fix it — Older SDK: runs, but letterboxed

Dimensions.get cached at module scope

This is the most common React Native failure on a foldable. A width read when the module loads is captured once. Launch the app on the closed display, unfold it, and every style built from that number stays sized for 466 points on a 626-point screen. Dimensions.addEventListener does not help, because a StyleSheet.create object is never rebuilt.

Width captured while folded versus Width read on every renderTwo iPhone Duo inner displays, 626 points wide. Left: cards sized from a width read while the device was folded, 466 points, stay 434 points wide after unfolding and leave an empty band down the right side. Right: cards sized from the live width fill 594 points.434 pt594 pt

Left: Width captured while folded

const { width } =
  Dimensions.get('window');

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

Right: Width read on every render

function Card({ children }) {
  const { width } =
    useWindowDimensions();
  return (
    <View style={{ width: width - 32 }}>
      {children}
    </View>
  );
}
Drawn to iPhone Duo’s point dimensions.How to fix it — Width captured while folded

Portrait lock ignored on the inner display

Apple states the inner display does not honour supported interface orientations, so a lock in Info.plist or an orientation library stops working without any warning. Layouts that assumed height is always greater than width get laid out sideways. The fix is not a stronger lock but a layout chosen by width.

Portrait lock, ignored versus Layout chosen by widthTwo iPhone Duo inner displays held landscape, 890 by 626 points. Left: a portrait-locked layout is shown anyway, and its full-width hero image runs off the bottom of the screen. Right: a layout chosen by width shows a sidebar beside the detail view.890 × 626 pt890 × 626 pt

Left: Portrait lock, ignored

import Orientation from
  'react-native-orientation-locker';

Orientation.lockToPortrait();
// A portrait-only Info.plist is
// ignored in exactly the same way.

Right: Layout chosen by width

const { width } = useWindowDimensions();

return width >= 600
  ? <SidebarLayout />
  : <StackLayout />;
Drawn to iPhone Duo’s point dimensions.How to fix it — Portrait lock, ignored

Symmetric safe-area maths

react-native-safe-area-context reports the real insets, and SafeAreaView applies them correctly. The bugs are in hand-written maths that collapses left and right into one value. That was harmless when both edges matched, but on iPhone Duo they differ, so one side is over-padded and the content drifts off-centre.

One value for both edges versus Each edge its own insetTwo iPhone Duo inner displays with a narrow safe-area inset on the left and a wide one on the right, shown hatched. Left: the larger inset applied to both edges wastes a band on the narrow side and pushes content off-centre. Right: each edge padded by its own inset.

Left: One value for both edges

const insets = useSafeAreaInsets();

<View style={{
  paddingHorizontal:
    Math.max(insets.left, insets.right),
}} />

Right: Each edge its own inset

const insets = useSafeAreaInsets();

<View style={{
  paddingLeft: insets.left,
  paddingRight: insets.right,
}} />
Inset widths are exaggerated for legibility. Apple states the insets differ; it has not published the values.How to fix it — One value for both edges

Split View looks frozen

Every app takes part in Split View on iPhone Duo, with no opt-in. An app there can be visible without being active, so code that pauses video, timers or animation whenever the state leaves active stops content the user is still looking at.

Paused while still on screen versus Paused only when hiddenTwo iPhone Duo inner displays in Split View, with another app on the left and a video app on the right. Left: the video has stopped because the app paused itself on becoming inactive, though it is still on screen. Right: the video keeps playing until the app is actually in the background.

Left: Paused while still on screen

AppState.addEventListener(
  'change',
  (s) => {
    if (s !== 'active') {
      player.pause();
    }
  },
);

Right: Paused only when hidden

AppState.addEventListener(
  'change',
  (s) => {
    if (s === 'background') {
      player.pause();
    }
  },
);
Drawn to iPhone Duo’s point dimensions.How to fix it — Paused while still on screen

16:9 video on a 1.42 display

The inner display is far squarer than a phone. A full-screen 16:9 player fitted to the 890-point width leaves 125 points of black bars. Apple’s guidance is to use that space rather than fight it: keep the player at 16:9 and put related content beneath it.

16:9 fitted to 890 pt: 125 pt of bars versus Player plus content beneathLeft: a 16:9 video fitted to an iPhone Duo inner display held landscape, 890 by 626 points, leaves 125 points of black bars. Right: the display held portrait with the player at the top and related content filling the space beneath it.125 pt of bars626 pt

Left: 16:9 fitted to 890 pt: 125 pt of bars

<Video
  style={StyleSheet.absoluteFill}
  resizeMode="contain"
/>

Right: Player plus content beneath

<View style={{ flex: 1 }}>
  <Video style={styles.player} />
  <FlatList data={related} {...rest} />
</View>

// styles.player = { aspectRatio: 16/9 }
Drawn to iPhone Duo’s point dimensions.How to fix it — 16:9 fitted to 890 pt: 125 pt of bars

What React Native cannot reach without native code

Correct layout is reachable from JavaScript, but awareness of the hinge is not. None of the following have JavaScript bindings today:

Without them, an app can lay out correctly at every size and still put a button on the fold.

Centred content lands on the fold versus Only reachable through a native moduleTwo iPhone Duo inner displays held open like a book, 890 by 626 points, with the fold shown as a band running top to bottom through the middle. Left: a button centred on the screen sits directly on the fold. Right: content on the left of the fold and controls on the right, with nothing across it.

Left: Centred content lands on the fold

<View style={{
  flex: 1,
  justifyContent: 'center',
}}>
  <PrimaryButton />
</View>

Right: Only reachable through a native module

// Your own bridge around Swift's
// reservedRegions(kind: .division).
// No package ships this today.
const hinge = useHingeRegion();
Drawn to iPhone Duo’s point dimensions.How to fix it — Centred content lands on the fold

For feeds, commerce, messaging and media, correct layout is the whole job. For a canvas, an editor, a drawing app or a game board, budget for a native module that wraps reservedRegions(kind:) and passes the frames into JavaScript.

Find them in your codebase

Each of these searches maps to one of the blockers above. Every hit outside a component’s render function deserves a look.

grep -rn "Dimensions.get" src/
grep -rn "Math.max(insets" src/
grep -rnE "isPad|lockToPortrait|UISupportedInterfaceOrientations" src/ ios/
grep -rn "AppState" src/

Work through them in that order. The first four fixes are usually a day’s work and account for nearly all of the visible improvement.

Then check your dependencies

Your own code is half the problem. The other half is the forty libraries under it, and they are not in the same state as each other: react-native-screens shipped iPhone Duo fixes on 13 October, React Native’s own fold API is still an open pull request, and npm install expo-hinge installs a placeholder rather than Expo’s module.

We went through them one at a time in React Native libraries on iPhone Duo, with the version numbers and pull request states you can re-check yourself.

For the long-form version, with the reasoning behind each pattern and the full migration order, read what breaks in React Native on iPhone Duo, and what works. Building with Expo? Expo apps on iPhone Duo covers EAS build images, app.json and native tabs. Built the app with an AI tool? Start with why vibe-coded apps break on iPhone Duo.

Free evaluation

Want this done for your React Native app?

We adapt existing iOS apps to iPhone Duo. Send your email and an engineer replies with what is likely to break in your React Native app, what to fix first, and a realistic estimate of the work.

Takes about 20 seconds

See what an audit costs

Checklist items that apply to React Native

Open the full checklist

Weighing React Native against the others? All six frameworks scored side by side — or see our iPhone Duo development services if you would rather hand the work over.

Users already reporting that your app looks wrong? What each symptom means, in plain language you can send them.