A mobile application, in the stores

React Native with native modules where JavaScript will not do

A cross-platform mobile client for the platform, written in React Native with native Android modules where the JavaScript layer cannot reach — background message delivery, floating overlay windows, device enrolment and secure credential storage.

Every number here names where it came from and when it was measured.
MeasureValueSourceMeasured
Native Android modules alongside the React Native codebaseKotlin modules for overlays, background delivery and enrolmentandroid source tree in the mobile client repository
Kotlin source in the mobile client24 filesfind . -name '*.kt' across project repositories
Distribution channels operated2 (store release and over-the-air update)mobile release process

What building it taught us

Cross-platform frameworks are sold on the promise that you write once. You do, for perhaps eighty per cent of an application. The remaining fifth is where the work is, and it is invariably the part that makes the app feel native rather than wrapped: notifications that arrive when the app is closed, overlays that survive the app losing focus, enrolment flows that touch the secure element.

Our overlay work is a good illustration of a subtle class of bug. A floating head is raised for any message arriving from a conversation other than the one on screen — simple enough, until you notice the unread badge is drawn twice, once in JavaScript and once in native code, and that the heads live in two separate stores so clearing one leaves the other populated. Two sources of truth for one visual element is the commonest structural defect in mobile applications and it is almost never visible until a user reports something impossible.

Enrolment taught us about ordering. A one-time enrolment token was being consumed before device registration completed, so any later failure in the flow presented to the user as 'this code has already been used' — a message that sends them to support rather than to retry, and that describes a symptom rather than the cause. Sequencing a multi-step flow so that its failure messages remain truthful is design work, not just engineering.

The release process is deliberately boring: builds happen on one machine that has the toolchain, over-the-air updates are handled separately from store releases, and neither is done from a laptop at the end of a day.

Built with

  • React Native
  • TypeScript
  • Kotlin
  • Android SDK
  • push notifications
  • WebSocket

What this qualifies us for

Mobile applicationsCross-platform where it makes sense, native where it does notReal-time systemsLive data, messaging, presence and media — the unforgiving end of the webCustom web applicationsThe system your business actually runs on, built properly

Tell us what you are trying to do

A short conversation is usually enough to tell whether we are the right people. If we are not, we will say so and point you somewhere better.

Start a conversationI already use KamoCRMHow we quote