Software engineering · Mobile and cross-platform
Apps that keep working long after launch
We build native and cross-platform apps, and plan the release process, app store management and the realities of different devices from the start. Releasing the first version is the easy part.
Where this starts
Building the app is only a small part of the commitment
A mobile app is not just a website in a different shape. It runs on devices you do not control, is distributed through app stores you do not own, and depends on operating systems that change on someone else’s schedule. Many users will not update when asked. Teams often budget for building the app, but not for the two years afterwards, which is where most of the work is.
What we usually find
- A first version released, then nothing more, because nobody owns the release process
- An unexpected app store rejection that delays a launch
- Old versions still in use, calling an API that has since changed
- Crash reports with no way of telling which release or device caused them
- A separate codebase for each platform, now so different that they are effectively two products
- No plan for using the app offline, so it stops working on a train
Our position
Before writing any mobile code, the most important question is not which framework to use. It is who will release updates in eighteen months’ time, and how.
What the work covers
Build it, release it and keep it running
The choice of technology matters less than most discussions suggest. What matters is whether every stage of the app’s life has an owner and a repeatable process.
Native and cross-platform
We use Swift and Kotlin where the app genuinely needs features specific to each platform, and React Native or Flutter where a shared codebase suits the product better. We will explain which fits and why, rather than defaulting to our own preference.
Offline use and poor connections
We carefully design how the app stores data on the device, resolves conflicts and syncs when it reconnects. Mobile devices lose their connection regularly, and an app that ignores this is only a demonstration, not a product.
Real devices and platforms
We test on the devices and operating system versions your users actually have. Screen sizes, text sizes and accessibility settings are treated as requirements, not as unusual cases.
Release process
Builds, signing and gradual rollouts are automated, and anyone on the team can run the process. App store submission and review is a planned step, not a regular surprise.
Supporting older versions
Your API keeps supporting the app versions still in use. You cannot force people to update, and older versions always stay in use for longer than expected.
Crash reporting and product analytics
Every crash is linked to its release, device and operating system. A rise in failures can be diagnosed within an hour, rather than discussed for a week.
How releases become routine
A healthy app has uneventful releases
Everything below exists to turn a release from an event that needs planning into a routine step.
- Build
- Signed builds are produced by the pipeline from a tagged version, never from someone’s laptop. This also means the process still works when someone leaves.
- Test
- Automated tests run on a range of devices covering the operating system versions your users have, not only the latest one.
- Distribute
- Internal and beta versions are distributed automatically, so the business sees a change before customers do and feedback arrives before the app store release.
- Release
- New versions are rolled out gradually and stop automatically if crashes rise above a set level. A bad release only affects a small percentage of users.
- Monitor
- Crash and performance data is linked to each release and device, and appears in the same dashboards as the rest of your systems.
What you are left with
- Apps in both app stores, released from a pipeline rather than a laptop
- A documented release process that your own team can run
- Automated testing across the operating system versions your users have
- Gradual rollouts that stop automatically if crashes rise
- A versioning policy that both your API and your apps follow
Tell us who uses the app and what happens when they lose signal
The answer will shape the design more than the choice of framework ever will.
