Native iOS
Your app, rendered natively, no Mac required.
Contrast’s native surface runs on rnx, a clean-room React Native simulator built in CanvasKit that runs inside the browser, not a local iOS simulator process. It renders your app the way a real device would. It advertises a modern Fabric and new-architecture environment to the React Native bundle, so libraries take their native code paths instead of falling back to web shims.
Here is the Contrast side of native: how you turn it on and what to expect. The simulator itself, including its CLI, conformance suite, package compatibility, and engine architecture, is documented separately at the rnx docs.
Enable native
A project targets native when iOS is on in Project Settings → Runtimes. The App and Game templates ship with iOS enabled. The Website template is web only. With iOS on you get the native preview pane, iOS deploy options, and the native tools agents use.
iOS is the parity baseline. Android is bootstrapped and useful for focused slices, but not at full parity yet. Don’t treat it as a finished target.
Native setup
Contrast starters register their shared native integrations before One creates the router:
Point One at that file in vite.config.ts:
Keep this import in the native setup file. Importing it from a route or layout
is too late for APIs whose implementation is selected while the router starts.
The package registers the standard Tamagui native integrations and One’s native
Stack.Toolbar implementation.
The app still owns the corresponding native packages in dependencies.
Registration tells JavaScript which implementation to use. React Native
autolinking reads the app manifest to discover the native modules and pods.
Native form sheets and toolbars
Configure a route as a native-stack form sheet in the layout:
Compose the route’s native header menu and bottom toolbar through One:
Stack.Toolbar stays headless when native setup has not registered an
implementation. On native, the header menu and bottom toolbar are UIKit-owned
surfaces and their callbacks return to normal React state. On web, the toolbar
does not add a substitute DOM control.
Use rnx for the fast interaction loop, then verify native-stack presentation, detents, menus, and toolbar attachment on real iOS before shipping. Capture the same low-detent, high-detent, and open-menu states on both surfaces when visual parity matters.
Package compatibility
Native packages are the main thing to check before you rely on one. Drop a
package.json or lockfile onto the
package compatibility scanner and it scores every
dependency:
- supported and partial are validated, fully or in part.
- stub and auto-stub mean a native seam exists, or a basic no-op proxy stands in for an unrecognized package.
- unsupported means it needs a real native SDK or hardware the browser can’t provide.
- build-only is a build or config tool that doesn’t affect the running app.
Most pure-JS packages run from your bundle and aren’t listed individually, because rnx’s high core-RN conformance covers them. The ones that matter are packages with native modules, which need a seam. For the per-package detail and how custom stubs work, see the rnx compatibility docs.
Native assets and fonts
The Media pane in the Dev section manages a project’s native assets across
its Images, Fonts, and Splash tabs. Images land under
assets/images. Fonts land under public/fonts, either dropped in or installed
from Google Fonts, so the same file the browser fetches by path is the one native
bundles. A native font is ready once a .ttf or .otf file is present and
your code loads it through expo-font. The Fonts tab shows that readiness state
for each face.
Test on a real device
Rendering in the browser is the fast loop. When you want to feel the app on hardware, the App Store flow puts a build on your iPhone through TestFlight, and the Contrast phone app lets you drive and check work on the go.
rnx on its own
rnx also ships as a standalone simulator you can point at any React Native repo from the terminal, independent of Contrast:
Those commands, plus conformance, custom stubs, and the host, shell, and tenant execution model, are documented at the rnx docs, which generate from the simulator’s own source. Contrast links out to them rather than duplicating them, so the reference never drifts.