Mobile Builder Technical Specifications
How Mobile Builder serves your component trees over-the-air, compiles real native binaries on EAS without a Mac, binds screens to any Aeion collection, ships 42 industry templates and 346 native components, and rolls back any publish in one click.
Capabilities & Performance
App architecture
Server-Driven UI — your component tree lives in Aeion, the app fetches and renders it natively
OTA update
Publish a change, every device pulls the new tree on next launch — no App Store review
Native runtime
Expo SDK 55 with the New Architecture (JSI + Fabric)
Build target
EAS cloud — iOS and Android, 10–20 min per platform, no Mac required
Industry templates
42 — pre-loaded screens, navigation, branding, and data bindings
Native components
346 across 14 categories — forms, commerce, maps, media, charts, signature pad, biometric, barcode/NFC, more
Component tree depth
Up to 10 levels of nesting (validated at save)
Data bindings
Every component can bind to any Aeion collection — filters, sort, field mapping, no code
Offline
WatermelonDB per-component — configurable sync intervals and conflict resolution
AI screen generation
Natural-language description → component tree (falls back to keyword-based component matching when AI unavailable)
Analytics
Immutable event ledger — events never modified or deleted, appended as-received per batch
Retention cohorts
D1 / D7 / D14 / D30
Funnels
Multi-step with drop-off and average-time-to-step metrics
Push
Per-app campaigns, device tokens, channel segmentation
Beta testing
TestFlight (iOS) + Play Console internal track (Android), invite by email
Build types
Full app, iOS App Clip, Android Instant App
Signing
Per-app credential storage with 30-day pre-expiry alerts
Localization
Per-app translations served at runtime; locale-aware fallback
Deep linking
Universal Links (iOS) + App Links (Android), per-app route table
1. Server-Driven UI (SDUI) — How Your App Updates Without App Store Review
Every Aeion-built app ships as a thin native runtime that fetches its component tree from the Aeion runtime API on launch. The component tree is a typed JSON structure — what to render, what props, what data to bind, in what order:
typescript
interface ComponentNode {
id: string;
type: string; // a component from the native library (346 available)
props?: Record<string, any>;
children?: ComponentNode[];
slots?: Record<string, ComponentNode[]>;
}
`
When you change a button color, add a screen, or re-bind a list to a different collection, you Publish in the admin UI. The runtime API immediately starts serving the new tree, and every device that launches the app from that point forward renders the new layout — no App Store re-submission, no Apple Review, no Play Console rollout.
Tree validation caps nesting at 10 levels deep so you can't accidentally publish a runaway recursive layout. Every save validates component IDs against the registered component catalog and checks that bound collections exist in your tenant.
2. Runtime API — What the Device Actually Calls
| Endpoint | Purpose |
|---|---|
| `GET /mobile-builder/runtime/{bundleId}/config` | Fetch the published component tree, navigation config, and theme |
| `POST /mobile-builder/runtime/{bundleId}/auth` | Exchange a user session for a signed, app-scoped runtime JWT |
| `GET /mobile-builder/runtime/{bundleId}/ota-check` | Check OTA rollout status — current/latest version, release notes, and whether this device is in the rollout percentage |
| `POST /mobile-builder/runtime/{bundleId}/events` | Batch analytics event ingestion (rate-limited per device) |
| `POST /mobile-builder/runtime/{bundleId}/tokens` | Push notification device token registration |
| `POST /mobile-builder/runtime/{bundleId}/sync` | Offline-first batched mutation sync |
3. Data Binding — Connect Components to Aeion Collections
Every list, card, chart, or map component can be bound to an Aeion collection without writing code. In the canvas, select a component → Data Binding panel:
json
{
"type": "collection",
"collectionSlug": "commerce_products",
"filters": {
"status": { "equals": "active" },
"category": { "equals": "electronics" }
},
"limit": 50,
"sort": [{ "field": "createdAt", "direction": "desc" }],
"fieldMapping": {
"imageUrl": "images[0].url",
"name": "title",
"price": "salePrice ?? price"
}
}
Filter operators include equals, not_equals, gt/gte/lt/lte, in, contains, starts_with, ends_with, plus the full Aeion QueryBuilder for complex predicates.
Field mapping translates between collection field names and component prop names — so a ProductCard expecting imageUrl can render from a product collection that calls it images[0].url without a custom transform.
Context variables like $currentUser, $tenant, $now are supported so a Fleet driver app can show only "tasks where assignedDriver = $currentUser" without per-user configuration.
Out-of-the-box bindings exist for every Aeion module: CRM (contacts / deals / activities), Commerce (products / orders / customers), Fleet (vehicles / drivers / tasks / geofences), Hospitality (reservations / rooms / services), Health (patients / appointments / medications), Events (attendees / sessions / check-ins), plus any custom collection.
4. EAS Build — Cloud Compilation, No Mac
Triggering a native build creates a build record in the admin UI and submits to EAS Build (Expo's cloud compilation service). EAS provisions a macOS build VM for iOS or a Linux build VM for Android, compiles your React Native app, signs it with your stored credentials, and returns a downloadable artifact (.ipa for iOS, .aab for Android).
Build profiles are defined in eas.json — development, preview, production. Each profile can specify different resource classes (macOS version, Xcode version, Node version).
Build types:
full_app— Complete native app binaryapp_clip— iOS App Clip (lightweight version that launches without install)instant_app— Android Instant App equivalent
Status polling + webhooks — the admin UI polls EAS for status; EAS also calls our webhook on completion. Both pathways update the same build record, so you always see the truth.
Signing credentials are stored encrypted, per-app — iOS provisioning profile + .p12, Android keystore + key alias + store password. A workflow trigger fires 30 days before any credential expires so you renew proactively rather than discovering it during a release.
5. Native Component Library — 346 Components in 14 Categories
| Category | Sampled components |
|---|---|
| Layout | Stack, Row, Column, MasonryGrid, HorizontalCarousel, SwipeableList |
| Navigation | TabBar, StackNavigator, DrawerMenu, Breadcrumb, BackButton |
| Forms | TextInput, TextArea, PinInput, DatePicker, TimePicker, ColorPicker, Slider, Stepper, Checkbox, RadioGroup, ToggleSwitch, SearchBar, FileUpload, CameraCapture, RatingStar, Autocomplete, MultiSelect, SignaturePad |
| Commerce | ProductCard, ProductGrid, AddToCartButton, CartIcon, CheckoutButton, AddressForm, CouponInput, PaymentSheet |
| Maps | MapView, MarkerPin, RouteLine, GeofenceCircle, GpsTracking |
| Media | ImageGallery, VideoPlayer, AudioPlayer, DocumentViewer, PdfViewer |
| Charts | BarChart, LineChart, PieChart, AreaChart, MetricCard, TrendIndicator |
| Social | UserAvatar, UserCard, FollowButton, ShareButton, CommentThread |
| Auth & Security | BiometricButton (FaceID / TouchID), PinInput |
| Field Service | SignaturePad, PdfViewer, BarcodeScanner, NfcReader |
| Monetization | StripeCheckout (recommended default — server-priced, no App Store/Play Store IAP review), SubscriptionPaywall + StoreProductList (RevenueCat, opt-in, native-build only) |
| Data | OfflineSyncProvider (WatermelonDB), FlatList, DataTable, PullToRefresh |
| General | Card, Accordion, Modal, BottomSheet, ToastNotification, ProgressBar, SkeletonLoader, EmptyState |
6. 42 Industry Templates
Each template is a complete starting point — navigation, default screens, theme, permissions, and data bindings already wired. Pick a template, change the name + bundle ID + brand colors, and you have a working app:
eventsHardwareKiosk, fleetDriver, hotelGuest, patientPortal, shoppingApp, businessPhone, employeePortal, lmsStudent, diningStaff, legalClient, eventAttendee, hotelStaff, crmMobile, diningGuest, fieldService, gymMember, productionCrew, scmOperator, eventsStaff, smartSpace, recruitPipeline, marketingDash, expenseApprover, healthProvider, helpdeskAgent, warehousePicker, securityOfficer, teamCollab, eventsExhibitor, authorCompanion, manuscriptReader, loyaltyMember, constructionField, workspaceEmployee, conciergeStaff, teamInbox, communityForum, interactiveRetailCompanion, smartCampusKiosk, productionScriptSupervisor, productionCameraDept, productionHMUCostume
Templates declare their required Aeion modules (e.g., Fleet Driver requires the Fleet module) and recommended pricing tier. Some screens may be locked behind a tier — those screens show a paywall fallback at runtime if the tenant hasn't licensed the required module.
7. Analytics — Immutable Event Ledger
Mobile Builder ships with first-class analytics — no Segment or Mixpanel required. The runtime SDK auto-instruments common events:
- Lifecycle:
app_open,app_background - Navigation:
screen_view(with screenName, screenId) - Interaction:
button_click,form_submit,search - Commerce:
add_to_cart,purchase - Auth:
sign_up,login - Social:
share - Engagement:
notification_open - Technical:
error
Custom events can be emitted from any component handler.
Immutability — analytics events are write-once: nothing in the ingestion pipeline updates or deletes a row once it lands.
Retention curves are computed per cohort with configurable intervals (D1 / D7 / D14 / D30). Cohort users are grouped by install date, then counted as "returning on day N."
Funnel analysis is multi-step — define an ordered sequence of events (install → signup → first_purchase), the engine counts users at each step, computes conversion vs the previous step and drop-off, and returns the average time from start to each step.
Per-screen stats include views, unique users, average session duration, bounce rate, top entry / exit screens.
8. AI Screen Generation
Describe what you want in natural language and the AI Copilot generates a starting component tree:
> "I want a product listing screen with a search bar, category filter chips at the top, and a grid of product cards with image, name, price, and add-to-cart button"
Output is a valid component tree with bound data sources where possible — you review, customize, and publish. Falls back to keyword-based component matching when the AI service is unavailable so you always get a starting point, never a hard fail.
The keyword library covers common screen archetypes — list / feed / search, form / login / register, dashboard / analytics, commerce / cart / checkout, map / location / GPS, profile / settings, calendar / agenda, media / gallery / video, chat / messaging, navigation / tabs, data / charts — and suggests up to 8 components per archetype.
9. Offline-First — WatermelonDB Per Component
Components that load data from collections can be configured as offline-first with WatermelonDB as the local replica. The runtime keeps a per-collection local copy and reconciles changes via a configurable conflict-resolution strategy (last-write-wins, reject-on-conflict, or field-merge).
Sync intervals are per-component — a price list might sync every 5 minutes while a configuration table syncs hourly. Components that need real-time data (chat, live order status) skip the offline tier and stream via WebSocket.
Key Architecture Decisions
App architecture
Server-Driven UI (JSON tree) — OTA updates without App Store review
Component tree
Typed JSON, 10-level depth cap — Declarative, versionable, diffable, safe
Offline
WatermelonDB per component — Configurable per collection, conflict-resolution per component
Build
EAS cloud — no Mac required — Windows, Linux, or browser can trigger iOS builds
AI fallback
Keyword-based component matching — Always returns a valid screen, no AI required
Analytics
Immutable event ledger — Events never modified or deleted, audit-safe
Retention
D1 / D7 / D14 / D30 cohorts — Standard SaaS retention metrics out of the box
Signing
Per-app encrypted credentials — iOS / Android keys isolated per app, 30-day expiry alerts
Localization
Runtime locale fallback — One app, many languages, served at runtime
Versioning
Immutable publish snapshots — One-click rollback to any previous publish