app/_layout.tsx, app/(auth)/sign-in.tsx, NativeWind classes — rendered inside a CSS chrome that mimics an iPhone or Android device. No simulator install. No real phone required for layout work.
What it is — and what it isn’t
It is: a fast, accurate way to check layouts, navigation flows, Tailwind/NativeWind styling, Supabase queries, form behavior, and route transitions. The bundle is built by Metro the same way EAS would build it for production. It isn’t: a full native runtime. APIs that touch native code — push notifications, biometric auth, camera, file system, haptics, Bluetooth — won’t fire in the iframe. For those you publish to a Preview OTA channel and open the link on a real device with Expo Go.Devices
Eleven device presets cover the realistic spread of modern hardware. Pick from the dropdown in the preview toolbar:
Each preset uses the logical pixel dimensions Apple and Google publish, not the raw screen resolution. So a Pixel 8 frame is 412×915 (logical), not 1080×2400 (physical) — which matches what your
<View>s actually render against.
The Galaxy Fold preset renders the folded outer screen (374×882). For unfolded testing, use the iPad mini preset as a stand-in — same aspect ratio family.
Landscape mode
Click the rotate icon in the toolbar to flip orientation. The chrome rotates with the content — notch ends up on the right, home indicator on the bottom — so screenshots look correct for App Store landscape submissions. Some screens are intentionally portrait-only (auth flows, simple forms). React Native respects theapp.json orientation setting at runtime, but the preview lets you override it visually so you can audit what would happen if a user rotated mid-flow.
Color variants
Below the device dropdown is a color picker for the chrome itself. Six accent colors per device:- iPhone: Natural Titanium, Blue Titanium, White Titanium, Black Titanium, Gold, Pacific Blue
- Android: Obsidian, Porcelain, Bay, Mint, Wintergreen, Rose
Boot lifecycle
When you open the preview pane:1
Fly machine spin-up (cold boot ~10–20s)
A per-project Fly machine boots from
ghcr.io/locus2012/hiveku-previews:expo. First boot pulls the Docker image (~400 MB) and starts Metro. You see a “Starting your project…” splash with a moving progress bar.2
Metro bundle (~5–8s after spin-up)
npx expo start --web --port 3000 compiles your app/, components/, lib/ directories into a single JS bundle. Source maps are inline so errors point at the file you wrote, not the bundle line.3
Iframe handshake
Once Metro responds with
200 OK, the LivePreview iframe loads https://hvk-{hash}.preview.hiveku.com. You see your sign-in screen rendered inside the phone frame.4
Hot reload
Subsequent edits trigger Metro HMR. JS-only changes apply in ~1.5 seconds without a full reload. Adding a native dependency (e.g.
expo-camera) requires a full rebuild — Metro detects the dependency change and shows a “rebuilding native bundle” toast.Errors in the preview
Metro errors don’t return HTTP 500 — they return HTTP 200 with the error embedded in the bundle response. We detect 8 distinct Metro patterns and surface them as a clear banner above the iframe:
Each banner has a Fix with AI button that drops the error into the chat as the next user message — the AI reads the relevant files and proposes a patch.
Bundle size warnings
If your Metro bundle exceeds 75 MB compressed, the preview toolbar shows a yellow “Bundle size: 81.2 MB” chip. Tap it for a breakdown by package:- Native modules contributing the most bytes (e.g.
react-native-skia: 14.2 MB) - Asset sizes (PNG/SVG you’ve added under
assets/) - Whether tree-shaking is fully eliminating dev-only code
Auth & data flow in the preview
The preview is a real environment, not a mock:- Supabase queries hit your actual project database (provisioned at project creation)
- The sign-up button creates a real
auth.usersrow - Items you create persist across reloads, across other devices, and into the EAS-built binary later
- RLS policies enforce the same
auth.uid() = user_idrules in preview as in production
Web-only quirks to know
The preview runs React Native Web, which means a few things behave slightly differently than on a real device:
These are cosmetic — your code doesn’t change. Just don’t be surprised when a screenshot from the preview looks 20px taller than a real-device screenshot (no status bar inset).
Editor integration
The preview pane sits beside the file tree and Monaco editor. Three syncing flavors:- Save → reload (~1.5s): Edit a file in the editor, save (Cmd+S), and the preview hot-reloads.
- AI edit → reload (~3s): AI chat applies a patch via
manage_filetool, file-sync pushes to the Fly machine, Metro HMR triggers. - Branch switch (~10s): If you switch git branches via the GitHub panel, the preview re-pulls and rebuilds.
What’s next
Builds & Submissions
OTA channel deep-dive, the full Build & Ship lifecycle, and Fix-with-AI workflows.
Native Modules
Which packages work in the web preview vs need a real device or full rebuild.
App Store Assets
Use the preview’s screenshots feature when generating App Store hero images.
Mobile Credentials
Connect your Apple + Google accounts to start shipping past the preview.