All Articles

Rewritting two React Native apps in Flutter

flutter-wordpress-podcast

After using React Native (RN) for 5 years, I started to learn flutter at work for a new project and I quickly enjoy the Google framework. Besides that, two of my personal apps, Thinkerview and Cause Commune, written with RN became unmaintainable, both because I didn’t touch them for years and also because the code was awful as they were one of my first apps released to production. This article is comparing flutter and RN development in detail, while I also give more insight of the rewriting of Cause Commune and Thinkerview apps. These two apps are podcasts apps, fetching data from wordpress backend.

Philosophy of the project

Since these two outdated apps were no longer working, I started to think about rewriting them, but I realized that the main audio library for React Native, react native track player, was not poorly maintained and unstable, which was blocking me to use RN. This is unfortunately a common issue in the open source community, many libraries are made by developers on their spare time but so they lack of support on the long run as it’s only an unpaid side project.

Therefore, I decided to use flutter for these apps and choose a monorepo / white label app approach to make it easier to maintain in the long run. This was really easy to do for Android using flavors, but it required a lot of efforts to set up the project correctly on Xcode for iOS. It was worth it, the result is really nice. I’m now planning to build the app for macOS as well, and I wish I could help some help for Ubuntu and Windows builds.

Ecosystem and native world

Even if the JavaScript (JS) ecosystem is much bigger than what you can find for flutter, you can get everything you need on pub.dev for flutter. I found that for the native part regarding audio, the flutter was a winner as just_audio library was working perfectly, with good documentation and separation of concerns with audio_service. Creating the background audio feature for the Android lock screen and iOS control center wasn’t an easy task at all, but I make it work, creating two repositories (or services), one for the player and another for the audio background service. They talk to each other’s thanks to get_it, a package creating a singleton used across the app. On the old RN apps, I had the issue of creating different instances of the player, it was so confusing, so using dependency injection is exactly what I was looking for and make development easier. Fix is a strong point for flutter in my opinion as it was unclear/ not so easy to make the same in RN world.

The bad

What I really don’t like with flutter, it’s the underscore convention and styling. Renaming a file is much quicker with when using a dot because you can use the key option of your keyboard to easily move across words. As for the styling, I just prefer the RN approach, as you have separate files and everything is more concise, where in Flutter you have a styling directly in the widget/component making the file bigger and harder to read, with a lot of long Theme.of(context).... I also don’t like that you have to use a lot generated code with flutter, like for parsing json from api calls where it’s straight forward in js.

The good

However, if you want to be pixel perfect and don’t like the constraints of the native components, flutter is the best tool as you are actually drawing whatever you want, where in RN world you are using native elements. The only drawback is that you might lose the native feel and fall into what I call the “Dribbble effect trap”, which means that are the design team can go nuts and design beautiful things with a lot of animations and so on but are only cool to the eyes of the designers but make the user lost since he doesn’t recognize native/conventional components or is overwhelmed by the many animations, lose focus on app content.

Testing

For testing, RN is a winner even if flutter does the job correctly. Despite having testing out the box on Flutter, I found Jest easier to use, with more documentation and a ton of examples and Stack Overflow issues. But the real problem is that there is no good solution on flutter for UI regression. On RN you have snapshots, for flutter you have golden toolkit, but it’s not as good as having snapshots. For example, you might get different screenshots for the same widget if you are not using the same OS among developers. Besides that, good luck for finding the difference in a text color being #0c0c0c instead if #0d0d0d on the screenshots. In overall, snapshots are much better because you can see which line of code has changed and can still get screenshots with E2E testing tools like Wix detox.

For navigation, no discussion, RN is a clear winner thanks to the amazing React Navigation package which is much cleaner/easier to use compared to go_router, the flutter competitor or the “native” flutter navigation.

Extra notes

From a hybrid designer/developer perspective, to be forced to use material guidelines with ThemeData is a bit annoying because you have to respect naming material wording like bodyText1, primarySwatch… etc. but on the other hand you get the dark mode support out the box in return 👌

Regarding state management, I’ve used cubit but I won’t formulate an opinion as I don’t have a big experience with it, but for RN redux is a my favorite choice, especially the package redux-toolkit which is extremely powerful. However, I’m really happy that react left the setState world for hooks, helping to write consice code, which is not the case of flutter.

As Google remains Google doing Google stuff, I found that comparing flutter to RN was very similar as comparing angular with react. With angular, you have basically to use Google stuff all the time, while you can choose for yourself in react, giving you more flexibility and freedom. For example, you have to use ngFor while you would use vanilla js map with react, and the same applies to flutter you have to use material like ThemeData while you can set your own design system with RN. The drawback of using Google tools is that you get a bit “trapped” in its ecosystem/bubble imo.

Conclusion

Just like expo, I found that flutter is an excellent framework for startups and small projects. You get icons, navigation, theming… and a lot more out of the box without any effort, which is a big plus if you want to quickly release a first MVP. For bigger apps, flutter is also a very good choice as you can “cut” your app into different packages, with different teams working on a specific part of the app, something you can’t do with RN.

Discover the project

If you want to have a look to Flutter Wordpress Podcast app, here is the repo on Github.