Mobile Engineering
We build the iOS and Android apps people open to review a record, sign an approval and authorize a change. They have to load on a five-year-old phone over a flaky 3G connection, work offline when the network drops, and recover gracefully from a backgrounded session the user forgot they had open. A crash during a critical approval is not a metric; it is an incident.
Cold start to first action
Crash-free sessions
Minimum OS supported
Offline-capable critical flows
Why Mobile
The phone is where trust meets the thumb
The phone is the surface a customer opens at 2am to approve a release, to check whether their data survived the night, or to authorise a change they cannot undo. That moment is the trust test, and we engineer for it specifically: the app cannot lie about the network, cannot freeze mid-approval, cannot show a stale state when the user is about to sign. Every critical-path screen is built to survive a dropped connection mid-tap and recover to a consistent state — never a half-sent one. Biometrics are convenient, but the security boundary they protect has to be designed first; we treat Face ID as the lock, not the door.
We refuse the idea that mobile is "the website in a wrapper". Our apps are native where the cost of a millisecond matters — biometrics, secure enclave, background sync, push delivery — and shared everywhere else through a single TypeScript codebase. Accessibility is a release gate, not an afterthought: a VoiceOver user has to complete the same wire a sighted user does, in the same number of taps, with the same confirmation copy read aloud. And because a phone is the most personal device a person owns, we treat privacy as a feature: the app collects the telemetry it needs to fix crashes and nothing more, and the user can see and delete that data from inside the app.
What we build
From approval apps to operator consoles on tablets, here is what leaves our keyboards and ships to the App Store and Play Store.
Approval & Signing Apps
Native iOS and Android clients for record approvals, document signing and key ceremonies — biometric-gated, secure-enclave-backed, and offline-capable when the network drops mid-ceremony.
Operator Tablets
Internal compliance and finance tools running on managed tablets, with audit-grade input controls and a signed-action trail that maps every tap back to an operator and a device.
Push & Background Sync
Silent push and background-fetch that keep record states and approval queues fresh without draining the battery — and that survive iOS background-app-kill and Android Doze.
Shared TypeScript Core
Domain logic, validation, and domain primitives live in a single TypeScript module consumed by both platforms — written once, reviewed once, behaviourally tested once.
Offline-First Critical Flows
Critical flows queue locally on device, sync when the network returns, and never show a success state for a transaction that has not been confirmed by the backend.
Accessibility & VoiceOver
Every critical screen ships with VoiceOver and TalkBack labels, dynamic-type support, and a tap-by-tap test plan a screen-reader user can complete unaided.
How we work
Our loop is shared-core, native-shell. Here is one orbit, from keyboard to store.
Specify the shared core
Engineer pairs with backend and design on a written spec: shared validation, states, copy in two languages, accessibility labels, acceptance tests.
Implement the core in TypeScript
Shared logic — domain math, validation, state machines — is implemented once and behaviourally tested once, before any platform-specific shell is written.
Build native shells
iOS (Swift) and Android (Kotlin) shells consume the shared core; biometrics, secure enclave and push are implemented natively where millisecond cost matters.
Test on real devices
A real-device farm runs every PR on five-year-old hardware over a throttled 3G profile; a regression on a low-end device blocks the release.
Phased store rollout
Releases ship to 1% of users then 10% then 100% over 72 hours, with a kill-switch that reverts server-side without a new store submission.
Observe crashes, ship a fix
Crash telemetry feeds the next sprint; a regression that fires more than twice triggers a hot-fix release within 24 hours. We do not wait for the next scheduled release to fix a crash.
Definition of done
A mobile release ships only when all of this is true
Crash-free
Crash-free sessions ≥ 99.4% on the previous release; any new crash class blocks the rollout.
Accessible
VoiceOver and TalkBack labels merged, dynamic-type verified, screen-reader test plan completed unaided on every critical screen.
Offline-safe
Every critical flow survives a dropped connection mid-tap and recovers to a consistent state — never a half-sent one.
Low-end ready
Cold start under 2s on a five-year-old device over throttled 3G; memory under the budget on the lowest-supported hardware.
Revertible
A server-side kill-switch can disable the feature without a new store submission; a regression can be turned off within minutes, not the days a store review takes.
Tools & why we use them
Shared core, native shells. Each tool was chosen for its failure mode, not its demo.
Native where milliseconds matter: biometrics, secure enclave, push delivery. Wraps the shared TypeScript core.
Same reason, other platform. Coroutines for background sync that survives Doze and background-app-kill.
Domain math, validation and state machines written once, reviewed once, behaviourally tested once — then consumed by both shells.
Crash telemetry that feeds the next sprint; a regression that fires more than twice triggers a hot-fix within 24 hours.
Real-device farm on every PR; five-year-old hardware over throttled 3G; a regression on a low-end device blocks release.
Phased store rollout to 1% then 10% then 100% over 72 hours, with a server-side kill-switch independent of store review.
Server-driven feature flags let us turn a feature off without a store submission; we can revert within minutes.
Accessibility lint on every PR; VoiceOver and TalkBack test plans completed unaided before a critical screen ships.
How we interface
Where mobile meets the rest of the company
Backend
Shared TypeScript core is co-owned; backend writes the server side of the contract, mobile writes the client side, and contract tests prove they agree on every PR.
QA
Maestro flows run on every PR on the real-device farm; QA owns the critical-path scenario matrix that runs against every release candidate before phased rollout begins.
DevOps
Phased store rollout is owned jointly; DevOps owns the kill-switch infrastructure, mobile owns the feature-flag gates. Either can turn a feature off within minutes.
Design
Designers spec states and accessibility labels jointly with engineers; a critical screen does not ship without a VoiceOver label spec merged first.
Questions we get asked
Why a shared TypeScript core and not full native?
Domain math, validation and state machines are the riskiest code we write; writing them twice in two languages doubles the bug surface. A single reviewed, behaviourally-tested core consumed by native shells gives us correctness once and native UX where it matters.
How do you handle a dropped connection mid-approval?
Every critical action is idempotent on the backend; the app queues the request locally, retries with the same idempotency key when the network returns, and never shows a success state until the backend has confirmed it.
Do you really test on five-year-old hardware?
Yes — on a real-device farm with throttled 3G. A regression on a low-end device blocks the release even if it is invisible on a flagship, because that is the phone most of our customers actually hold.
What happens if Face ID is bypassed?
Face ID unlocks a session; it does not authorise a change. Every critical action requires a second factor that survives a stolen unlocked phone — a server-side authorisation the user must approve from a trusted device.
Can you revert a release without waiting for the store?
Yes. Server-side feature flags let us turn a feature off within minutes, independent of store review. A new binary submission is the last resort, not the first.
Our mission
Build mobile apps that earn trust at 2am, on a five-year-old phone, over a flaky network, when the user is approving something they cannot undo. We treat the phone as the trust surface where the thumb meets the ledger — and we engineer accordingly.