iOS and Android
Mobile App Development
We build apps that live on a phone: Flutter and React Native when one codebase is the right answer, native Android in Kotlin or Java and native iOS in Swift when it is not. Before any of that, we will tell you plainly whether your idea needs an app at all, because plenty of what gets described as an app is better served by a website.
What we work with
- Flutter & React Native
- Android mobile app development (Kotlin/Java)
- Native iOS (Swift)
- Store submission for the App Store and Google Play
- Push, offline sync and over-the-air updates
Start here
Does this actually need to be an app?
A mobile app is not simply a website in a different shape. It is a distribution channel with a gatekeeper in front of it. Someone has to find your listing, decide to install it, hand over storage on a device they already feel is full, grant the permissions you ask for, and then not delete it a month later.
A responsive web page asks for none of that: a link opens it, and an update reaches everyone the moment it is deployed. That difference is worth settling before a line of Dart or Swift is written, because it decides whether the install step is buying you something or costing you something.
The install is a toll every single user pays once. The app has to be worth more than that toll before the first screen has any value at all — which is why the honest answer to some briefs is a website.
Reasons that genuinely justify an app
- Work continues with no signal in vans, warehouses, basements, aircraft and rural sites
- Hardware the browser cannot reach well: Bluetooth LE, NFC, barcode scanning at speed, background location
- Push notifications are the product loop, not a nice extra
- Biometric-gated data, or a secure element requirement
- Daily, habitual use where a home-screen icon earns its place
- A buyer or partner contractually expects a store listing
Reasons that usually do not
- Marketing content, news or a brochure that already reads well on mobile
- A booking or enquiry form used once or twice a year
- An internal dashboard people open at a desk
- A competitor has one and it looks like a gap
- Wanting a home-screen icon, which a progressive web app can also give you
If your brief lands on this side, we will say so and point you at web development instead. A rejected app costs more than an unbuilt one.
A worked example: “we need an app for our engineers”
Take a brief in that shape. Field engineers currently fill in a paper job sheet and type it up when they get back to the office, and somebody has decided an app would fix it. Work the requirement through rather than the request.
They spend their day in plant rooms, lift shafts and basements, so signal is unreliable and the sheet has to be completable without one. They photograph what they did, so the device has to hold images until it can upload them. They need the day's jobs before they leave the depot, and a job reassigned mid-morning has to reach them. Every one of those is a point for an app, and the last one is what push notifications are for.
Now change a single detail. The same job sheet, filled in by people sitting in offices on wifi, is a form. It wants a well-built responsive page and a saved login, and it will reach the browser on a laptop, a tablet and a phone without anyone installing anything. The brief did not change; the environment did, and the environment is what decides.
The first real decision
Cross-platform or native, and the honest trade-offs
People expect cross-platform to halve the cost. What it actually shares is the screen and business-logic layer. Store accounts, review submissions, release management, device testing, platform-specific design conventions and support stay stubbornly per-platform, and they do not shrink because the code is shared.
So choose on where your app spends its complexity, not on a slogan. The four options below are all things we build in; the question is only which one your particular app makes cheapest to live with.
Flutter
Flutter draws its own widgets rather than borrowing the platform's, so a screen looks the same on an iPhone and a Pixel, and custom, brand-led interfaces and animation stay predictable. The cost of that control is that your app does not inherit new platform UI behavior for free, binaries are heavier than a native equivalent, and anything unusual at the hardware boundary needs a platform channel written per platform. Dart is quick to read, but it is one more language in your organization.
React Native
React Native renders real platform views, so scrolling, text selection and accessibility behave the way each operating system intends, and a team that already writes React and TypeScript can read the codebase without learning a new language. The trade-off is dependency risk: much of the ecosystem is community-maintained, quality varies, and the move to the newer rendering architecture left some packages behind. We keep the native module count deliberately low and pin what we depend on.
Native Android — Kotlin and Java
Go native on Android when the app fights the operating system for a living: foreground services, scheduled background work, home-screen widgets, sustained Bluetooth sessions, or a printer and scanner stack that expects a real Android integration. Battery optimization and the aggressive process management some manufacturers ship on top of stock Android are where cross-platform abstractions leak first, and where Kotlin with Jetpack libraries pays for itself. Legacy Java modules can sit alongside Kotlin without a rewrite.
Native iOS — Swift
Swift with SwiftUI or UIKit is the right call when the iPhone experience is the product: home-screen and lock-screen widgets, live activities, Apple Watch companions, CarPlay, deep HealthKit or camera work, or a need to adopt a new iOS capability soon after it ships. A native iOS codebase can reach a new platform API directly, where a cross-platform one waits for plugin support to catch up.
Which way a requirement usually points
Read this as a starting position rather than a verdict. Most apps produce a few rows pulling one way and one row pulling the other, and the argument is about which row costs most to be wrong on.
| If the app has to… | Starting position | Why |
|---|---|---|
| Show lists, forms and media over an API | Flutter or React Native | Nothing here touches the platform hard enough to pay for two codebases. |
| Carry a strong custom visual identity, identical on both platforms | Flutter | One rendering engine means one set of pixels to sign off rather than two. |
| Feel like the platform it is running on | React Native, or native | React Native uses real platform views; Flutter deliberately draws its own. |
| Be maintained by a team already writing React and TypeScript | React Native | Your existing developers can read and change the codebase from day one. |
| Hold a long-lived Bluetooth session or track location in the background | Native | Background execution rules differ per platform and are where abstractions leak first. |
| Survive aggressive battery management on budget Android handsets | Native Android (Kotlin) | Foreground services and manufacturer-specific behavior need direct control. |
| Ship widgets, live activities, a Watch app or CarPlay | Native iOS (Swift) | These are Apple surfaces with no cross-platform equivalent worth relying on. |
| Diverge in features between iOS and Android over time | Two native codebases | A shared codebase full of platform conditionals costs more than two clean ones. |
We have no house default, and when the rows genuinely tie we lean cross-platform, because it is the cheaper mistake to make. A shared codebase that later has to go native is a port of work you have already specified and tested. Two native codebases that turn out not to have needed to be separate are duplicated effort you cannot get back. Whichever way it goes, the reasoning goes into the scope document, so the team that inherits the app can see why the decision was made instead of guessing at it.
Engineering detail
The parts of a mobile app that are easy to underestimate
Mobile estimates go wrong in the same four places, and none of them are screens. They do not appear in a design file or a feature list. They appear when the build is on a real handset, on a real network, on an ageing device, in front of a real reviewer.
Offline-first behavior and sync
A phone loses signal in elevators, parking garages, steel-framed warehouses and on train journeys. Offline-first means the local database is the source of truth for the screen, writes are queued rather than lost, and the interface says clearly what has synced and what has not.
The decisions that matter are the conflict policy — server-authoritative, last-write-wins or a per-field merge — and idempotency keys on every mutation, so a retried request cannot double-book a slot or take a payment twice. Both are settled during scoping, not during testing.
Push notifications and permissions
Push runs through APNs on iOS and Firebase Cloud Messaging on Android, and both require the user to say yes. Android 13 and later prompts for notification permission the way iOS always has, and a refusal is close to permanent, because the only way back is the system settings screen.
So we ask in context, after the app has shown why a notification is worth having, rather than on first launch. Every notification also needs a deep link that opens the correct screen from a cold start, and a plan for the fact that background delivery is best-effort rather than guaranteed.
Over-the-air updates
React Native and Flutter can both ship code updates outside a store release, through Expo Updates and CodePush-style services for React Native and Shorebird for Flutter. That turns a serious bug from a wait on review into a same-day fix. The limits are real: only the JavaScript or Dart layer moves, anything touching native code still needs a store build, and platform rules require that an over-the-air update does not change what the app is for. Native Android and iOS builds always go through the store.
The long tail of OS and device support
Every older operating system version you support is testing time you pay for on each release. iOS versions turn over faster, so the floor there is usually easy to agree. Android is where the tail sits: budget devices stay on old builds for years, screen shapes vary widely, and Google Play separately requires new and updated apps to target a recent Android API level, with that bar moving each year. We agree the minimum supported versions in writing at the start, revisit them annually, and test on real handsets rather than only on emulators.
Three of those four cost you a release to put right: a notification strategy can be changed, an over-the-air channel can be added, an OS floor can be raised. Adding offline sync to an app that assumed a connection is a rewrite of the data layer, which is why it is the first question we ask and the last one we compromise on.
The gatekeepers
Getting through App Store and Google Play review
Two things routinely catch first-time publishers out. The first is that developer accounts take calendar time of their own: enrolling an organization with Apple requires company verification and a legal signatory, and Google Play asks for its own identity and contact verification before a listing can go live. Start both the week the project starts, not the week you want to launch.
The second is that review is a human process against published rules. That is better news than it sounds, because it means most rejections are predictable and avoidable rather than bad luck.
What most commonly gets an app rejected
- Minimum functionality, a wrapper around a website with nothing a browser could not do
- No working demo account for a login-gated app, so the reviewer sees only a sign-in wall
- Sign-up with no in-app way to delete the account
- Permission prompts with vague purpose strings, where "we need your location" explains nothing
- Privacy declarations that contradict the SDKs actually bundled, in Apple's App Privacy details and Play's Data safety form
- Selling digital content or subscriptions around the platform's own billing
- A crash, a dead link, placeholder text or a privacy policy URL that 404s
- Screenshots that show features the build does not contain
Timing, and why we do not submit on the launch date
Review timetables belong to Apple and Google, and no agency can promise you one. A small update to an established app is normally the quickest case. A first submission of a brand new app takes longer and often comes back with questions before it is approved, and an appeal or a policy clarification adds more on top. Because none of that is under your control or ours, we submit with slack in the plan instead of on the launch date itself, and we tell you what the current queue looks like when we file.
The listing is a small project of its own
None of the following is code, and all of it blocks a submission. It is slow to produce from a standing start, which is how launch dates get lost after the build is finished, so we prepare it alongside development rather than after it.
| What the store wants | App Store | Google Play |
|---|---|---|
| Icon | Square store icon, fully opaque, at Apple's stated size | Square store icon at Play's stated size |
| Screenshots | A set per device class you support, iPhone and iPad | Phone screenshots, plus tablet sets if you list tablet support |
| Extra artwork | No feature graphic; an app preview video is optional | A feature graphic for the top of the listing |
| Store text | Name, subtitle, description, promotional text and a keyword field | App name, short description and full description; no keyword field |
| Privacy | Hosted privacy policy, plus App Privacy details declared per data type | Hosted privacy policy, plus the Data safety form |
| Ratings | Age rating questionnaire | Content rating questionnaire |
| Reviewer access | Working demo account and review notes | Working demo account and review notes |
| Technical and legal | Export compliance answers, support URL | Target API level met, app signing configured, support contact |
Most of that comes from your side rather than ours. The descriptions are marketing copy, the privacy policy is a legal document that has to describe what the app genuinely collects, and the data declarations have to be true, because a contradiction between the form and the bundled SDKs is one of the easiest rejections to earn. We tell you exactly what is needed and when. We do not write your privacy policy.
Before we start
What actually moves a mobile project's date
Almost never the number of screens. Three things move dates on mobile work, and all three are decided outside the codebase.
- The backend is not ready. An app is a client. If the API it talks to is being written at the same time, the app team either waits or builds against a mock and pays for the re-integration later. Where an API already exists, we want the documentation and a staging environment on the first day, not the first sprint review.
- The real devices arrive late. Emulators do not reproduce camera behavior, Bluetooth pairing, push delivery, thermal throttling or a manufacturer's battery manager. Discovering late in the build that the app must also run on a rugged scanner or an ageing warehouse tablet means sourcing the hardware and testing again.
- The listing material is late. Store enrolments, descriptions, screenshots, the privacy policy and the demo account are yours to produce. They are usually the last thing anyone thinks about and the first thing that stops a submission, which is why we ask for them at the start.
What we ask you for
Accounts and access
- Apple Developer Program and Play Console enrolments in your organization's name
- API documentation, a staging environment and credentials, if a backend already exists
- Any third-party accounts the app has to talk to, such as a payment or messaging provider
Material and decisions
- Brand assets, or a decision to run interface design first
- The handsets and hardware the app must work with — scanners, printers, beacons
- One named person who can approve a screen without convening a committee
Where we are not the right fit
We build application software for phones: forms, lists, media, hardware integrations, sync and connections back to whatever runs the business. That is a wide range, and it is not everything.
Real-time 3D games, engine-based titles, heavy on-device machine learning and augmented-reality products are outside what we take on. If that is the core of your idea rather than a small feature at the edge of it, a specialist studio will serve you better than we will — and we would rather say so at the first call than at the third.
After launch
Shipping is where the cost starts, not where it stops
All software needs looking after, which is why our website work comes with a maintenance plan. A mobile app puts a harder floor under that, because two platform owners set the schedule for you. Apple and Google each ship a major operating system release every year, and each one deprecates APIs, changes permission behavior or introduces a new screen shape.
Around that, signing certificates and provisioning profiles expire, push credentials need rotating, store policy changes can require a rebuild and resubmission on a deadline you did not set, and third-party SDKs go unmaintained. None of it is caused by anything you did, and all of it lands on your app anyway.
So we plan releases rather than emergencies: staged rollouts on Google Play and phased release on the App Store, crash and error monitoring watched during the ramp, and a halt rule if the crash-free rate moves the wrong way. Store reviews and ratings get read, because a one-star review describing a bug is a free reproduction report.
Between releases we keep dependencies current in small steps. That is far cheaper than a once-a-year upgrade that touches everything at once and lands on the same week as a forced platform deadline.
Scope first
A written feature list, the platforms, the minimum OS versions and the offline behavior, agreed before estimating.
Build on real devices
Test builds you can install through TestFlight and Play internal testing from early on, not a demo video at the end.
You own the accounts
Store listings, signing keys and repositories sit in your accounts, so you are never locked out of your own app.
How we quote
Mobile apps are quoted per project, in US dollars, once the scope above is written down. The platform count, the offline requirements and the integrations move the number far more than the screen count does, so there is no honest list price to publish here. Website work is separate and starts at $399, with website maintenance from $49 a month. Either way you get a fixed figure before any work begins.
All prices in US dollars (USD). We can invoice in GBP, EUR, AUD or INR on request.
Mobile App Development — FAQs
Ping us about your app
Tell us what the app has to do
Send us the feature list, the platforms you care about and anything the app must do without a connection. We will come back with a recommendation on native or cross-platform, the store requirements you will need to satisfy, and a fixed quote. If a website would serve you better, we will say that too.
Mon–Fri, 09:00–19:00 IST (UTC+5:30) — 4+ hours of live overlap with US Eastern; full overlap with UK and EU mornings.
Related services
Web Development
Fast, scalable websites and web apps to develop web application solutions with Laravel, React and modern stacks.
Custom Software
Custom software development for bespoke CRM, ERP and SaaS platforms, engineered around your exact workflow.