Mobile Apps

Mobile App Development


Most businesses do not need a mobile app. A responsive web application covers the majority of use cases, avoids app store review cycles, and eliminates platform-specific maintenance. We say this as a company that builds custom mobile app development projects regularly, because the distinction matters.

A mobile app earns its place when the use case demands capabilities that browsers cannot provide: offline data capture in areas with no signal, push notifications that reach users outside the browser, background GPS tracking, camera and barcode scanning with native performance, or biometric authentication tied to the device keychain. If your requirements include none of these, a custom web application will serve you better at lower cost.

We have been building business software since 2005, with 50+ Laravel applications in production. Our mobile work follows the same principle that guides everything else we build: the technology serves the business constraint, not the other way around.


When a Mobile App Is the Right Call

The decision between mobile app and web app is a technical one, not a preference. Three categories of requirement push a project toward native.

Hardware access beyond the browser sandbox

NFC for asset tagging. Bluetooth Low Energy for connecting to field equipment. Camera access with real-time processing rather than file upload. Accelerometer and gyroscope for equipment monitoring. The Web Bluetooth and Web NFC APIs exist but remain incomplete, inconsistent across devices, and absent on iOS Safari for most use cases.

Offline-first data capture

Field service engineers, delivery drivers, warehouse operatives. These users spend significant parts of their day without reliable connectivity. A web app with a service worker can cache static assets, but it cannot reliably queue complex transactional writes, resolve merge conflicts when the device reconnects, or handle large binary attachments like photos and signatures.

Persistent background processes

Geofencing that triggers when a driver enters a delivery zone. Background sync that uploads queued work orders while the phone sits in a pocket. Push notifications that wake the app to refresh critical data. These require native platform capabilities that Progressive Web Apps approximate but do not match.

If your use case fits none of these categories, start with a responsive web app. You can always add a mobile client later, and an API-first architecture makes that straightforward.


Why Expo and React Native, Not Native Swift or Kotlin

For business applications, cross platform app development with React Native (via Expo) is the right default. Not because it is cheaper per se, but because the constraints of business apps align with what cross-platform frameworks handle well.

Business applications are form-heavy, data-driven, and workflow-oriented. They display lists, capture input, show status, and navigate between screens. They are not GPU-intensive games or camera-filter apps that demand frame-level control over the rendering pipeline. For this category of work, React Native produces genuinely native UI components (not WebView wrappers) with a single TypeScript codebase that targets both iOS and Android.

The naive approach

Build from scratch using the bare React Native CLI. Manage native iOS and Android project files directly, handle Xcode and Android Studio configuration, write custom native modules for each platform, and maintain two separate build pipelines. For a team whose primary expertise is web and API development, this creates a maintenance surface that compounds over time.

The robust pattern

Use Expo as the managed layer. Expo abstracts native project configuration behind a declarative app.json, provides pre-built native modules for camera, file system, notifications, biometrics, and secure storage, and handles the build pipeline via EAS Build. When you need custom native code, config plugins and development builds give you escape hatches without ejecting.

We pair Expo with a Laravel API backend. The mobile app is a client, identical in architectural role to a web frontend. Authentication tokens, business logic, validation rules, and data persistence all live server-side. The mobile app handles presentation, offline caching, and device-specific features. This separation means the mobile codebase stays thin, focused, and replaceable.

When native development makes sense

Native Swift or Kotlin is the right choice when the app's core value depends on platform-specific capabilities that React Native cannot reach: AR experiences using ARKit or ARCore at full fidelity, custom camera pipelines with real-time ML inference, or deep Siri/Google Assistant integrations. In four years of mobile work for business clients, we have not yet needed to go fully native. The Expo ecosystem covers business app requirements comprehensively.


API-First Architecture: The Mobile App as a Client

Every mobile project we build follows an API-first pattern. The Laravel application exposes a RESTful API (or, where appropriate, GraphQL) that serves as the single source of truth. The mobile app consumes this API exactly as a web frontend would.

  • Shared business logic Validation rules, pricing calculations, workflow state transitions, and permission checks execute server-side. When a business rule changes, it changes in one place.
  • Independent deployment The API evolves behind versioned endpoints. A mobile app update and a backend change do not need to ship simultaneously. App store review cycles introduce delays that server deployments do not.
  • Multiple clients from one API The same Laravel API serves the mobile app, the web dashboard, webhook integrations, and background job processors. Adding a mobile client does not require rebuilding the backend.

The pattern is straightforward: Laravel handles authentication (Sanctum for token-based auth), authorisation (policies and gates), business logic (services and actions), and data (Eloquent with PostgreSQL). Expo handles screens, navigation, local state, offline queue, and device features.


Offline-First Patterns for Field Workers

Offline support is the most common reason our clients need a mobile app rather than a web app. Field service engineers inspecting equipment. Delivery drivers confirming drop-offs. Warehouse operatives scanning stock in buildings with poor signal. These users cannot wait for connectivity to do their work.

The naive approach: Check for network availability before each API call and show an error when offline. This fails because connectivity is not binary. A device can report "connected" while sitting on a network that drops 60% of packets.
The robust pattern: Assume the network is unreliable. Every write operation goes to a local queue (SQLite). The queue processor syncs when connectivity is available, using exponential backoff.

Each queued operation carries a timestamp, a unique client-generated ID, and enough context for the server to resolve conflicts. Conflict resolution follows a last-write-wins strategy for most business data, with explicit merge logic for cases where that would cause data loss.

Attachments (photos, signatures, PDF annotations) queue separately with chunked upload support. A 5 MB photo on a 2G connection will fail if sent as a single request. Chunked uploads with resume capability mean the file eventually arrives without requiring the user to retry.

This pattern requires server-side support. The Laravel API accepts idempotent writes keyed by client-generated UUIDs, handles out-of-order arrival gracefully, and returns sync status that the client uses to update its local database.


Push Notifications and Real-Time Updates

Push notifications in a business app serve a specific purpose: alerting users to events that require action. A new work order assigned. An approval waiting. A delivery window changed. They are not marketing tools.

Permission strategy

iOS requires explicit notification permission, and Apple rejects apps that request it on first launch without context. The pattern that works: wait until the user encounters a feature that benefits from notifications (for example, when they are first assigned a task), explain what they will receive, then trigger the permission prompt. This approach consistently achieves 70-80% opt-in rates in business apps versus 40-50% for prompt-on-launch.

Technical architecture

Expo's notifications module handles device token registration for both APNs (iOS) and FCM (Android). The Laravel backend stores device tokens per user (a user may have multiple devices) and dispatches notifications through a queue worker using Laravel's built-in notification system with custom channels for push delivery.

Foreground notifications

Update the app's state while it is open. A new item appears in a list. A badge count increments. These use the app's WebSocket connection or short-polling mechanism, not push notifications.

Background notifications

Arrive when the app is closed or backgrounded. They carry a payload the app uses to update its local data store on next launch, plus a visible alert for the user. Silent notifications trigger background sync on both platforms.


Authentication and Security Patterns

Mobile apps handle authentication differently from web apps because the device itself becomes a factor. The patterns we use are designed around this constraint.

Token-based authentication

The user authenticates once with email and password (or SSO). The server returns a long-lived refresh token and a short-lived access token. The refresh token is stored in the device's secure enclave (iOS Keychain, Android Keystore) via expo-secure-store, not in AsyncStorage. The access token lives in memory and expires after 15 minutes.

Biometric authentication

After initial login, the app offers Face ID or fingerprint unlock. A successful biometric check unlocks the securely stored refresh token, which exchanges for a new access token. The server never sees biometric data; it only sees a valid token.

Certificate pinning

For apps handling sensitive business data, we pin the expected TLS certificate in the app binary. This prevents man-in-the-middle attacks even on compromised networks. The trade-off is that certificate rotation requires an app update, so we plan pin rotations 30 days before certificate expiry.

Remote session management

The server tracks active device sessions per user. An administrator can revoke a specific device's access (for example, when a phone is lost) without affecting the user's other devices.

These patterns align with the security and operations standards we apply across all IGC projects.


App Store Deployment and OTA Updates

Getting a business app into production involves two distinct channels: app store releases and over-the-air (OTA) updates.

App store releases go through Apple's App Review and Google Play's review process. EAS Build compiles the native binary from the Expo project, signs it with the appropriate certificates, and submits it. Apple's review typically takes 24-48 hours; Google's is usually under 6 hours. For internal business apps, Apple's Enterprise programme or TestFlight and Google's internal testing tracks bypass public review.

OTA updates via EAS Update are the more interesting capability. Because Expo apps load JavaScript bundles at runtime, you can push code changes (UI fixes, business logic updates, new screens) without going through app store review. The app checks for updates on launch, downloads the new bundle in the background, and applies it on the next restart. A bug fix can reach every user's device within hours, not days.

The practical split: Approximately 80% of updates to a typical business app are JavaScript-only and eligible for OTA delivery. The remaining 20% (native dependency updates, new device features, Expo SDK upgrades) go through the app store.

We maintain three channels: development (latest builds for internal testing), staging (release candidates for client review), and production (live builds). EAS Update channels map directly to these environments, each pointing at the corresponding Laravel API environment.


Performance Considerations for Business Apps

Mobile app performance for business use cases differs from consumer app optimisation. The priorities are: reliable data loading on variable connections, smooth list scrolling for large datasets, and minimal battery drain during background sync.

Render performance

React Native's FlatList handles large lists through virtualisation. Keep list items shallow (three to four levels of nesting maximum) and move heavy computation to useMemo hooks.

Network efficiency

Batch related requests, use cursor-based pagination, and cache responses locally so repeat views load from SQLite rather than the network.

Battery impact

Sync aggressively on WiFi and charging, conservatively on cellular (every 15 minutes), and defer non-critical sync when battery drops below 20%.


When a Mobile App Is Not the Answer

Honesty matters more than a project fee. Many businesses approach us wanting a mobile app when a responsive web application would serve them better.

The app is primarily informational. A staff directory, a company handbook, a client-facing portfolio. These are websites. A responsive web app with a home screen shortcut provides the same experience.
All users have reliable connectivity. If your team works in offices with WiFi or urban areas with consistent 4G/5G, the offline-first argument disappears.
The budget does not cover ongoing maintenance. A mobile app is not a one-time build. OS updates, library deprecations, and app store policy changes require 15-20% of initial build cost per year.
The timeline demands it. A web app can ship incrementally with no review process. A mobile app requires enough functionality to pass app store review on first submission.

When a web app is the right answer, we build it as a custom web application with the same Laravel backend. If the mobile requirement emerges later, the API-first architecture means adding a mobile client is additive, not a rebuild.


Discuss Your Mobile Project

If your team works in the field, handles offline data capture, or needs device-level features that browsers cannot provide, a mobile app may be the right fit. The first conversation is free and comes with no obligation. We will tell you whether a mobile app, a web app, or something else entirely makes more sense for your situation.

Book a discovery call →
Graphic Swish