Releasing Your Flutter App to the App Stores
This month, Bob wraps up his article series on mobile app development from the perspective of an embedded systems designer. He looks at what it takes to release your Flutter app to the Apple and Google app stores, and then gives a high-level, opinionated, overview of the two paradigms—Flutter and React Native.

As I have discussed in previous articles in this series, I developed my React Native app using Expo. I found it easy to use with very few downsides. There were the normal quirks that we get from all software (I can’t believe I just said that!), with things not always working the same and the constant changes made underneath us that are maddening. But software developers like us have conditioned the public to expect that. It gives us a “get out of jail free” card for our lack of planning, design, and testing.
Expo provided Expo Application Services (EAS), which supplies services to simplify all aspects of alpha, beta, and production releases. I expected there to be something similar for Flutter for releasing the app to the app stores. Instead, I found a documentation page [1] that tells you how to release for Apple’s App Store and Google’s Play Store. This documentation includes all kinds of esoteric files that I never had to deal while releasing with EAS. And the procedures between the two platforms are very different (Figure 1).
When I complained to a friend, a long time Flutter developer, he recommended that I look into CodeMagic [2] (Figure 2) When I created my account with them, they said that with CodeMagic you could automate the most time-consuming app release steps, such as code signing, building and uploading new app versions, and setting changelogs.
All of this is not time-consuming with EAS, so clearly the free market has filled the need already for something the Flutter ecosystem doesn’t provide. Of course, when I tried CodeMagic for the first time, it hung up; and the webpage where it was hung said, “Click here to try again,” if it hung up.
I didn’t even complain. I just clicked there. And now it hung up in a different state! The next time, through, it seemed to work. See what I mean about how we have trained the public?
Of course, CodeMagic comes at a cost, but “time-consuming” steps scared me away. And the cost for a personal account is not prohibitive. What do they say—“Time is money?” As of 2025, the cost is $50 per year. Plus there is a free level. It was definitely better than what Flutter provided, but a far cry from Expo EAS.
PRELIMINARY PLANNING
Before you release your app to the app stores, you need to make some decisions. Do you need to prevent others from reverse-engineering your code? What do you want to use as an icon for your app? Do you have a developer account with both Google and Apple? Is the app a free or a purchased app? In what countries do I want to distribute my app? Am I going to monetize the app? Will I record user data (even username and password)? Am I using encryption techniques that cannot be exported? You will need answers to these kinds of questions when you register with Google or Apple.
OBFUSCATION
I remember when I first heard the word “obfuscate” and I thought it was a joke. Basically it is a big word for “hide.” Reverse-engineering tools have come a long way since I first tried to reverse engineer some of the code in “Where in the World is Carmen Sandiego?” (Shhh! It did violate the license agreement!) There are tools out there on GitHub that will take you a long way toward reverse engineering Dart/Flutter code.
Flutter provides a way to obfuscate the code, but I don’t see how it would significantly slow down a serious team bent on reverse engineering your code. However, it will make their job harder by making all variable names, class names, and function names generic. If this is important to you, you need only add the “—obfuscate” switch to the “Flutter build” command. But some obfuscated code may actually fail. Buyer beware.
A better way to slow them down might be to incorporate some native code in your mix (Java or Kotlin for Android, or Swift or Objective-C for iOs).
FLAVORS
I created a React Native app that is used in several different environments. Let me mention three. All of them use all of same source code.
The first flavor is called the Sermon Engagement app. Each week someone from the church takes the sermon and the sermon’s slides, and creates from one to 10 engagements. They take a particular point from the sermon, and summarize it and provide questions to probe deeper into what was said. Some slides are included to help reinforce the message. References to links are provided to material that was either handed out or referenced. All of the weekly data is stored in the Cloud.
A second flavor is used by a book author to promote his book [3]. The book has more than 70 paths or exercises intended to help us grow in humility. This flavor includes a dozen or so of the exercises, and then includes a link to buy the book.
A third flavor was a Christmas present I made for my grandson who got his pilot’s license. I took a book about flying (whose copyright had expired) and made it into a book he could both read—with pictures and maps from the book and elsewhere—and listen to his grandpa and grandma read.
Flutter provides a similar feature [4]. Whereas with React Native and Expo, a single method is used for creating flavors, Flutter requires separate procedures for Android and iOS. This is a somewhat annoying trait of the Flutter ecosystem that frankly is just frustrating and time consuming. Every developer must wade through the different approaches of Android and iOS, rather than a single developer creating a wrapper that handles both.
RELEASING TO THE APP STORES
Once the preliminaries are out of the way, Flutter documentation provides you with a detailed, step-by-step procedure for releasing to Android [5] and to iOS [6]. Again, keep in mind “time consuming,” and that it will require you to dip into confusing details about Android and iOS that I didn’t need to know with Expo EAS. With EAS, I released to both app stores in hours. With Flutter, it took me days.
A BRIEF SUBJECTIVE COMPARISON
As I wrap up this series, I am going to provide a subjective comparison of the two ecosystems—React Native with Expo using JavaScript, and Flutter using Dart. I have read a lot of the comparisons on the Web, and they all say pretty much the same thing. But it is not clear that the authors have actually developed using both. I am not going to give facts and figures about app size, or speed of execution, or time to load, or maturity of the tools and widgets. What I will provide is my gut reaction after fully developing and releasing an app that runs on Android and iOS with both React Native and Flutter.
Programming Language: JavaScript vs. Dart: In my very first article in this series [7], I mentioned that I chose React Native over Flutter because of Dart. I did not want to learn a new language. I already “knew” JavaScript and didn’t like it but I still was familiar with it and its many libraries. Had I looked into Dart, I would have seen that it combined features of languages I already knew (C and JavaScript), so this should not have been a big deciding factor. Overall, I like Dart. Its strong typing can be maddening, but I don’t hold it against that, because I know it is good for me—for the most part.
Score: JavaScript 3, Dart 7
Ease Of Development: Expo vs. Bare Metal Flutter: For my React Native app, I used Expo (called “Managed Workflow”), rather than what they called “Bare Metal” using the React Native Command Line Interface (CLI). For Flutter, there were no other options such as Expo. I had zero downsides using Expo. But designing and coding my app in Flutter took much longer and was much more work, primarily because it was more like Bare Metal React Native.
For testing and debugging, the idea of having a separate app (Expo Go) on your phone made connecting the development tools much simpler either with Wi-Fi or USB. Every time I went away for a day from a Flutter debug session and then came back, it was an adventure to connect my phone over Wi-Fi or USB. Of course, the gigantic drawback for Flutter is that I had to have a Mac to debug and test an iOS Flutter app. My Linux or Windows development machines won’t do it. Yuck.
Score: Expo 8, Flutter 4
Ease of Release Deployment: If you are not a Mac person, Flutter has a huge downside. You must have Xcode to do a release. For a Windows/Linux user, the Mac is just not intuitive, no matter what people say. I have had a much harder time navigating my Mac than I did when I first used Linux or OS/2. I was glad to get a confirmation of this from my granddaughter the other day. She is not any kind of a computer geek and has had an iPhone since her teens. But when she switched jobs at her workplace and was issued a MacBook instead of a Windows laptop (different IT departments!), she echoed the same concerns I had.
Simple tasks become major efforts until you figure out the quirks of the user interface. Start with X’ing out a window. The stoplight analogy is just not intuitive! It’s not that Windows or Linux are intuitive, but we know the quirks!
So, because of its requirements to have a Mac for release, and that Flutter has two completely different procedures for releasing to the Play Store and the App Store, the Expo score is much higher.
Score: Expo 9, Flutter 2
Splash Screen: Expo made creating a splash screen a breeze by being built into the ecosystem. Flutter required a very buggy plug-in to have a single path to a splash screen, without having to plunge into the depths of the archaic iOS and Android methods of this required feature. A generic splash screen is shown in Figure 3.
Score: Expo 9, Flutter 5
Code Stability: I had code stability problems with both ecosystems. The code underneath was frequently changing. Going from one version of the SDK to the next created time consuming problems with both. Once, when I went from Expo SDK version 49 to SDK version 50, I got errors in my build. I spent the better part of a day trying to find the cause. Then I updated to SDK version 51, and all problems magically went away.
Take a look at Figure 4. Do things stay centered with a small perturbation (Stability a)? Or do things move a little with a small change (Stability b)? Or do things go flying if the wind picks up just a little (Stability c)?
Score: Expo 4, Flutter 4
(both are between stability types b and c)
Flutter Widgets vs. React Native Components: This comparison comes down to the difference between Components (React Native) and Widgets (Flutter). I found that the Flutter widgets were more intuitive to create object-oriented designs with inheritance. In other words, creating a base class or Widget, and then building more complex widgets inheriting the children’s attributes is easier. My mind easily adapted my C++ experience with the Flutter paradigm. After a time, I found myself in design thinking about widgets. That did not happen with React Native and components. Overall, I found I was starting to think Flutter and Dart. This did not happen with React Native.
Score: Flutter 7, React Native 4
Stable Libraries/Packages: Here is my non-qualitative comparison. It doesn’t matter who has more widgets or components. What matters is: Do they work? Are they easy to install and use? Is the documentation sufficient. Here I rate both as a 10. Tons of widgets and components to choose from.
Asynchronous Programming: This was covered for each ecosystem in my April 2024 [7] and December 2024 [8] articles, but the bottom line is that the Dart Future is better than the React Native JavaScript Promise. The tools to handle asynchronous programming seem to be more deterministic and robust in Flutter. Plus I still have an unsolved asynchronous bug in my React Native code that does not exist in my Flutter code. That said, it seems as if the Flutter paradigm has too many options, which adds to our learning curve.
Score: Flutter 6, React Native 4
State Management: The ecosystem for each state management solution was covered in my October 2024 [9] and April 2025 [10] articles in Circuit Cellar. The presence of many more third-party, state management solutions in Flutter indicates the clear winner here. React Native’s solution is less powerful but simpler and more robust. They both could use work, however.
Score: Flutter 2, React Native 5
COMPARISON SUMMARY
My ratings of the various aspects of Flutter and React Native are given in Table 1, using a scale of 1 (poor) to 10 (excellent).

My ratings of various aspects of React Native/Expo and Flutter, on a scale of 1 (poor) to 10 (excellent).
The purist in me likes Flutter and Dart, with which you can create some elegant designs. I am not talking about the elegance of the user interface, but rather, of the underlying code structure. The code is neat and clean. The design can be made stable and reusable. But the release and development tools for Flutter are so painful, that knowing what I know now, I would still choose React Native with Expo over Flutter. The development time was much quicker even if the code was not as elegant.
CONCLUSION
Releasing your mobile app to the app stores is much harder with Flutter than it was with React Native and Expo EAS. I suspect that this is a maturity issue with Flutter and I would expect it to become easier within the decade. For my entire career, I always wanted to do two complete projects with completely different paradigms to compare them. Acomparative analysis broadens our technical skills and enhances our understanding of the strengths and weaknesses inherent in each framework. This was never possible as for-profit developers. But as a retired embedded engineer, it was a fun and mind-expanding exercise. We learn a lot when we see in depth two totally different approaches to the same problem. Even when you are doing it in thin slices.
RESOURCES
CodeMagic | www.codemagic.io
Expo | www.expo.dev
Flutter | www.flutter.dev
React Native | www.reactnative.dev
REFERENCES
[1] https://docs.flutter.dev/deployment
[2] https://codemagic.io/start/ Getting started with CodeMagic
[3] https://www.amazon.com/Its-Not-All-About-You/dp/B0BW2NLPKS/ref=tmm_pap_swatch_0 It’s Not All About You!: The Secret Joy of Practical Humility
[4] https://docs.flutter.dev/deployment/flavors The starting documentation for Flavors
[5] https://docs.flutter.dev/deployment/android This procedure can be performed from Linux, Windows or a Mac.
[6] https://docs.flutter.dev/deployment/ios This procedure can only be performed on a Mac.
[7] Bob Japenga. “An Embedded Designer Looks at Mobile App Development.” Circuit Cellar #405, April, 2024.
[8] Bob Japenga, “Easing the Path for App Releases: Managed Development of React Native with Expo.” Circuit Cellar #413, December, 2024.
[9] Bob Japenga, “React Native Hooks: The Closest Thing to System Calls.” Circuit Cellar #411, October, 2024.
[10] Bob Japenga, “Introduction to Flutter State Management.” Circuit Cellar #417, April, 2025
— ADVERTISMENT—
—Advertise Here—
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • JUNE 2025 #419 – Get a PDF of the issue
Sponsor this ArticleBob Japenga has been designing embedded systems since 1973. From 1988 - 2020, Bob led a small engineering firm specializing in creating a variety of real-time embedded systems. Bob has been awarded 11 patents in many areas of embedded systems and motion control. Now retired, he enjoys building electronic projects with his grandchildren. You can reach him at
Bob@ListeningToGod.org





