Guides8 min read

Get your Capacitor app ready for iPhone Duo

iPhone Duo ships on 23 October with two very different screen sizes. What changes for a Capacitor app, the CSS that breaks on a foldable, how to test in Xcode 27.1, and how to fix layout issues after launch without a store release.

Apple's first foldable, iPhone Duo, opens for pre-order on 16 October and ships on 23 October 2026. Xcode 27.1 beta, released on 18 September, adds the SDK and a simulator you can fold, unfold and rotate. That leaves app teams about a month.

For a Capacitor app, this is mostly good news. Your UI is a web page, and web pages have handled resizing for thirty years. The work is finding the places where your app quietly assumed one phone-sized screen, fixing them in CSS and JavaScript, and making sure you can keep fixing them after launch day.

Short version: ship one store build made with Xcode 27.1 (and Capacitor 8.5 for UIScene) before 23 October. Treat every layout issue found after that as a web change you can ship over the air the same day.

What actually changes for a Capacitor app

iPhone Duo runs apps on a compact outer display and a much larger inner display, and the user can move between them while your app is open. Apple's guidance is to design for a continuous range of sizes rather than a fixed layout per pose. Apps that are not updated still run, but Apple says they may not properly fill the display.

In a Capacitor app, the native side of this is small:

  • The WKWebView resizes with the window. Your page receives a normal resize event and new viewport dimensions.
  • Scene handling is native. Building with the iOS 27 SDK already requires the UIScene lifecycle, which Capacitor 8.5 adds. If you have not done that migration, it comes first.
  • True multi-window support (two instances of your app side by side) is on the roadmap for Capacitor 9, not Capacitor 8.

Everything else lives in your web code. That is where the bugs will be.

The web code that breaks on a foldable

These patterns work on every phone until the screen changes size underneath a running app:

PatternWhat goes wrongFix
Reading window.innerWidth once at startupLayout decisions freeze at the size the app launched withUse CSS media or container queries, or listen for resize
Branching on orientation (portrait vs landscape)A large unfolded screen can be portrait and still have room for two columnsBranch on available width, not orientation
Fixed pixel widths for sheets, modals and cardsContent is stranded in a narrow column on the inner displayUse max-width with fluid percentages or clamp()
Canvas, charts or maps sized onceBlurry or cropped rendering after unfoldingObserve the container with ResizeObserver and re-render
Hard-coded safe-area paddingControls under the camera area or rounded corners in some posesUse env(safe-area-inset-*) everywhere
Virtual lists with a fixed item count per screenBlank gaps or overdraw after the viewport growsRecalculate on resize or use a library that measures

Make the layout fluid

Start with the viewport. Capacitor's default index.html is usually fine, but confirm viewport-fit=cover is present so safe-area insets work:

<meta
  name="viewport"
  content="width=device-width, initial-scale=1, viewport-fit=cover"
/>

Then let width decide the layout. Container queries are supported in the WebKit that ships with current iOS, and they are the best fit for a screen that changes size: each component adapts to the space it has, not to the device.

.inbox {
  container-type: inline-size;
}

.inbox__layout {
  display: grid;
  grid-template-columns: 1fr;
}

/* Two panes once there is room, whatever the device or pose */
@container (min-width: 700px) {
  .inbox__layout {
    grid-template-columns: minmax(280px, 360px) 1fr;
  }
}

.app-shell {
  padding:
    env(safe-area-inset-top)
    env(safe-area-inset-right)
    env(safe-area-inset-bottom)
    env(safe-area-inset-left);
}

For anything drawn in JavaScript, react to size changes instead of reading them once:

const chart = document.querySelector('#chart');

const observer = new ResizeObserver(([entry]) => {
  const { width, height } = entry.contentRect;
  renderChart(chart, { width, height });
});

observer.observe(chart);

One more: keep state across size changes. A fold or unfold should not reset a form, close a modal or scroll the list back to the top. If your router or framework remounts views on resize, fix that before worrying about pixels.

Test it in Xcode 27.1

Xcode 27.1 beta needs an Apple silicon Mac on macOS 26.6 or later. It includes an iPhone Duo simulator runtime that can fold, unfold and rotate. The first simulator boot can take several minutes, and most app extensions do not run in it yet.

  1. Build and run your app on the iPhone Duo simulator with npx cap run ios or from Xcode.
  2. Open each main screen, then fold and unfold with the screen open.
  3. Attach Safari's Web Inspector (Develop menu, then the simulator) and watch for layout shifts, console errors and resize handlers that fire too often.
  4. Rotate on both displays. Check the keyboard with a text field focused in each pose.
  5. Check modals, bottom sheets and anything positioned with fixed coordinates.

No Apple silicon Mac? You can run the same steps on a cloud Mac and pull screenshots back.

After 23 October: fix layout bugs the same day

The simulator will not find everything. Real users will unfold the device in the middle of checkout, in split view, with accessibility text sizes you did not test. The bug reports will arrive in the first week, and they will almost all be CSS.

Waiting for App Review for each of those fixes means a week of a broken first impression on a device whose owners are exactly the early adopters who leave reviews. With a live update system, a layout fix is a web build and one command:

npm run build
npx @otakit/cli upload --release

OtaKit downloads the new bundle in the background and applies it on the next launch by default. If you want to test the fix on your own devices first, release it to a staging channel and promote it once it looks right. This is well within Apple's rules: you are changing HTML, CSS and JavaScript, not the app's native code or purpose. See does Apple allow live updates.

A plan for the next four weeks

  1. Now: migrate to Capacitor 8.5 if you have not, and build with Xcode 27.1 beta.
  2. This week: run the table above against your codebase. Search for innerWidth, orientation, screen.width and fixed px widths on containers.
  3. Before the Xcode 27.1 release candidate: make sure the OtaKit plugin is in your next store build. The plugin is native, so it must ship in the binary.
  4. When Xcode 27.1 is final: submit that build so it is live before 23 October.
  5. Launch week: fix what users report and ship it over the air, with a staged rollout if the change is large.

Foldables will not be the last new screen shape. A layout that follows available space, plus a way to ship fixes in hours, covers the next one too.

Related docs