Shalitha Suranga Programmer | Author of Neutralino.js | Technical Writer

Flutter vs. Ionic for cross-platform development

12 min read 3597

Flutter Vs Ionic Cross Platform Development Featured Image

Modern mobile application development teams tend to use mobile app-specific frameworks to build their apps for several advantageous reasons: a single codebase for developing Android and iOS apps; developer-friendly tools; platform-independent, abstract native APIs; and community support.

There are two different mobile framework types: hybrid and native.

Hybrid mobile frameworks, like Ionic and Apache Cordova (formerly PhoneGap), let developers build hybrid mobile apps by loading web resources to a native webview component. On the other hand, native mobile frameworks like Flutter and Kivy let developers build native mobile apps by offering a platform-agnostic UI toolkit. Meanwhile, React Native offers different a way to build native apps with a headless-webview concept.

In this article, I will provide a detailed and practical comparison between Flutter and Ionic for selecting the best framework to build your next mobile app.

What is Flutter?

Flutter is a cross-platform software development kit developed by Google. The Flutter framework lets developers build apps in Dart, using a widgets-tree-based layout, and was initially a cross-platform mobile application development framework that produced application packages for Android and iOS. More recently, the Flutter team extended the framework by supporting desktop (Linux, macOS, Windows, and Fuchsia) and web targets.

Flutter doesn’t use web-based or platform-specific UI elements. It uses an inbuilt UI toolkit and renders graphics via the Skia cross-platform graphics library.

What is Ionic?

Ionic is a hybrid mobile application development framework developed by Max Lynch and Ben Sperry. Ionic was initially built on top of the Apache Cordova framework, but the Ionic team made Capacitor.js as a replacement for the Apache Cordova foundation layer.

Ionic doesn’t use native platform-specific UI elements. It uses native-like, web component-based UI elements and renders them in a webview component. Ionic lets developers build mobile apps with Angular, React, Vue.js, and Stencil frontend libraries.

Ionic officially supports Android, iOS, and web targets. The developer community also created Electron-based desktop app generation support.

Flutter vs. Ionic: Popularity and market share

Let’s look at the impressive usage statistics of Flutter and Ionic.

We made a custom demo for .
No really. Click here to check it out.

Framework
Usage statistics
Apps built with framework
Flutter
  • Statista developer survey’s Flutter votes increased from 30percent to 42 percent from 20192021
Ionic
  • The official Ionic website mentions that nearly 5 million developers built about 5 million apps with Ionic

Popularity and market share statistics typically give us a sense of developers’ awareness of the frameworks, the success of each framework’s marketing strategy, and developers’ satisfaction level with each specific framework. These statistics data won’t show us clear user-experience factors, performance factors, and features for technical decision-making in our projects. For example, the most popular framework might not solve your primary technical requirement.

For that, let’s move on to the next section, comparing each framework’s architecture and how it’s suited to different environments.

Flutter vs. Ionic: Internal framework architecture

Learning framework internals is undoubtedly the best technical decision-making activity you can do before selecting a framework for your next mobile app. A framework’s internal architecture gives us a clean, transparent overview of each framework product’s feasibility and future.

How Flutter works internally

Three Main Layers Of Flutter App
Flutter’s high-level architecture

Flutter has three main layers:

  1. Dart-based framework: implements all widgets, animations, and foundation building blocks that developers access frequently
  2. C++-based engine: connects the Dart-based framework layer with the embedder app layer, with the help of the Dart runtime and Dart-to-native communication channels
  3. Platform-specific embedder app (also known as the host app)

Flutter architecture is similar to the SDL graphics library that allows APIs to render platform-independent UI elements. Flutter uses a JavaScript-free binary protocol to call native operating-system-level APIs.

Summary

Remember the following important points about Flutter from the above technical review:

  • Flutter doesn’t use a webview or platform-specific UI toolkits (e.g., Cocoa and Android UI) — it renders widgets built by Flutter
  • Flutter calls OS-layer APIs with a binary messaging protocol
  • Flutter apps are universal and platform-independent
  • Flutter apps will run natively on any platform that can run a Flutter engine and Skia graphics because it promotes native GUI performance with a custom rendering canvas, like a game engine

How Ionic works internally

Three Main Layers of Ionic App
Ionic’s high-level architecture

The Ionic framework has three main layers:

  1. Web components-based widgets framework
  2. JavaScript-to-Native bridge
  3. The host application

Ionic’s widgets toolkit is written with the Stencil web components library. Stencil-based components can be easily ported to any frontend framework, and the Ionic team officially provides wrappers for React, Vue.js, and Angular. The JavaScript-to-Native bridge (also known as Capacitor.js) converts every native API call to a JSON message and sends it to the host application’s webview interface. The host app also can call the web app layer via the JavaScript bridge.

Ionic uses a React Native-like approach for talking to the operating system’s native SDKs with a JavaScript bridge.

Summary

Remember the following important points about Ionic from the above technical review:

  • Ionic uses a webview component to render HTML-based UI elements that we can create using our favorite web frontend frameworks
  • Ionic offers pre-built, native like web component-based widgets
  • Ionic communicates with the OS layer (host app) via JSON payloads (it uses base64 encoding for parameters)
  • A large portion of the entire framework core is written with web technologies, so the Ionic ecosystem goes toward web development culture — not the native development culture

Flutter vs. Ionic: Development workflow comparison

The development workflow is a crucial comparison factor — because it directly affects developer productivity.

Now that we know about each framework’s primary building blocks, let’s develop a simple app from each environmental setup and run it on a real mobile device to study the learning curve, developer tools, and developer environment.

Creating a Flutter application

If you’ve developed a Flutter application before, you can skip to the end of the Flutter tutorial section.

Flutter application development requires setting up two components: the Flutter CLI and the platform-specific SDK. The platform-specific SDK installation is required only for mobile platforms because most desktop platforms already include the required developer libraries by default.

Developer environment setup

First, install the Flutter CLI according to the official guide. If you are on Linux, you can use the following Snapcraft command (run with sudo) to install it quickly.

>snap install flutter --classic

Next, you have to set up mobile SDK tools. If you plan to test the app on an Android device, you can use the following command to install Android Studio.

snap install android-studio --classic

The Flutter CLI provides a helpful diagnostic command called doctor to find configuration issues. You can start creating a Flutter app if the flutter doctor command doesn’t show any critical errors, as shown below.

Flutter Doctor Command Output
The flutter doctor command output on Linux

Creating a new app

You can create a new Flutter app with the following command:

flutter create myapp

The above command will generate a minimal sample Flutter application very fast, since there are no external dependencies like Node.js modules.

You can run the application on an Android device with the following command:

cd myapp
flutter run

The above command creates a debug build of the Android embedder app with Flutter hot-reloading support and runs on the connected physical device or virtual device.

Sample Flutter App
A sample Flutter app runs on an Android device

Developing Flutter apps

You can browse the source code of the sample application from the lib/main.dart file. As you may have already noticed, Flutter comes with a widgets-tree-based layout system that other popular cross-platform mobile frameworks don’t use. The widgets-tree-based layout offers a friendly development environment for developers who have previously worked in native application development, but it’s a new and somewhat confusing concept for frontend and web developers.

Even though Dart is a new development technology for most developers, developers can still use the familiar, generic project architecture patterns to build large-scale apps. For example, we can structure our Flutter codebases with the repository pattern, MVC pattern, services, DAO pattern, and state management patterns, like BLoC, by also decomposing large UI into multiple widgets.

Releasing Flutter apps

The Flutter CLI offers the build command to produce application packages. Flutter generates ahead-of-time (AOT) compiled Dart code segments for faster application startup with production builds.

Let’s generate an APK of the example application. You can generate a fat APK for multiple CPU architectures with the following command:

flutter build apk --release

The above command generates a 15.8MB-sized, single APK. However, we can generate an APK for a specific CPU architecture with the following command:

flutter build apk --split-per-abi

The above command generates a 5.2MB-sized, CPU-dependent APK for my arm64-v8a Android device, along with two other APKs for different CPU architectures. Flutter offers this CLI feature to reduce the application package, since it uses Android NDK-generated, CPU-dependent dynamic libraries.

Summary

Remember the following points from the above practical review of the Flutter application development workflow:

  • The Flutter CLI offers features to create, run, debug, and build Flutter applications with a fully-featured diagnostic tool
  • We can’t use a traditional XML-like layout syntax with Flutter — it comes with a widgets-tree-based syntax
  • We can use any generic architectural pattern to structure Flutter codebases

Creating an Ionic application

If you’ve developed an Ionic application before, you can skip to the end of the Ionic tutorial section.

Ionic application development requires setting up three software components:

  1. Node.js with the package manager of your choice
  2. The Ionic CLI
  3. The platform-specific SDK

Developer environment setup

First, make sure that you already have the latest Node.js LTS version installed. Next, install the Ionic CLI program with the following command.

npm i -g @ionic/cli

The above command activates the ionic command globally; you can verify it by entering ionic on your terminal.

Entering Ionic On Your Terminal

Creating a new Ionic app

You can create a new Ionic app with the following command.

ionic start myapp

The above command displays a project creation wizard and asks you to choose a frontend library and app template. I selected React and the blank template for this example. Project creation takes some time compared to the Flutter CLI because we have to install the Node.js modules.

You can run the Ionic application on an Android device with the following command.

ionic capacitor run android
Creating A New Ionic App
A sample Ionic app runs on an Android device

The above command triggers a React production build and won’t enable the hot-reloading (HMR) feature. However, the Ionic CLI provides the following command to activate hot-reloading with the frontend framework developer tools:

ionic capacitor run android -l --host=<your_ip_address>

Note that you need to connect both your mobile device and your computer to the same network before executing this command. The Ionic documentation suggests previewing the application on the web browser with the ionic serve command before previewing with real devices or emulators.

Developing Ionic apps

Ionic renders web-based application UI via platform-specific webview components. Therefore, it lets you use the most popular frontend frameworks like React, Angular, and Vue to develop UI components.

Every popular frontend framework typically comes with XML-like templating syntax, which means frontend developers don’t need to learn a special layout syntax like Flutter’s widgets tree.

The Ionic framework and Capacitor.js consist of loosely-coupled framework components. Therefore, you can easily use only Capacitor and turn your existing web app or PWA into a hybrid mobile application without Ionic components. As in Flutter, you can use any architectural pattern you want to organize your code for large-scale applications.

Releasing Ionic apps

Ionic also has a build command, but it doesn’t directly generate release packages for Capacitor-based projects. The ionic build command packs web resources to the host app and opens the mobile development IDE for manually compiling mobile platform binaries.

For example, the following command updates the host app with web resources and opens Android Studio automatically.

ionic build

Android Studio generated a 3.6MB-sized APK with the Gradle release build configuration.

The Ionic team is planning to extend the CLI to generate release binaries, as Flutter does via this GitHub issue.

Summary

Remember the following points from the above practical review of the Ionic application development workflow.

  • The Ionic CLI offers features to create, run, and debug Ionic applications, but you have to use the standard mobile IDE to generate release binaries
  • Ionic uses web-based UI widgets, so frontend developers can easily learn Ionic development, but we can turn web apps into hybrid mobile apps with Capacitor.js
  • We can use any generic architectural pattern to structure Ionic codebases

Flutter vs. Ionic: User experience

Now that we have an idea of how each framework supports developers with tooling, let’s factor in UX. Developers create apps for end-users — so user experience factors also help mobile applications to become successful.

Flutter offers a native UI experience

Flutter doesn’t use UI elements from the operating system’s inbuilt libraries — it uses consistent native MUI elements on every platform—but you can apply the Cupertino UI theme on iOS to make iOS-like UI elements. Flutter UI’s main goal is to provide a consistent user experience across different operating systems.

Flutter renders widgets so efficiently, even on low-end devices,  due to the AOT compilation and high-performance Skia library.

Ionic offers a native-like UI experience

Ionic provides pre-built, native-like UI elements with the web components technology. Your hybrid Ionic app will render different CSS styles automatically on each platform to match the native UI style. For example, the Ionic button component will look like an Android button on Android devices, and look like an iOS button on Apple devices.

Ionic’s UI rendering performance depends on the platform’s specific webview HTML rendering performance. Users may sense the app is a web application if they run a complex HTML screen on low-end devices due to the slow HTML rendering and delay in web resource loading.

Flutter vs. Ionic: Performance and resources usage

Neither Flutter nor Ionic directly calls native platform SDKs. Instead, each framework runtime uses different approaches to communicate with native SDKs. Let’s discuss how the framework affects performance and resources usage.

Performance in Flutter

Flutter uses a binary messaging protocol called platform channels to communicate with native SDKs, so it offers near-native performance while dealing with platform APIs. The AOT-compiled binary also removes Dart code parsing and compilation steps for production apps decreasing the TTI (Time-To-Interactive) factor drastically.

Performance in Ionic

Ionic uses a JavaScript bridge concept for communicating with platform SDKs like React Native. React Native’s new architecture implementation replaced the bridge component with the new JSI communication concept because of the bridge’s performance drawbacks.

We have to think twice if we choose Ionic to write a mobile app that often calls native SDKs. However, these performance drawbacks of the Ionic framework only happen with low-end or embedded devices because modern mobile devices typically come with powerful hardware.

The bundle size usually depends on application resources regardless of the framework in most cases. However, Ionic offers the lightest framework binary, since it just uses a native splash screen and webview component in the host app. By comparison, Flutter’s framework binary is somewhat larger, due to the platform-dependent Flutter engine libraries.

Flutter vs. Ionic: Desktop application generation support

Flutter desktop

Flutter officially supports Linux, macOS, Windows, and Fuchsia desktop platforms. Therefore, you can turn your Flutter app into a desktop app without third-party tools or frameworks. Try it out and see how easy it is to run the above sample Flutter application as a native desktop app.

We need to enable desktop support and enter flutter run to open the desktop app.

flutter config --enable-linux-desktop
flutter create --platforms=linux .
flutter run -d linux

The above commands build and run the Flutter app as a native GTK-windowed application, as shown below.

Home Page Of Flutter Demo
A sample Flutter app runs as a native desktop app on Linux.

Ionic desktop

Ionic doesn’t officially support desktop platforms, but the Ionic community created a project to turn Ionic apps into hybrid desktop apps with the Electron framework. This desktop app-generation workflow is also as easy as Flutter’s desktop app-generation support.

You can run your Ionic app as a hybrid desktop with the following commands. These commands will work faster than the Flutter desktop app execution commands because Electron typically comes with pre-built binaries.

npm i @capacitor-community/electron
npx cap add @capacitor-community/electron
npx cap open @capacitor-community/electron

The above commands open the Ionic app as an Electron desktop app, as shown below.

Desktop Of Ionic App
A sample Ionic app runs as a hybrid desktop app on Linux.

Flutter vs. Ionic: Web application generation support

You don’t need to put in any extra effort to convert Ionic apps to web apps, since Ionic apps are already web apps. For example, if you use React to build your Ionic app, you can trigger a production build and obtain a deployable web app. Ionic components will work on any web browser without any performance issue because they are HTML elements.

Flutter also supports web application generation via two different renderers: HTML renderer and CanvasKit. The HTML renderer renders the Flutter app on a browser with a mixture of HTML elements and canvas elements. It has a smaller download size than the CanvasKit.

The CanvasKit renderer tries to offer a native-like performance on the browser, but has a somewhat large download size. However, both web renderers use canvas elements instead of native HTML elements.

Flutter vs. Ionic: Which framework is better?

We’ve discussed framework internals, development workflows, desktop support, web support, user experience, and the performance of both frameworks. Now, we can summarize all comparison data into one table for studying the pros and cons.

But first, you need to understand that no mobile framework will produce technically great apps as native apps  —  we use frameworks mainly to reduce development time.

Flutter and Ionic both offer impressive features, but also come with several drawbacks, so we need to carefully pick a framework based on our project’s primary requirements.

Look at the summarized pros and cons of Flutter and Ionic.

Framework
Pros
Cons
Flutter
  • Offers a consistent, platform-independent native UI toolkit for mobile, desktop, web, and embedded platforms
  • Provides near-native performance with the binary messaging protocol and AOT compilation
  • Official support and tooling for desktop platforms: Linux, macOS, Windows, and Fuchsia
  • Plugins ecosystem is not large, butstill growing with community support
  • Developer APIs and layout system is not beginner-friendly
  • Web application generation uses HTML Canvas API, so  content-driven web apps may face SEO issues
Ionic
  • Offers native-like, pre-built UI elements with the web components technology
  • Web developers can easily start Ionic development with their preferred frontend framework
  • Official Capacitor.js plugins offer abeginner-friendly JavaScript API to access general native SDK needs, like the camera, local notifications, message boxes, and preferences
  • Large-scale Ionic apps may perform slowly on low-end devices due to the webview resource loading/parsing bottleneck and performance issues in the JavaScript bridge
  • Developer tooling requires further improvements to boost developer productivity i.e., a command to generate release packages
  • Remote web resources increase XSS vulnerabilities risk of the mobile application

Flutter vs. Ionic: Use cases

We can decide when to use Flutter and Ionic based on the above pros and cons. Carefully choose the most suitable framework based on your requirements , rather than just considering the current trends.

Use Flutter if:

  • Your primary product is a somewhat complex mobile app
  • You care about both performance and beautiful UI at the same time
  • Your application end-users wish to use your app from low-end mobile devices, embedded devices, and/or desktop devices
  • Your engineers (or you) would like to work with a new language (or you can adjust your budget to hire new Dart engineers)

Use Ionic if:

  • Your primary product is a less-complex mobile app
  • You need to convert a web app to a hybrid mobile app
  • Performance is somewhat less important compared to a beautiful UI
  • Your engineers (or you) wouldn’t like to switch from the web development environment to native application development environment by changing tech stacks

Conclusion

In this article, we compared Flutter and Ionic frameworks from various perspectives. Frameworks are changing rapidly, so a specific framework can introduce a feature at any time to make the particular development workflow even more productive.

The underlying architecture says a lot more about a framework’s feasibility and stability than the way in which a specific framework product is advertised to the developers. That’s why we discussed the internals of each framework before proceeding with the evaluation.

Both Flutter and Ionic are good mobile frameworks and loved by millions, but Flutter undoubtedly wins from the performance perspective, while Ionic is recognized as the most productive tool for web developers to build hybrid mobile apps.

Choose a framework by carefully studying your requirements  —  there is no easy way to switch from Ionic to Flutter or Flutter to Ionic, rather than rewriting the entire app.

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page and mobile apps.

.
Shalitha Suranga Programmer | Author of Neutralino.js | Technical Writer

3 Replies to “Flutter vs. Ionic for cross-platform development”

  1. Thanks for the balanced review. I’m one of the founders of Ionic and there’s one other critical aspect that people often overlook: commercial features and support. Ionic is a business and sells a variety of powerful cloud services, fully supported native solutions, and cloud services that are all built to pair perfectly with Ionic.

    This is a really important aspect that many people skip over. Google does not offer any kind of enterprise support for Flutter, nor does it support any integrations for services like Microsoft Authentication (MSAL), Intune, encryption/biometric support, etc. You can’t call Google for support if you’re building a mission-critical app, and there’s no guarantee of any kind of long term maintenance on Flutter components.

    This is fine if you’re an indie, but could be a big deal if you’re an enterprise putting a lot of money into your app.

  2. Hey just a heads up, Nationwide’s app is listed here as being an Ionic app, but the Nationwide app is actually built on Flutter.

Leave a Reply