Build the mental model
A cross-platform app is built with a single framework designed to target both Android and iOS from one primary codebase. Flutter and React Native are the two examples this site teaches in depth.
Continue for hands-on depth
For hands-on widget and component syntax, continue to the Flutter or React Native tutorials on this site.
The mental model here is simpler than either course's details: Shared Application Code sits at the center, and a build step for each platform turns that shared code into an Android app and an iOS app.
The part beginners misunderstand most often is assuming "cross-platform" means one hundred percent identical code for both targets. It rarely does.
Almost every real cross-platform project still keeps a smaller layer of platform-specific code alongside the shared core -- to reach a platform-only API, match a permission flow, or work around a bug that only shows up on one OS. Flutter calls this pattern platform channels; React Native calls it native modules.
Either way, the shared portion is usually large, often eighty to ninety-five percent of the codebase, but it is a majority, not an absolute. Cross-platform trades some of native's performance ceiling for a large win in development speed: one team, mostly one codebase, two apps shipped from it.
- Cross-Platform App
- An app built from one primary, shared codebase using a framework like Flutter or React Native, which compiles or runs on both Android and iOS -- usually with a smaller layer of platform-specific code alongside the shared core.
CROSS-PLATFORM: SHARED CODE, TWO OUTPUTS
----------------------------------------
SHARED APPLICATION CODE (most of the app)
|
|-- branches to --> ANDROID BUILD
| (+ small Android-specific code)
|
`-- branches to --> IOS BUILD
(+ small iOS-specific code)Connect it to a real scenario
When you evaluate or plan a cross-platform project, do not just ask "what percentage is shared." Ask where the platform-specific slice actually lives, because that tells you what kind of work it will demand from your team later.
A small platform-specific slice handling push-notification registration or a payment SDK is routine and expected. A platform-specific slice that keeps growing to work around missing framework features is a warning sign that the framework may not fit this particular app well.
Watch the trend, not just the number
Track your shared-versus-platform-specific split every few months, not just at kickoff. A codebase where the platform-specific layer keeps expanding release after release is quietly drifting back toward two separate native apps -- at which point native development may be the more honest choice.
Try the working example
function evaluateCodeSharing(codebase) {
const { platformSpecificPercent, targetSharedPercent = 80 } = codebase;
const sharedPercent = 100 - platformSpecificPercent;
const meetsGoal = sharedPercent >= targetSharedPercent;
let tier = "mostly platform-specific";
if (sharedPercent >= 95) {
tier = "nearly fully shared";
} else if (sharedPercent >= 80) {
tier = "highly shared";
} else if (sharedPercent >= 60) {
tier = "moderately shared";
}
return {
sharedPercent,
tier,
meetsGoal,
note: meetsGoal
? `At ${sharedPercent}% shared, this codebase meets its ${targetSharedPercent}% sharing goal.`
: `At ${sharedPercent}% shared, this codebase falls short of its ${targetSharedPercent}% sharing goal -- worth investigating why the platform-specific layer is that large.`,
};
}
const typicalFlutterApp = evaluateCodeSharing({
platformSpecificPercent: 10,
targetSharedPercent: 80,
});
const strugglingProject = evaluateCodeSharing({
platformSpecificPercent: 35,
targetSharedPercent: 80,
});
const strictGoalProject = evaluateCodeSharing({
platformSpecificPercent: 12,
targetSharedPercent: 90,
});
console.log(`Typical Flutter-style app: ${typicalFlutterApp.sharedPercent}% shared (${typicalFlutterApp.tier}), meetsGoal=${typicalFlutterApp.meetsGoal}`);
console.log(`Struggling project: ${strugglingProject.sharedPercent}% shared (${strugglingProject.tier}), meetsGoal=${strugglingProject.meetsGoal}`);
console.log(`Project with a stricter 90% goal: ${strictGoalProject.sharedPercent}% shared (${strictGoalProject.tier}), meetsGoal=${strictGoalProject.meetsGoal}`);Typical Flutter-style app: 90% shared (highly shared), meetsGoal=true
Struggling project: 65% shared (moderately shared), meetsGoal=false
Project with a stricter 90% goal: 88% shared (highly shared), meetsGoal=false5-minute try-it
Run evaluateCodeSharing with your own project's real platform-specific percentage. Then try raising targetSharedPercent to 95 and see whether your project would still meet that stricter bar.
One important caution
Assuming "cross-platform" guarantees zero platform-specific code -- most real projects still keep a meaningful platform-specific layer.
Treating a growing platform-specific layer as normal drift instead of a signal worth investigating.
Wikipedia: Cross-platform software — How Mobile Apps Work