App compilation process in Flutter for Android and iOS apps
Each Flutter project goes through a compilation process to generate the APK/Bundle file for Android and IPA file for iOS. These installable files contain the compiled version of following items:
- Dart source code
- Flutter Engine (C/C++ source code)
- Platform-specific native source code (Swift or Kotlin/Java source code)
- Assets (icons, fonts and other files)
Dart source code
Every Flutter app has dart code for two reasons:
- First is the app-specific dart source code written by developers containing the business logic, repository classes, specific widgets and so on. Like: LoginScreen.dart, ProductCart.dart etc.
- The second is the Flutter Framework APIs so that developers could write the first kind of source code like: FilledButton, Stack etc.
Flutter Engine
Flutter apps have to be shipped with Flutter Engine. The Flutter Engine mainly provides an app the rendering capabilities for drawing widgets via SKIA (or Impeller) graphic engine and ability to interact with platform specific features like: device Camera, file system etc.
Since this Flutter Engine is written in C/C++ so this also needs to be compiled before integrating it into the executables for the Android and iOS platforms.
Platform-specific native source code
Whenever a Flutter app needs access to any of the platform specific resource, the Flutter app developers need to write a plugin in the native platform specific language (Kotlin or Swift) with the support of Platform-Channel feature.
Assets
Flutter project contains assets like: icons, images and fonts to be rendered on the widgets.
Now, let’s understand the compilation process for these in Flutter:
Compilation process for Android in Flutter
In case of Android, the Dart code written by developer and the Flutter Framework’s Dart libraries get compiled to the x86 or ARM specific library which device CPU architecture could understand.
Flutter does this job using the AOT (Ahead of Time) compiler for the Release builds.
Each Flutter app has to be shipped with Flutter Engine. This Flutter Engine written in C/C++ gets compiled to the X86 or ARM libraries using the Android’s NDK (native development kit) SDK.
In the APK, all of the Flutter Framework related compiled Dart source code exists in the FlutterLib.so file, while the app specific compiled Dart source code exists in the AppLib.so file.
If the app uses Android specific native code written in Java/Kotlin to access platform-related features then this code gets compiled and added to the APK/Bundle file as per the Android app compilation process.
All of the project specific assets add by user like: images, fonts are added in the assets/flutter_assets folder. If the Flutter project contains multiple packages then you can find assets of each individual package at the assets/flutter_assets/packages/<package name> path of APK.
Compilation process for iOS in Flutter
In case of iOS, the Dart code written by developer and the code of Flutter framework’s Dart libraries gets compiled to the ARM64 binary code by Ahead of Time (AOT) compiler in case of Release builds.
The IPA file contains the Flutter Engine too. The Flutter Engine’s C/C++ source code first gets compiled to the ARM64 code libraries by LLVM (Low Level Virtual Machine) and then gets added to the IPA file.
The compiled Dart code of app exists in the App.framework folder of IPA, while the Flutter Engine exists in the Flutter.framework folder of IPA. Also, for all third party packages you can find <package name>.framework folder for compiled source code of related package.
The native source code written in Objective-C/Swift to access platform-specific features gets compiled and added to the IPA file as per the iOS app compilation process.
All of the project specific assets added by user like: images, icons and fonts are also bundled into the IPA file’s Framework/App.framework/flutter_assets path.
This blog focuses on the compilation & build process for the APK and IPA file of Release mode only. Notably, Debug mode builds in the Flutter platform uses the JIT (Just in Time) compiler instead of AOT compiler and the source code gets compiled at run time on the device as and when user uses the app features. This is why they’re slow and not a good candidate for testing app performance.
Also, the Debug mode builds contain some extra Flutter tools as well to support the debugging and hot reload features.
Thank you! If you like this post don’t forget to clap.