# iPhone Duo support for React Native and Flutter apps

Source: https://foldready.dev/guides/react-native-flutter-iphone-duo

Published: 2026-09-12. Updated: 2026-09-12. Author: FoldReady (vity5.diduk@gmail.com).

Summary: React Native and Flutter apps run on iPhone Duo, but they must read window size reactively (useWindowDimensions in React Native, MediaQuery or LayoutBuilder in Flutter) instead of caching it at startup, handle asymmetric safe areas, and use native code for the iOS 27.1 ReservedRegion API until framework support lands.

Cross-platform teams are the least prepared for iPhone Duo. Their layout code often reads the window size once at launch, and their foldable experience, if any, comes from Android where the fold is exposed through different APIs. This guide covers what actually changes and what still needs native Swift.

## What is the same as native?

- Rebuilding with Xcode 27.1 and the iOS 27.1 SDK is required to leave the compatibility window. This is a native toolchain step regardless of framework.
- The window resizes live when the device opens, closes, folds or enters side-by-side multitasking. Anything that cached the size at startup is wrong after the first fold.
- Safe areas on the inner display are asymmetric. Use per-edge insets, never a single horizontal padding value.
- Every screen must be checked in all six poses plus side-by-side multitasking. The framework does not change the test matrix.

## React Native

```tsx
import { Dimensions, useWindowDimensions } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";

// Wrong: read once at module load, never updates on fold or multitasking.
const { width: staleWidth } = Dimensions.get("window");

// Right: re-renders when the window changes.

function Library() {
  const { width } = useWindowDimensions();
  const insets = useSafeAreaInsets(); // per-edge, asymmetric on the inner display
  const regularWidth = width >= 600;   // conventional compact/regular cut in points; confirm in the Device Hub simulator
  return regularWidth ? <TwoColumn insets={insets} /> : <Stack insets={insets} />;
}
```

- Search the codebase for Dimensions.get and replace it with useWindowDimensions. Avoid relying on Dimensions change events; React Native has a long-standing issue where they do not fire on first entry into split view, and side-by-side multitasking is a first-class window state on Duo.
- Derive a size-class equivalent from width, not from Platform.isPad or device model. iPhone Duo's inner display is regular width on a phone.
- Use react-native-safe-area-context for insets and apply them per edge.
- Navigation libraries with drawer or split layouts (for example React Navigation's drawer) can provide the two-column layout on the inner display.
- The fold and camera reserved regions are exposed by the iOS 27.1 ReservedRegion API. Until a maintained package wraps it, expose the regions through a small native module and pass them to JavaScript as insets.

## Flutter

```dart
// Reacts to window changes, including fold, unfold and multitasking.
Widget build(BuildContext context) {
  final size = MediaQuery.sizeOf(context);
  final padding = MediaQuery.paddingOf(context); // asymmetric on the inner display
  final regularWidth = size.width >= 600; // conventional cut in logical pixels; confirm in the simulator
  return regularWidth
      ? TwoColumnLayout(padding: padding)
      : StackedLayout(padding: padding);
}

// Prefer LayoutBuilder for widgets that only need their own constraints.
LayoutBuilder(builder: (context, constraints) =>
  constraints.maxWidth >= 600 ? const WideList() : const NarrowList());
```

- MediaQuery.sizeOf and LayoutBuilder already respond to window resizing; the risk is code that stored size in a singleton or computed it in initState.
- Flutter's MediaQuery.displayFeatures API describes hinges and folds. As of September 2026 it is populated on Android; check the Flutter changelog for iPhone Duo support, and until then bridge the ReservedRegion API through a platform channel.
- Use SafeArea with per-edge control rather than symmetric padding.
- NavigationRail or a two-pane layout package gives the regular-width layout on the inner display.

## Where native code is still required

| Need | React Native | Flutter |
| --- | --- | --- |
| Rebuild with iOS 27.1 SDK | Xcode project setting | Xcode project setting |
| Window size updates | useWindowDimensions | MediaQuery, LayoutBuilder |
| Asymmetric safe areas | react-native-safe-area-context | MediaQuery.paddingOf, SafeArea |
| Fold and camera reserved regions | Native module until a package exists | Platform channel until displayFeatures covers iOS |
| Half-fold detection | Native module | Platform channel |
| Concentric corner shapes | Native views only | Native views only |

> FoldReady audits React Native and Flutter apps as well as native ones, and the FoldCheck tester drives the built app, so it works regardless of framework.

## FAQ

**Does React Native support iPhone Duo?**

Yes. Apps run and resize. The work is in your layout code: window dimensions must be read reactively and safe areas applied per edge. Fold-specific APIs need a small native module for now.

**Does Flutter support iPhone Duo?**

Yes. MediaQuery and LayoutBuilder respond to window changes. Fold regions need a platform channel to the iOS 27.1 ReservedRegion API until Flutter exposes them on iOS.

## Sources

- [Apple Tech Talk: Prepare your app for iPhone Duo](https://developer.apple.com/videos/play/tech-talks/111461/)
- [Apple Tech Talk: Strike a pose with adaptive layouts on iPhone Duo](https://developer.apple.com/videos/play/tech-talks/111463/)