Native Apps
Every AbsoluteJS app is also an iOS and Android app. Add a mobile block to absolute.config.ts and the pages you have already written ship to the App Store and Google Play: the same routes, the same server and the same code.
#One config
Three fields make an app: its store identifier, its name and the server it talks to.
import { defineConfig } from '@absolutejs/absolute';
export default defineConfig({
mobile: {
appId: 'com.example.shop',
appName: 'Shop',
server: { productionOrigin: 'https://shop.example.com' }
}
});bunx absolute mobile init # create the iOS and Android projects
bun dev # web, plus your app on an emulator or simulatordeepLinks. Your server publishes the files that link your domain to the app, and a production server will not start without them. Branding & deep links covers both.#What you get
AbsoluteJS looks at what your app already uses and sets up the native side to match. Install @absolutejs/auth and the app signs in; install @absolutejs/sync and it works offline; import camera and the camera plugin and its permission prompts are added.
#How it works
Because the interface ships inside the app, it starts instantly and offline. Each page asks your server for fresh data when it opens; data that must be there offline lives in @absolutejs/sync. When you deploy a new server, apps already installed keep working: the server keeps answering the three most recent releases, kept in a blob store or your build directory, and asks for an update only when an installed app is older than that. How it works has the details.
#Same code everywhere
Device features come from @absolutejs/devices. The build picks the right implementation for the browser, iOS or Android, so your page never checks which one it is running on. This function takes a photo with the native camera in the app and through the browser on the web:
import { camera, haptics } from '@absolutejs/devices';
const takeReceiptPhoto = async () => {
const permission = await camera.requestPermission();
if (permission.state !== 'granted') return null;
await haptics.impact('light');
return camera.takePhoto({ direction: 'rear' });
};#Capacitor or Expo
Apps are built with Capacitor unless you choose otherwise, and that is the right choice for almost every app. Expo is there for teams that need specific screens in React Native: very long lists, gesture-heavy interfaces, native stack transitions, or a library that only exists for React Native. You keep every other page as it is. Expo explains when it pays off.
| Feature | Capacitor (default) | Expo |
|---|---|---|
| Every page in every supported framework | ||
| Screens written in React Native Expo routes you choose can be React Native components; every other route stays your AbsoluteJS page. | ||
| Native project | Committed, editable mobile/ | Generated, never edited |
| Device features, Auth, Sync and push | ||
| Signed over-the-air updates | ||
| Best for | Every app | Screens that need native UI |
#Frameworks
| Pages written in | Capacitor | Expo |
|---|---|---|
| React | ||
| Svelte | ||
| Vue | ||
| Angular | ||
| HTML | ||
| HTMX hx-get, hx-post and form actions are pointed at your production server. | ||
| Ember | Coming soon | Coming soon |
| Astro | Coming soon | Coming soon |
#Platforms
| Platform | Build on | Setup |
|---|---|---|
| Android | Linux, macOS, Windows or WSL | absolute mobile doctor android --fix installs the SDK, emulator and Java 21 |
| iOS | macOS with Xcode, or any machine with a paired Mac | absolute mobile pair mac builds and runs on a Mac over SSH |
$ bunx absolute mobile doctorChecks the Android SDK, emulator, Java and Xcode, and says what is missing.
#Packages
Native support is part of @absolutejs/absolute. These packages provide the parts your pages call, and the build installs the versions it needs.
@absolutejs/devicesCamera, location, notifications, share, storage and more. One API on the web and in the app.
@absolutejs/httpHTTP to your server that carries the signed-in user’s credentials in the app and in the browser.
@absolutejs/sync-capacitorEncrypted SQLite storage and background sync for @absolutejs/sync in the app.
@absolutejs/dispatchAPNs, FCM and Web Push delivery with device registration that follows the signed-in user.
@absolutejs/auth-expoThe Expo implementation of @absolutejs/auth sign-in.
@absolutejs/sync-expoEncrypted SQLite storage and background sync for @absolutejs/sync in Expo.
#Where next
From config to your app running on an emulator or simulator.
How pages are packaged, how data arrives, and how older app versions keep working.
Every device feature, with what each one does on the web, iOS and Android.
Build, sign and publish to the App Store and Google Play.