Flutter · React Native · Native iOS and Android
Most business apps do not need two native codebases. Some do. We work through that decision with you first, because it sets the cost of every feature you add for the next three years.
The problem
The cross-platform question gets answered by ideology far too often. The useful version is a short list of what your app actually does. If the screens are lists, forms, maps, camera capture and push notifications, one Flutter codebase will serve both stores at close to native quality and roughly two-thirds of the engineering cost.
Native starts to earn its price when the app depends on something the platform does differently and deeply: sustained background location, Bluetooth Low Energy with a specific peripheral, heavy real-time video or audio processing, tight integration with HealthKit or CarPlay, or a widget and watch experience that is a genuine part of the product. In those cases a shared codebase spends its savings on plugin workarounds and platform-specific bugs.
There is a third answer that gets ignored: your users may not want an app at all. Installing something is a real cost, and if the workflow is occasional, a fast mobile web experience will be used more than an app that sits uninstalled. We have talked clients out of app projects on exactly this basis, usually where the app was going to be a login wrapper around a portal.
The field-use question decides more than the platform question does. An app used by drivers, technicians or sales staff will spend part of its day with no usable connection, and that single fact reshapes the data model, the sync strategy and the testing plan far more than the choice of Flutter or Kotlin.
What is included
9 areas of work. Most engagements start with one or two and widen once the first release is in use.
One Dart codebase producing Android and iOS builds with a shared design system, plus desktop and web targets where they are useful. Our default for business applications, field tools, marketplaces and customer apps where the interface is the product rather than the hardware access.
The right choice when you already have a React web team and want shared conventions, typing and some shared logic across web and mobile. New Architecture, typed navigation and native modules written where a package would be a liability.
Swift and Kotlin where the app depends on platform depth: background location over long shifts, BLE peripherals, camera pipelines, widgets, watch apps and background processing that a bridge cannot serve reliably.
The server half of a mobile product: authentication and refresh tokens, versioned APIs that keep an old app version working, push notification delivery through FCM and APNs, and real-time channels for chat, tracking and live status.
A local database as the source of truth for the screen, a write queue that survives a force-quit, and explicit conflict resolution rules agreed with you rather than last-write-wins by accident. Designed for the delivery van in a basement and the plant with no signal at the far end.
Secrets kept out of the bundle, tokens in Keychain and Keystore, certificate pinning where the threat model justifies it, root and jailbreak awareness, and server-side authorisation on every endpoint. Client-side checks are a speed bump, never the control.
Store listings, privacy nutrition labels and the Play data safety form filled in accurately, signing and provisioning set up in your accounts, staged rollouts, and handling of the rejection categories that catch first-time publishers.
Crashlytics or Sentry with symbol upload so a stack trace is readable, funnel events defined around real questions, and a release checklist that includes watching the crash-free rate for the first forty-eight hours.
Number of distinct screens, whether the backend exists, offline requirements, real-time features, payments, and how many user roles each screen has to serve. Store presence and device fragmentation add a fixed overhead that no framework choice removes.
How we work
The first two weeks produce a clickable prototype on a real device rather than a specification document. Handing a phone to the people who will use the app, in the place they will use it, surfaces more requirement errors in an afternoon than a month of workshops. Warehouse lighting, gloved hands and a screen in direct sun are requirements, and none of them show up in a Figma review.
Builds go to internal testers from the first sprint through TestFlight and Play internal testing, so release mechanics are exercised early rather than discovered in the week you planned to launch. Store review is a scheduling dependency with its own rejection risk, and treating it as a formality at the end is how launch dates slip by a fortnight.
After release the work changes shape rather than stopping. Crash reporting, adoption of the current version, and where people abandon a flow, reviewed together on a cadence, with a backlog that reflects what the data shows rather than what was assumed at kickoff. Forced-update handling is built in from the first version, because eventually you will need it.
In practice
The first two weeks produce a clickable prototype on a real device rather than a specification document. Handing a phone to the people who will use the app, in the place they will use it, surfaces more requirement errors in an afternoon than a month of workshops. Warehouse lighting, gloved hands and a screen in direct sun are requirements, and none of them show up in a Figma review.
Where it comes up
Stack
We pick from a stack we actually run in production. Where your team already has a preference and it is a reasonable fit, we work in yours instead of arguing for ours.
Sector context
Domain knowledge shortens discovery. These are the sectors where we already understand the vocabulary and the failure modes, so the first version of the build is closer to right.
Shift-based production data, downtime causes, quality records and the daily gap between what the ERP holds and what the floor actually did.
Appointments, records, billing and reporting, where patient data handling and clinical workflow set the constraints before anything is designed.
Lot and parcel movement, job-work with karigars, grading records and the reconciliation that follows a stone through five pairs of hands.
We have not published a case study for this service yet. When we do, it will name the client with written permission and quote numbers the client can defend. Nothing else is worth reading.
Until then, the useful version of proof is a conversation about your problem. Ask us how we would approach it, what we would refuse to do, and where the estimate is soft.
Ask about comparable workQuestions
Flutter is our default for business and consumer apps because the rendering is consistent across both platforms and the tooling is stable, which shows up as fewer platform-specific defects late in a project. React Native becomes the better answer when you already run a React web team, because the hiring pool, the conventions and some of the logic carry across. Neither is right when the app depends on deep platform capability, and that is a native conversation.
A focused first version with one primary user role, a working backend and store submission is usually twelve to sixteen weeks. The variables that move it most are whether the backend already exists, whether the app must work offline, and how many user roles the same screens have to serve. Payments, real-time tracking and document capture each add meaningfully to that.
You do. Apple Developer and Google Play accounts are registered to your business, and we are added as team members with the access we need. Publishing under a vendor's account is a common shortcut that becomes a serious problem when you change vendor, because the app, its reviews and its install base are attached to the account, not to you.
It is a normal part of the process rather than a crisis, and most first rejections fall into a handful of predictable categories: incomplete metadata, an account deletion path that is missing, a permission prompt without a clear reason string, or a login wall in front of content that should be browsable. We plan for one review cycle in the schedule and respond with a fix and a note rather than an argument.
Usually. We start with a paid assessment: reading the code, running the build, checking dependency versions, signing setup and crash history, then reporting what it would take to work in it safely. Occasionally the honest answer is that a rewrite of one layer is cheaper than maintaining it, and we would rather tell you that with the reasoning attached than quietly accept a maintenance retainer.
Ask how often a user will open it. Daily or weekly use justifies the install; a form filled in twice a year does not, and a fast mobile web page will get used more. Push notifications, offline operation, camera and hardware access, and a home-screen habit are the real reasons to build an app. Being on a store is not one.
Works well with
Send a paragraph about what is not working today. You will get a written reply from someone who would be on the build, covering how we would approach it, roughly what a first phase looks like, and whether mobile app development is even the right place to spend the budget.
What happens next