Lightening Tech Evidence, not opinion

Mobile & App Development

One codebase, both app stores

A React Native or Flutter app that ships to iPhone and Android from a single codebase — with the publishing work for each store priced honestly rather than assumed to be free.

From
$4,000–$30,000
Typical time
6–16 weeks
Usually bought by
Most SMEs

What this actually solves

The arithmetic is the reason this exists. Two native apps means two codebases, two teams' worth of work, two sets of bugs and two maintenance bills for the rest of the product's life. For most small and mid-sized businesses that sum never closes. A single cross-platform codebase gets you the great majority of the same product for a fraction of the cost, and it goes on paying you back every month afterwards, because every fix and every new feature is written once.

There is a second benefit that clients rarely ask for by name but notice immediately. With one codebase, both platforms get the same feature on the same day and behave the same way. With two, the Android version quietly falls a release behind, the two apps drift apart, and support becomes a conversation about which phone the customer is holding. That drift is expensive in a way that never appears on a quotation.

Where this service stops being the right answer is worth stating. Sustained heavy graphics, deep or unusual hardware integration, and watch or TV companions are not cross-platform territory. If your project needs those, we would rather tell you in the first call than discover it in week seven.

What we do, and in what order

  1. Discovery call, and the list of what version one will not contain. Not a feature workshop — a conversation about what actually happens in your business today, where the money leaks, and which single moment the app is meant to fix. The exclusion list comes out of this call and goes into the specification. Two to three days.
  2. Written specification, screen count and deposit. Scope in mobile is best measured in screens, so the specification names every screen and prices additional ones up front. That turns a week-six argument into a line item. It also states, explicitly, that both store accounts are opened in your name and the fees are yours. Three to five days.
  3. Accounts before code. Apple Developer Programme at $99 a year, Play Console at a one-off $25, both in your name, plus a dedicated email address for the app rather than somebody's personal Gmail. Apple's organisation verification can take a fortnight, so it starts now and not in the submission week. One day of work, then the platforms take their time.
  4. Screen map and data model, approved in writing. Every screen, every route between them, then the entities behind them and the places that will need an index. This is also where the concurrency questions get answered — what happens when two people try to claim the same last slot is a design decision, not a bug to find later. Three to five days.
  5. Build, screen by screen, on your phone and ours. Static screens first, then screens that read data, then screens that write it. A commit for every working screen, and a build in your hands early through TestFlight and Play's internal testing track rather than an APK sent over WhatsApp. Four to ten weeks depending on scope.
  6. Testing on real handsets, and the store assets. Physical devices on real networks, then a day and a half of listing work — icon, screenshots at both stores' sizes, descriptions, live privacy policy URL, App Privacy and Data safety forms, content rating, demo account. One to two weeks.
  7. Submission, review and rejection response. Both stores, with the review window stated separately in the timeline because it is not in anyone's control. One to two weeks.
  8. Handover. Both store accounts confirmed in your name, keystore and password, backend access, and a written page on how the next release goes out. One day.

Typical stack — React Native with Expo, or Flutter; Firebase or Supabase for the backend; EAS Build for iOS builds; TestFlight and Play Console for distribution; Sentry or Crashlytics for what happens after launch.

What moves the price

The range is $4,000–$30,000 across 6–16 weeks. Three things account for almost all of that spread.

Screen count and where the data lives. Building against an existing API you already own is one job. Designing and standing up a new backend, plus whatever admin interface your staff need to run it, is a larger one.

Offline capability. An app that must work with no signal and reconcile when the connection returns is roughly twice the work of one that assumes connectivity. It is the single largest swing factor in this service and it is the one most often left out of a brief.

Payments. In-app purchases and subscriptions bring store rules, a billing layer, receipt validation and edge cases around refunds and lapsed access. It is effectively a project inside the project and it is priced as one.

What usually goes wrong

Both platforms are quoted as one price, and the iPhone half is forgotten. One codebase halves the building. It does not halve the publishing. You still need Apple's paid account, TestFlight set up, a separate set of screenshots, a separate review, and time to handle the things that behave differently on iOS. Reserve real budget for the iPhone side of launch or the project eats its own margin.

Over-the-air updates get treated as a way around store review. One codebase does make it possible to push a fix straight to phones with no submission — but only on the React Native side, not Flutter, and only for the JavaScript layer. Anything that touches native code, adds a permission or changes what the app is for goes through both stores like any other release, and pushing that kind of change over the air is against their rules. A plan built on "we will just push it" comes apart the first time a change lands on the wrong side of that line. Assume review, and treat over-the-air as the narrow exception it actually is.

Builds are shared as raw files instead of through test tracks. Sending an APK over a chat app once sets the expectation that every build arrives that way, and it destroys the record of which version you actually looked at. When you report a bug that was fixed two builds ago, nobody can prove which build you were holding. TestFlight and Play's internal track exist precisely so that every build has a number and a date attached to it.

See where the site stands before you brief anyone.

If the site is already live, start from what it scores rather than from a guess. The audit reports what it checked, what it found, and — the part most tools leave out — what it could not check, and why.

See the website audit Talk about this work

Questions people ask before they commit.

Is a cross-platform app worse than a native one?
For most business apps, no. You are trading a small amount of platform polish and some access to the newest platform features for roughly half the build cost and one codebase to maintain instead of two. Where it does not hold up is heavy real-time graphics, deep hardware work, and watch or TV companions, and we will say so rather than sell around it.
React Native or Flutter — how do you choose?
The real difference is that Flutter paints every control itself on its own canvas, so both platforms look identical, while React Native drives the platform's actual components, so each platform keeps its own behaviour. Flutter suits a strong custom design that must be pixel-identical everywhere. React Native suits apps that share a backend and a web product. If you already have code in one of them, that decides it.
Does one codebase mean one price for both stores?
It halves the building, not the publishing. Each store needs its own developer account, its own screenshots at its own sizes, its own compliance forms and its own review. Budget for the iPhone side separately — it is a meaningful share of the launch work and pretending otherwise is how projects run over.
Can you build the iPhone version without a Mac in the room?
Yes. Expo's EAS Build and equivalent services compile and sign on Apple hardware in the cloud, which is a normal, supported route rather than a workaround. It is worth knowing the limitation — when something goes wrong deep in native code, cloud builds give you less to work with than a machine in front of you.
Can you update the app without going through review every time?
Partly, and only on React Native. Over-the-air updates can replace the JavaScript layer without a store submission, which is genuinely useful for copy fixes and small changes. Anything touching native code or a new permission still goes through the stores. We will tell you which side of that line a change falls on.
What if the app has to work without internet?
Then say so at the quotation stage, because it is close to double the work. Offline is not a setting — it means local storage, a queue of pending changes, and a rule for what happens when two people edit the same thing while disconnected. It is entirely doable and it belongs in the scope from day one, not week six.

Often taken together.

Start with the brief, not the invoice.

Send what you are trying to achieve. You get a written scope, a price and a date — or an honest “this is not the right service for that”.

Talk about Cross-platform app All Mobile & App Development services