App Development
Cross-platform apps with Flutter and React Native
Cross-platform development builds one codebase that runs on both iOS and Android, cutting cost and time roughly in half against two native apps. With Flutter or React Native, the result is fast and feels right on both platforms.
Who it is for: Businesses that need an app on both stores without funding two separate builds, and products where speed to market matters more than the last few percent of native polish.
Everything in this service
- One Flutter or React Native codebase for both platforms
- Framework recommendation based on your product, not our habit
- Native modules where the framework needs help
- Testing on real iOS and Android devices
- Both store submissions handled
What to expect
- Both stores covered for far less than two native builds
- Features that ship once and land on both platforms
- A maintenance bill for one codebase, not two
How cross-platform apps actually works
What a shared codebase actually saves, and what it does not
The pitch for cross-platform is that you write once and ship twice. The reality is more like writing most of it once, and the difference between most and all is where projects get their surprises.
What genuinely gets shared is the majority of the work: business logic, data handling, the connection to your server, state management, most screen layouts, most components, and validation rules. Fixing a bug in that shared code fixes it everywhere, and adding a feature there adds it everywhere. Over the life of a product that compounding effect on maintenance is often worth more than the saving on the initial build.
What is not shared is easy to underestimate. Two store submissions, two sets of store assets and metadata, two review processes and two rejection risks. Testing on both platforms, which is not halved by sharing code because the runtime behaviour still differs. Platform-specific behaviour for movement between screens, permissions and notifications. Any integration where the framework has no ready-made bridge. And configuration for signing, certificates, build pipelines and release. A realistic expectation is a substantial saving on a first build and a larger saving on ongoing feature work, rather than paying half of everything forever.
- Shared: logic, data, server communication, most layout and components
- Not shared: submissions, store assets, review, device testing, release setup
- Bug fixes and features land on both platforms at once, which compounds
- Testing effort is reduced but nothing like halved
- Expect a real saving, not a fifty percent saving on everything
Where platform-specific work is still required
Every cross-platform project has native work in it. The question is how much, and finding out late is what turns a comfortable budget into an uncomfortable one.
The usual areas are these. Hardware and system features the framework does not wrap, or wraps only partially, which is common for newer capabilities. Push notifications, which need per-platform configuration and behave differently in the background. Deep linking and how the app is opened from outside. In-app purchases and subscriptions, where each store has its own system and its own edge cases around restoring, upgrading and refunding. Widgets, watch apps and system extensions, which are native by definition. Background execution, which follows platform rules regardless of what framework you used. And platform interface conventions, which need per-platform handling if the app is to feel right on both.
The way to control this is to inventory it before committing. Take the feature list and mark each item as fully supported by the framework, supported through a well-maintained community package, or requiring native code. That third group is the real estimate. A short list is fine and normal. A long one, especially if several items sit in areas the framework struggles with, is a signal to consider native instead, because a cross-platform app carrying extensive native code on both sides has taken on the costs of both approaches.
- Notifications, deep links and purchases always need per-platform work
- Widgets, watch apps and extensions are native by definition
- Check each community package for maintenance before depending on it
- Mark every feature as supported, packaged, or native before committing
- A long native list means cross-platform may be the wrong choice
Performance trade-offs, described honestly
Modern cross-platform frameworks perform well. The claim that they are inevitably slow is out of date. But there are real differences, and they appear in specific places rather than uniformly.
Startup time is often slightly longer, since the framework runtime has to initialise before your code runs. Frameworks that keep a bridge between the interface and the application code can show delay in interactions that fire very frequently, such as gesture-driven animation, though this has improved considerably. Heavy computation on the device, complex list rendering with many live items, and anything doing continuous rendering are where a gap can still be felt. Application size is usually larger, because the framework ships with the app, which matters when many of your users are on limited storage or slow connections.
For most business applications none of this is perceptible. Forms, lists, content, dashboards, messaging and commerce run at a standard that users will not distinguish from native. The gap shows up in the demanding cases: sustained animation, real-time media processing, games. The practical approach is to identify early whether your product has any such moment, then prototype exactly that one thing on a mid-range device before committing to the framework. One afternoon of measurement is worth more than any amount of general argument, and it is the honest way to answer the question for your specific product.
- Expect slightly slower startup and a larger download size
- Most business apps show no difference users can perceive
- Gaps appear in sustained animation, heavy computation and real-time media
- Test on a mid-range Android, not a recent iPhone
- Prototype the single most demanding screen before committing
When cross-platform is the wrong choice
It is worth naming the cases where a shared codebase is a mistake, because agencies rarely volunteer them and the cost of finding out mid-project is high.
Skip it when performance is the product: games, real-time video or audio processing, augmented reality, anything rendering continuously. Skip it when the app depends on the newest platform capabilities, since framework support lags and you cannot ship on a promise. Skip it when the feature inventory shows extensive native work on both platforms, because you end up maintaining three codebases rather than one. Skip it when the two platforms need genuinely different products rather than the same product presented twice, which happens more often than expected with hardware-linked or enterprise tools.
There are non-technical reasons too. If you have an existing team fluent in one platform, building on their strength may beat retraining. If the app is a long-term core system with a long expected life, dependence on a framework maintained by someone else is a strategic consideration worth weighing. And if only one platform matters commercially, a single native app is simpler than a cross-platform build serving one target. None of this argues against cross-platform generally. It argues for choosing after looking at your specific product, which is the only way the question can be answered.
- Performance-defining products belong on native
- Dependence on brand-new platform features belongs on native
- Heavy native work on both sides removes the reason to share
- One team already fluent in one platform can outweigh the theory
- If only one platform matters commercially, do not build for two
Flutter and React Native: how the choice is actually made
Both are mature, widely used and capable of producing good apps. The decision is rarely about which is better in the abstract and almost always about fit with your product and your team.
Flutter draws its own interface rather than using the platform components, which gives very consistent results across devices and strong control over visuals and animation. The trade-off is that platform-native appearance and behaviour must be recreated rather than inherited, and the language is one your existing web team probably does not use. React Native uses the platform components and sits in the JavaScript ecosystem, which suits teams with React experience and can allow some sharing with a web product. The trade-off is that behaviour varies more across platforms and versions, and the dependency ecosystem needs more careful vetting.
The questions that decide it: does your team already work in React, does the product need a strongly branded consistent interface or a platform-native one, do you have a web application you would like to share logic with, and who will maintain this in two years. Hiring matters as much as technology here. A framework your future developers can be found for is worth more than a marginal technical advantage. Whichever is chosen, write down the reasoning, because the decision affects hiring and cost for years and the reasons should outlast the person who made it.
- Flutter: consistent controlled interface, strong animation, separate language
- React Native: platform components, React ecosystem, possible web sharing
- Existing team skills are a legitimate and often decisive factor
- Consider who you can hire in two years, not just who builds it now
- Record the reasoning so the choice can be reviewed later on its merits
Making a shared codebase feel right on both platforms
The most common criticism of cross-platform apps is that they feel like a website in a wrapper on at least one platform. That outcome comes from design and process decisions, not from the technology.
The root cause is usually designing once for one platform and shipping it to both. If the design was drawn against iOS conventions, Android users get an app that behaves subtly wrong in ways they notice without being able to name. The fix is to design one product with deliberate per-platform differences where users would notice: movement between screens and the back behaviour, control styles, typography, where primary actions sit, and system dialogs. That is a small proportion of the interface and it does most of the work of making an app feel like it belongs.
Beyond appearance, the details that give away a poor build are practical ones. Scroll behaviour that does not match the platform. Missing haptic feedback where a user expects it. Transitions that are slightly too slow. Text that does not respond to the system text size setting. Assuming a network connection is always present. Ignoring dark mode. None of these are hard, and all of them are noticed. Test on real devices of both kinds throughout, not just at the end, because these are the problems that a simulator hides and a user finds in the first ten minutes.
- Adopt each platform model for movement and back behaviour
- Use platform-appropriate controls, dialogs and typography
- Respect system settings: text size, dark mode, reduced motion
- Add haptics and transitions that match platform expectations
- Test on real devices of both kinds throughout the build
A clear path, step by step
- 01
Choose the framework
Flutter or React Native, decided by your product’s needs and your team’s future skills.
- 02
Design once, adapt twice
One design language with platform-specific touches where users would notice.
- 03
Build and test on devices
Short cycles, tested on real iPhones and Androids, not just simulators.
- 04
Launch both stores
Simultaneous submission, then one codebase to maintain and one place to add features.
Why choose us for this
We know where cross-platform breaks and design around it early
Native code added surgically when the framework hits a wall
Framework choice justified in writing, so you know why
Common questions
Flutter or React Native?
Both are mature. Flutter tends to give more consistent UI and strong performance; React Native suits teams with React experience and deep JavaScript ecosystems. Your product and future hiring plans decide it, and we recommend accordingly.
Will a cross-platform app feel cheap?
Not if it is built well. Major apps you use daily are cross-platform and you cannot tell. The compromises appear in heavy graphics and unusual hardware use, and if your product lives there, we will steer you native.
Explore related work
Want this for your business?
Book a free visibility call and I will tell you honestly whether I can help.
How this is delivered
One person leads every project. Where a job genuinely needs a specialist, I bring in people I have worked with before and manage them, so you get one point of contact and one invoice rather than three suppliers blaming each other.
- You talk to the person responsible for the work, not an account manager
- Specialists are briefed and managed by me, and their work is checked before it reaches you
- One contract, one invoice, one place to chase