AbsoluteJS

Mobile Config Reference

Every field of the mobile block in absolute.config.ts. Three are required; everything else has a default or is only needed for the feature it configures. After a change, run bunx absolute mobile sync to apply it to the native projects.

#Examples

Minimal. Enough to develop and run on emulators, simulators and devices.

TS
mobile: {
  appId: 'com.example.shop',
  appName: 'Shop',
  server: { productionOrigin: 'https://shop.example.com' }
}

Ready for the stores. Branding, deep links, push, error reporting and over-the-air updates.

TS
import { defineConfig } from '@absolutejs/absolute';

export default defineConfig({
  mobile: {
    appId: 'com.example.shop',
    appName: 'Shop',
    entry: '/home',
    platforms: ['ios', 'android'],
    server: { productionOrigin: 'https://shop.example.com' },
    ios: { version: '1.4.0' },
    branding: {
      icon: 'branding/icon.png',
      android: {
        backgroundColor: '#0F172A',
        foreground: 'branding/android-foreground.png',
        monochrome: 'branding/android-monochrome.png'
      },
      ios: {
        darkIcon: 'branding/icon-dark.png',
        tintedIcon: 'branding/icon-tinted.png'
      },
      splash: {
        backgroundColor: '#FFFFFF',
        darkBackgroundColor: '#0F172A',
        logoScale: 0.25
      }
    },
    deepLinks: {
      scheme: 'shop',
      hosts: ['links.example.com'],
      apple: { appIdPrefix: 'ABCDE12345' },
      android: {
        sha256CertificateFingerprints: [
          '14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5'
        ]
      }
    },
    pushNotifications: {
      android: { googleServicesFile: 'google-services.json' }
    },
    observability: {
      project: 'shop',
      environment: 'production',
      sampleRate: 0.5
    },
    updates: {
      channel: 'production',
      publicKeys: { '2026-10': 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE…' },
      server: {
        rollout: { automatic: true }
      }
    }
  }
});

#Required

FieldTypeDefaultWhat it does
appIdstringRequiredStore identifier in reverse-domain form, such as com.example.shop. Each segment starts with a letter.
appNamestringRequiredThe name shown under the app icon.
server.productionOriginstringRequiredYour deployed server, where the app loads page data and calls your API. HTTPS only (http is allowed on localhost), with no path, query, fragment or credentials.

#App and projects

FieldTypeDefaultWhat it does
engine'capacitor' | 'expo''capacitor'Capacitor builds every app. Choose Expo to write some screens in React Native.
entrystring'/'The route the app opens on. It must be one of your page routes.
platforms('ios' | 'android')[]['ios', 'android']Which native projects to generate and build. At least one.
ios.versionstringNoneApp Store version, one to three numbers such as 1.4.0. Needed for App Store builds; build numbers are assigned for you.
nativeProject.directorystring'mobile'Where the android and ios projects live. With Expo the generated project defaults to .absolutejs/mobile/expo.
bundleDirectorystring'.absolutejs/mobile/web'Where the packaged interface is written before it is copied into the native projects. Must stay inside the project.
compatibility.storestringNoneModule whose default export is a blob store, such as awsS3BlobStore from @absolutejs/blob/aws-s3. Builds keep their release history there, so a fresh CI checkout still serves apps already installed. Since 0.20.0-beta.134.
compatibility.prefixstring'absolutejs/mobile-compatibility'Key prefix inside the store, for several apps or environments sharing one bucket.

Your server publishes the Apple and Android association files for these hosts automatically. A production server will not start while the identity for a configured platform is missing.

FieldTypeDefaultWhat it does
deepLinks.schemestringappId, lowercasedCustom URL scheme such as shop://, also used for the sign-in callback.
deepLinks.hostsstring[]Your production hostExtra HTTPS hosts whose links open the app. Plain hostnames: no port, wildcard or path. Your production host is always included.
deepLinks.apple.appIdPrefixstringNoneYour Apple App ID prefix, usually the ten-character Team ID. Required in production when iOS is a platform.
deepLinks.android.sha256CertificateFingerprintsstring[]NoneSHA-256 fingerprints of every certificate that signs your Android builds, including Play App Signing. Colons are optional. Required in production when Android is a platform.

#Branding

absolute mobile assets generates every icon and splash size from these images. Colours are #RRGGBB.

FieldTypeDefaultWhat it does
branding.iconstringRequired if branding is setSquare PNG, at least 1024×1024. Used for iOS and as the base of the Android icon.
branding.android.backgroundColor#RRGGBB'#FFFFFF'Adaptive icon background colour.
branding.android.backgroundImagestringNoneOpaque 1024×1024 PNG used as the adaptive icon background instead of a colour.
branding.android.foregroundstringDerived from iconTransparent 1024×1024 PNG kept inside Android’s safe zone.
branding.android.monochromestringNoneTransparent single-colour 1024×1024 PNG for themed icons.
branding.ios.darkIconstringNone1024×1024 PNG for the dark appearance.
branding.ios.tintedIconstringNone1024×1024 PNG for the tinted appearance.
branding.splash.backgroundColor#RRGGBB'#FFFFFF'Launch screen background in light mode.
branding.splash.darkBackgroundColor#RRGGBB'#111111'Launch screen background in dark mode.
branding.splash.imagestringNoneA finished square launch image, at least 2732×2732. Without one, your icon is centred on the background.
branding.splash.darkImagestringNoneThe dark-mode launch image, at least 2732×2732.
branding.splash.logoScalenumber0.2Size of the centred icon relative to the screen, from 0.1 to 0.4.

#Push notifications

iOS push needs no config. Page code uses pushNotifications from @absolutejs/devices; the server side is set up in @absolutejs/auth.

FieldTypeDefaultWhat it does
pushNotifications.android.googleServicesFilestring'google-services.json'Firebase config for Android push. It must contain a client for your appId, and is copied into the Android project when you use pushNotifications.

#Observability

JavaScript errors and native crashes, hangs and ANRs are sent to a route on your production server.

FieldTypeDefaultWhat it does
observability.projectstringRequired if observability is setProject name attached to every report, up to 255 characters.
observability.environmentstringNoneEnvironment attached to reports, such as production. 1 to 64 characters.
observability.routestring'/api/observability/errors'The route on your production server that receives errors and native crash reports. Your server provides it.
observability.sampleRatenumber1Fraction of errors sent, from 0 to 1.

#Updates

Signed over-the-air updates for your interface. Changes to native features still need a store build.

FieldTypeDefaultWhat it does
updates.publicKeysRecord<string, string>Required if updates is setBase64 DER ECDSA P-256 public keys, by key ID. Keep old IDs while installed apps still trust them.
updates.channelstring'production'The release channel this build follows.
updates.manifestUrlstring/__absolute/mobile/updates/<channel>/update.json on your serverWhere the app looks for updates. HTTPS only outside localhost.
updates.bootTimeoutMsnumber20000How long a new update has to show its first page before the app rolls back. 5000 to 120000.
updates.expoCodeSigning{ certificatePath, keyId? }keyId 'main'Expo only. The certificate Expo uses to verify updates; its private key stays on your server.
updates.server.autoMountbooleantrueServe updates from your AbsoluteJS server. The manifest must then be on productionOrigin and end in /update.json.
updates.server.registrystring'mobile.update.ts'The module that stores releases, created by absolute mobile update provision.
updates.server.healthfalse | { failureRate?, minimumReports?, secretEnv? }On: 0.2, 20, ABSOLUTE_MOBILE_UPDATE_HEALTH_SECRETInstalled apps report whether updates start. A release whose failure rate passes failureRate after minimumReports is paused.
updates.server.rolloutfalse | { automatic?, stages? }OffStaged rollout. Default stages are 5%, 25% and 100%, each observed for 60 minutes with at most 5% failures. automatic moves through them on its own. Requires health.
updates.server.expoPrivateKeyEnvstring'ABSOLUTE_EXPO_UPDATE_PRIVATE_KEY'Expo only. Environment variable holding the private key that signs updates.
updates.server.expoCodeSigningKeysRecord<string, { certificatePath, privateKeyEnv }>NoneExpo only. Previous signing keys, kept while apps signed with them are still installed.

#Release policy

FieldTypeDefaultWhat it does
release.certificationfalse | { channels?, googlePlayTracks? }production: Android installed, iOS storeWhat testing a release needs before it is published to a channel or Play track. channels maps a channel to android: installed and ios: simulator, device or store. false turns the requirement off.

#Expo only

With engine: 'expo', two more fields are available. Every shared field above works the same way.

TS
mobile: {
  engine: 'expo',
  appId: 'com.example.shop',
  appName: 'Shop',
  server: { productionOrigin: 'https://shop.example.com' },
  routes: {
    native: {
      '/scanner': './mobile/native/scanner.tsx',
      '/products/:productId': './mobile/native/product.tsx'
    }
  }
}
FieldTypeDefaultWhat it does
routes.nativeRecord<string, string>NoneRoute patterns rendered by a React Native module. :name matches one segment; a final * matches the rest. Every other route stays your AbsoluteJS page.
routes.default'web''web'Routes not listed under native are your AbsoluteJS pages.
expo.sdkVersion5757The Expo SDK the generated project uses.
Native routes
Patterns are canonical paths with no query or trailing slash, and a parameter name can appear only once. A root /* is not allowed, and /__absolute/native is reserved. Expo covers writing these screens.