Mobile development fundamentals: why native still matters
By Ann Tech · 4 March 2026
Native APIs are the foundation everything else builds on. Even when you ship Flutter, the platform beneath is Android or iOS — understanding what happens underneath makes you faster at debugging, better at platform integrations, and more confident about performance.
What "native" means
A native app is compiled for and run directly by the target OS. Android means Kotlin/Java on ART. iOS means Swift/Objective-C compiled to ARM machine code. Flutter compiles Dart to native ARM code and renders using its own Impeller engine, bypassing most platform UI widgets.
This means Flutter is native in the performance sense but not the UI-component sense. The gap matters when you need to integrate something the SDK doesn't wrap — biometric auth, camera viewfinders, NFC readers, or custom hardware sensors.
Platform channels: the bridge
const _channel = MethodChannel('com.example.app/nfc');
Future<String?> readNfcTag() async {
try {
return await _channel.invokeMethod<String>('readTag');
} on PlatformException catch (e) {
debugPrint('NFC error: ${e.message}');
return null;
}
}
// Android: MainActivity.kt
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example.app/nfc")
.setMethodCallHandler { call, result ->
when (call.method) {
"readTag" -> result.success(nfcManager.readTag())
else -> result.notImplemented()
}
}
Why native knowledge pays off
Debugging crash reports. When a Flutter app crashes inside an Android service, the stack trace is Kotlin/Java. When iOS rejects your app for background audio misuse, you need to understand AVAudioSession categories.
Permissions. Flutter packages that request permissions call into native code. When the permission dialog doesn't appear, or the rationale string is wrong, you need to read AndroidManifest.xml and Info.plist to diagnose why.
Build systems. Gradle on Android and Xcode on iOS are where signing, flavors, build variants, and dependency conflicts live. You cannot avoid them in any production Flutter app.
Performance. Flutter's raster thread runs on the GPU via Impeller. Understanding that heavy CustomPainter work runs on that thread — not the Dart isolate — explains why certain animations jank and how to fix them with RepaintBoundary.
Practical native skills to build
- Read an AndroidManifest.xml and understand every element
- Write a simple Kotlin BroadcastReceiver or Service
- Understand Info.plist keys and when each is required by iOS
- Read and symbolicate a crash report from Xcode Organizer
- Understand code signing, provisioning profiles, and Android keystores
Common pitfalls
Treating the platform as a black box. When something breaks at the native layer, developers who've never touched Kotlin or Swift spend hours guessing. Those who've written a few hundred lines each diagnose in minutes.
Relying on Flutter packages for every native feature. A package wrapping a native SDK is always one version behind and may not expose every API. Knowing native means you can write the method channel yourself when a package falls short or is abandoned.
Sign in to like, dislike, or report.