Mobile apps
Expo / React-Native apps get the full treatment — live simulator preview, and debug · preview · production builds with signing, all on a Mac host. No EAS, no separate build service.
Overview
Add an expo service to your loor.json and Loor
treats it as a real mobile app. Two things light up in the Studio preview pane: a
Simulator tab (a live iOS / Android device streamed into the browser) and a
Build tab (native builds, signed, downloadable). Both run on a Mac host attached
to your project — the same machine, no EAS and no third-party build pipeline. Everything an app
store needs — keystores, certificates, App Store Connect / Play uploads — is handled on Loor's
side.
The mobile service
A mobile service is domainless: no domain, no HTTP port. It uses
metroPort for the live dev server and builds to native artifacts. The minimum is just
a type and root; the mobile block lets you pin bundle
identifiers and per-profile settings.
"mobile": {
"type": "expo", // or "react-native"
"root": "apps/mobile",
"metroPort": 8081, // Metro dev server — mobile is domainless
"mobile": {
"platforms": ["ios", "android"],
"ios": { "bundleIdentifier": "com.acme.app", "deploymentTarget": "16.0" },
"android": { "package": "com.acme.app", "minSdkVersion": 24 }
}
} Build profiles
Profiles mirror EAS so the mental model carries over. Each profile maps to a platform-specific build + distribution:
| Profile | iOS | Android | For |
|---|---|---|---|
| development | Debug · unsigned simulator .app | Debug .apk | Run on the simulator / a dev device |
| preview | Release · internal .ipa | Release .apk | Share with testers |
| production | Release · App Store .ipa | .aab | Ship to the stores |
"build": {
"profiles": {
"development": { "ios": { "buildConfiguration": "Debug", "simulator": true }, "android": { "buildType": "apk" } },
"preview": { "ios": { "buildConfiguration": "Release", "distribution": "internal" }, "android": { "buildType": "apk" } },
"production": { "ios": { "buildConfiguration": "Release", "distribution": "store" }, "android": { "buildType": "aab" } }
}
}
Leave profiles out and Loor applies exactly this default matrix. Override only what
you need.
Simulator preview
In the IDE preview pane, switch to mobile and pick Simulator, then tap iOS or Android. The latest available device for that platform boots on the Mac host and streams to the browser over WebRTC — tap, type, swipe, rotate, hardware buttons. One latest simulator per platform (no device catalog to wade through); it's a real simulator, not a screenshot loop, so you see your app exactly as it runs. Vibe Chat can boot it for you too — just ask ("open the iOS simulator").
Building an app
Switch to the Build tab, pick a platform (iOS / Android) and a profile, and hit
Build. The Mac host clones your repo at the current commit, installs
dependencies, runs expo prebuild, compiles with Xcode / Gradle, signs, and exports
the artifact. You watch every step and the live log; the build is tracked server-side, so it
survives a refresh and you can come back to it. When it finishes, download the
.ipa / .apk / .aab straight from the panel. Builds run
one-at-a-time per host; the history list keeps your recent builds. Vibe Chat can kick off a
build for you too — ask "build the Android app for production" and it starts the same job.
Signing & credentials
Open Signing from the Build panel to manage credentials. They're stored
encrypted on Loor — never in loor.json, never in your repo — and
decrypted only on the Mac host at build time, into a throwaway keychain that's wiped when the
build ends.
- iOS (recommended): an App Store Connect API key (the
.p8plus Key ID + Issuer ID) and your Apple Team ID. Loor manages provisioning profiles and signs with it — the same mechanism EAS uses, no interactive Apple ID / 2FA. A distribution.p12+ provisioning profile works as a fallback. - Android: upload your release keystore (
.jks) with its alias and passwords. Loor signs release builds with it. - Stores (optional): the same ASC API key uploads to TestFlight; a Google Play service-account JSON uploads to Play.
Studio only ever shows you which credentials are set — never the values back. Development / simulator builds need no signing at all.
Artifacts & stores
Each finished build produces a downloadable artifact, retained on the host. Production iOS builds
can upload to App Store Connect (TestFlight) with your API key; production Android builds produce
a Play-ready .aab and, with a service account, upload to an internal track. Install a
preview .apk straight onto a device, or drag a simulator .app into a
running simulator.
Requirements
Mobile builds + simulator run on a Mac host assigned to your project by an admin (a provisioned Apple-Silicon Mac with Xcode, the Android SDK, and the Loor runtime). If you see "No simulator host assigned", ask an admin to attach one. A connected GitHub repo is required — builds clone from the current commit. Everything else — Metro, prebuild, signing, store upload — Loor handles for you.