Development
The same bun dev that serves your site runs your app on an Android emulator, an iOS simulator or a phone on your desk. Edits reach the app as fast as they reach the browser.
#bun dev
With a mobile block in absolute.config.ts, bun dev starts a target for every platform in mobile.platforms. The first run sets up what is missing, asking before it installs anything:
$ bun dev➜ Local: http://localhost:3000/ ➜ Mobile: http://localhost:3000/__absolute/mobile-preview
Mobile targets start only in an interactive terminal. To run the web server alone:
bun dev --no-mobile # web only for this run
ABSOLUTE_NO_MOBILE=1 bun dev # same, for scripts and CI#Live reload on device
A release build carries its pages inside the app. In development, the app loads them from your dev server instead, so hot reload works exactly as it does in the browser. Emulators reach the server through adb reverse and the iOS Simulator through loopback. When the session ends, or the next time a crashed session is detected, the native project goes back to its production settings, so a development address never ends up in a store build.
| When you change | What happens |
|---|---|
| A page, component, stylesheet or public asset | Hot update on every target, including the app. No native rebuild. |
| absolute.config.ts, package.json or the lockfile | The native project is synced and rebuilt automatically. |
| capacitor.config.ts or files in the native project | The native project is synced and rebuilt automatically. |
| An Expo native route | Metro Fast Refresh, as in any Expo app. See Expo. |
#Logs and shortcuts
The app’s console output streams into the same terminal as your server, tagged [android] or [ios]. Type these at the bun dev prompt:
#Physical devices
Android. Connect the phone with USB debugging allowed, then pass its serial. The dev server listens on your local network so the phone can reach it.
adb devices # find the serial of the phone
bunx absolute dev --android-device R58N12ABCDEiOS. Pair the iPhone or iPad in Xcode, turn on Developer Mode, and choose a Development Team with automatic signing in the generated workspace once. Any identifier devicectl accepts works: the UDID, the device name or its serial number. AbsoluteJS builds, installs and launches the app, and later starts skip Xcode when nothing native has changed.
xcrun devicectl list devices # find the device identifier
bunx absolute dev --ios-device "Ada’s iPhone"dev.https and the app uses it too; there is no separate native setting. Android trusts the development certificate through a debug-only network setting that is removed when the session ends. The iOS Simulator gets it installed automatically. On a real iPhone, open the one-time link the terminal prints, install the profile, and turn it on under Settings → General → About → Certificate Trust Settings.import { defineConfig } from '@absolutejs/absolute';
export default defineConfig({
dev: { https: true },
mobile: {
appId: 'com.example.shop',
appName: 'Shop',
server: { productionOrigin: 'https://shop.example.com' }
}
});#Browser preview
Open the Mobile URL that bun dev prints, /__absolute/mobile-preview, to run your real pages inside an iOS- or Android-shaped frame with no SDK installed. It is more than a resized viewport: @absolutejs/devices and @absolutejs/http behave as they do in the app, and a panel drives the device around them.
Use it for fast work on app behavior, and an emulator, simulator or device for anything the operating system does itself:
| Feature | Browser preview | Emulator or device |
|---|---|---|
| Your pages with hot reload | ||
| Platform, network, lifecycle, Back and keyboard | ||
| Camera, location and notification permissions | ||
| Native rendering and WebView differences | ||
| Sign-in through the system browser | ||
| Keychain and Keystore storage | ||
| Push delivery | ||
| Background tasks and the app being closed by the OS | ||
| Needs an SDK | No | Yes |
#iOS from Linux or Windows
Xcode only runs on macOS, so AbsoluteJS uses a Mac you own as the iOS build host while you keep working on Linux, Windows, WSL or another Mac. Your editor, Bun and the dev server stay on your computer. The app in the Mac’s simulator reaches your dev server through an SSH tunnel, so hot reload works without copying anything for page edits. Set up the Mac once:
Check that you can SSH in with a key, then pair. Pairing confirms the Mac has macOS, Bun and Xcode, and stores only connection details, in ~/.absolutejs/mobile/remote-macs.json. The last Mac you paired is the default; ABSOLUTE_IOS_REMOTE=<name> picks another.
ssh builder@my-mac.local # accept the host key once
bunx absolute mobile pair mac studio builder@my-mac.local
# Another SSH port or workspace on the Mac
bunx absolute mobile pair mac studio builder@my-mac.local \
--port 2222 \
--workspace /Users/builder/AbsoluteJSFrom then on bun dev uses the Mac for iOS automatically, and --ios-device works for a phone on the Mac’s network. A Capacitor app needs its iOS project first (absolute mobile init); Expo generates its own.
| What | |
|---|---|
| Sent to the Mac | Your project, as an atomic snapshot, plus a checksum-verified AbsoluteJS agent |
| Never sent | .git, node_modules, build output, .absolutejs state, environment files, signing keys and profiles, Android keystores |
| Kept on the Mac between runs | node_modules, Xcode DerivedData and the installed app, so later starts are fast |
| Stays on your computer | The dev server, hot reload, logs and the development certificate’s private key |
bunx absolute mobile remotes # list paired Macs
bunx absolute mobile remotes inspect studio # disk use, caches, active builds
bunx absolute mobile doctor ios --remote studio
bunx absolute mobile remotes clean studio --yes
bunx absolute mobile unpair mac studioUnpairing removes only the local profile, never files on the Mac. The same Mac signs and uploads iOS releases; see Release.
#Checking your setup
mobile doctor checks the tools each platform needs and says what is missing; --fix installs it. Against a paired Mac it only reports, since the Mac is yours to configure.
bunx absolute mobile doctor # every platform
bunx absolute mobile doctor android --fix # install the SDK, emulator and Java 21
bunx absolute mobile doctor ios --fix # on a Mac: install a missing simulator runtimemobile inspect reports how AbsoluteJS sees your project: app identity, platforms, the device features found in your code and the plugins they need, whether the native projects exist, and whether the packaged pages are complete. It changes nothing, so it is safe in CI; --require-bundle fails when the packaged pages are missing or out of date.
bunx absolute mobile inspect
bunx absolute mobile inspect --json --require-bundle