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
resizeevent 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:
| Pattern | What goes wrong | Fix |
|---|---|---|
| Reading window.innerWidth once at startup | Layout decisions freeze at the size the app launched with | Use 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 columns | Branch on available width, not orientation |
| Fixed pixel widths for sheets, modals and cards | Content is stranded in a narrow column on the inner display | Use max-width with fluid percentages or clamp() |
| Canvas, charts or maps sized once | Blurry or cropped rendering after unfolding | Observe the container with ResizeObserver and re-render |
| Hard-coded safe-area padding | Controls under the camera area or rounded corners in some poses | Use env(safe-area-inset-*) everywhere |
| Virtual lists with a fixed item count per screen | Blank gaps or overdraw after the viewport grows | Recalculate 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.
- Build and run your app on the iPhone Duo simulator with
npx cap run iosor from Xcode. - Open each main screen, then fold and unfold with the screen open.
- Attach Safari's Web Inspector (Develop menu, then the simulator) and watch for layout shifts, console errors and resize handlers that fire too often.
- Rotate on both displays. Check the keyboard with a text field focused in each pose.
- 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
- Now: migrate to Capacitor 8.5 if you have not, and build with Xcode 27.1 beta.
- This week: run the table above against your codebase. Search for
innerWidth,orientation,screen.widthand fixedpxwidths on containers. - 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.
- When Xcode 27.1 is final: submit that build so it is live before 23 October.
- 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.