Native app development uses a platform’s own tools and APIs; cross-platform development shares parts of an application across platforms. Compare 4 requirements before choosing: device capabilities, interface behaviour, existing code and ongoing maintenance. Neither approach removes the need to test on the target devices. The useful choice depends on the app’s hardest real workflow, not a universal claim that one framework is best.
An Android-only application with deep device integration presents a different decision from a service intended for both Android and iOS. Start by describing the platforms and capabilities required. Keep a possible future platform separate from a committed requirement, so that the architecture is not justified by an expansion nobody has approved.
What is the difference between native and cross-platform work?
Android’s Kotlin-first guidance recommends Kotlin for a new Android app while maintaining support for Java APIs. Flutter’s platform-channel documentation describes connecting Dart code to platform-specific implementations. React Native’s platform-specific code guide explains ways to organise differences between platforms. These sources describe development approaches; they do not prove the delivery effort for your project.
| Approach | What can be shared or specialised | Important evaluation question |
|---|---|---|
| Native Android | Android implementation using its platform tools and APIs | Does an Android-only scope match the actual users and device requirements? |
| Flutter | Shared Dart application with platform-specific integration where needed | Which required capabilities need plugins or native channel code? |
| React Native | Shared application code with explicit platform-specific branches or files | Which screens and integrations need separate behaviour? |
This is a decision comparison, not a performance ranking. A simple demonstration in any framework may conceal the difficult integration. Ask for a representative test involving the actual device feature, authentication path or offline state rather than choosing solely from a generic sample screen.
Shared code is not the same as identical behaviour. Platform navigation conventions, permissions and hardware features may differ. React Native explicitly documents organising platform differences; Flutter provides a route to native functionality. The existence of these mechanisms is useful, but someone still needs to write, test and maintain the relevant integration.
Which requirements should drive the choice?
List capabilities in terms of user tasks. “Use the camera” is less precise than “capture an image, recover from denied permission and resume after the app returns from the background”. The second description identifies states a team can demonstrate. Apply the same discipline to notifications, location, document selection and external device connections.
Identify what must work without a network connection. An offline screen is not enough if the task also requires saving changes, showing their status and resolving a later conflict. State which actions can proceed, which must wait and how the user will know. This is a product requirement to implement, not a feature automatically supplied by choosing a framework.
Consider existing code and team knowledge. A substantial Android codebase may change the decision compared with a new application. A shared-code approach can also introduce platform-specific work when a dependency does not cover the required capability. Ask who can diagnose the complete application, including any native components, when a problem occurs.
Define the supported devices and operating-system versions with the implementation team. Do not invent a universal support window. Device resources, accessibility needs and an installed platform’s behaviour can influence the design. Test the proposed scope against actual users and the requirements of the stores or distribution method involved.
How can you evaluate the hardest workflow?
Use this original capability evidence sheet before committing to an architecture. Its purpose is to expose uncertain integrations early.
| Capability | Demonstration to request | Evidence of a gap |
|---|---|---|
| Device permission | Deny access, then allow it through the supported route | The user cannot recover without reinstalling |
| Local state | Interrupt the task and return later | Entered information disappears without explanation |
| Network failure | Lose connectivity during the intended operation | The app reports success without a completed action |
| Platform difference | Run the same task on each supported platform | An essential control or result is missing |
| External integration | Use the actual supported service or device interface | The prototype substitutes an unrelated mock |
| Accessibility | Navigate and understand the task with relevant assistive tools | Labels, focus or feedback prevent completion |
| Maintenance | Locate the code and dependency responsible for the feature | Nobody owns the platform-specific component |
These are acceptance requirements, not claims that every failure is present in every framework. Use non-sensitive test data and state which parts of the demonstration are mocked. A mock can be useful for design, but should not be presented as evidence that the production integration has been solved.
Choose a small proof of the uncertain capability. If the main risk is an external device connection, another week spent refining a login screen will not resolve it. Ask the team to document the integration route, relevant dependency and remaining unknowns. Keep the result attached to the exact versions and platforms tested.
What should the maintenance plan cover?
Record which parts are shared and which are platform-specific. Flutter’s channel mechanism and React Native’s platform-specific organisation both make it possible for an app to contain more than one kind of implementation work. The handover should identify those boundaries clearly enough that a later developer can find them.
Include dependency updates, operating-system changes and release responsibilities in the project plan. A shared codebase still needs platform testing and distribution work. A native codebase still needs application-level testing and operational ownership. Avoid promising a fixed maintenance advantage before the actual integrations and supported platforms are known.
Keep signing, account ownership and access recovery under the business’s control. These are separate concerns from language choice. A technically sound app can become difficult to update if its store account or release material belongs only to an individual who is no longer involved.
Document why the approach was chosen and what evidence would justify revisiting it. That decision record is more useful than a slogan about development speed. It helps later teams distinguish a deliberate trade-off from an accidental limitation.
See web development for related application requirements. To discuss an app, get started with the target platforms, hardest device workflow and existing code that must be retained.
By Spout Team. AI-assisted drafting by Codex using the linked primary sources.