First things first: I am neither a software engineer nor a computer scientist. My academic background is in social so-called sciences, and the closest I ever got to actual coding was with R (coding? come on!) and Python – if you, like me, do not consider HTML and CSS worth mentioning, and as my attempts to learn Java, PHP, C#, and C++ ended in big failure. Hence, I should warn you, dear reader, I probably (if you ask me, most certainly) is not the right person to ask if YOU should learn or use Flutter – but as this is my blog, and as I am allowed to write about whatever I like, here I am.
The main takeaway of this post is this: Don’t lose time researching if you should do React Native or Flutter. They both allow you to build almost whatever you want as long as you don’t try to fly a plane or rely (heavily?) on native stuff like bluetooth, sensors, or such. I love Flutter because:
- It is simple, lot simpler than JS.
- Hot reload is a huge win. And
- It works miraculously with VS Code.
Am but a beginner, and will remain so for a long time to come, until my fifties. And as I said, millions of people know A LOT better than I and maybe am very, very wrong. Though, a language is a language and “coding” is mostly if not wholly about knowing what you want to do, and its components – hence is like architecture. Once you have most if not all things laid down on a piece of paper, the language or framework is but a tool in your hand.
How I Failed with React Native
When I was at the crossroads, I had two options: Go native with Kotlin, which I did not want to do for I know that the actual money is on the Apple than Android side, or go cross-platform. There, as you know, there are two options: React Native and Flutter.
I first preferred React Native. I know some JS, but some. Like, really little. As you know, JS is, at least for people like me, who doesn’t know practically anything, is as close one can get to Python. It is fast, fast enough for most stuff – and if you’re doing critical job, you anyway wouldn’t even consider it as an alternative. It is a programming language, hence once you get to actually learn it, you are not limited with RN but a whole world lies ahead of you.
The environment. Setting up the environment for RN, even though I followed the exact steps mentioned in the documentation, just was a headache so much so that it took days. Literally days. It’s been a while and I do not recall what it was but there was an error that hit me each and every time. At some point I even formatted my computer blaming the leftovers from previous attempts to no avail: I spent half a day to set up all programs for no reason.
When I managed to make it work in the end, I built a very simple password generator app. It is different from others in one and only way: You need a keyword. As long as you provide the right keyword, like the code to a safe, together with the mail address and the website name, it generates the same thing all the time. Hence, you would have a strong password, repeating the uppercase-lowercase-number-special character pattern by default, and no one, not even the app would need to remember what the password was. Set a keyword, anything that you like, and you could easily have a 16-digit password at hand, of which not even one character might need to remain in your mind.
Building it was a huge hassle. If you do not already, you better do now: JS is not forgiving. If it throws an error, and believe me it throws most if not all the time, it does not tell you what it is. You are to read the code and find it. Maybe you missed a comma, maybe something bigger. But, that is the smaller problem.
Bigger problem: When I unplugged my phone, and replugged it, suddenly my environment decided to start throwing errors again. After spending two weeks, I gave up and turned my head to the other alternative.
How Did I Start Flutter
With Flutter, setting up the environment is easy. So easy. Super easy. Download VS Code, download Android Studio, and you are practically done. Maybe, MAYBE it is that easy with RN too and my failures with that actually helped with Flutter, I really cannot tell. What I know is, I was mesmerized when things actually started to work. I unplugged my phone? No problem. When I plugged it back, it continued working. I switched to using the emulator? Still the same. Perfect! Two weeks I had spent on the password generator. I spent only two days later, with Flutter, and it was lot more featureful and was working wonderfully.
Here I must say: Every mistake we make grows us. React Native was my first venture in mobile development, and my failures there actually helped me to learn couple of stuff. I keep making tons of mistakes, and I keep learning from them. I cannot blame RN, I have to blame me. With R too, for example, when everyone set up RStudio on their laptops in the class, mine just and simply did not work – and I dropped that course simply because of that. Two years later I tried again and it just worked – on the same computer. Maybe I got a bad one, who knows?
Three Reasons to Love Flutter
I said above, but let me clarify those three points a bit here. Please remember: These are my experiences, and yours can wholly differ. Consider me an idiot who cannot even run RStudio, and add: If even he can do almost anything with Flutter, I can do tons better in shorter time and with less effort.
Flutter is Simple. It forces you to think two dimensionally for the front end: The vertical flow of blocks (for mobile development), and the order of stuff in each block.
What I mean? Think of a card. A simple card. In it, you will lay a text, centered. And the card will work as a button, and when clicked, don’t know, will do a calculation, send the user to another screen, whatever. How should the order of things be? Well, here it is simple: We open a card, then add a child, center, and another child, text. Done. Not everything is this simple but this is not a lecture, eh?
The main idea, most of the time, is that you first lay the ground for a triangle. In the basic example, it is card. That is the ground. Then, we narrow things down: How do we want the card to look, to act, to whatever? If we wanna add color, here it comes, for example. Once we are done with the general stuff, we move narrower and add a child: Center. Then we narrow things further and add the text widget. Flutter works like, widget, inside a widget, inside another widget… Take a look at the code below:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp( // Root widget
home: Scaffold(
appBar: AppBar(
title: const Text('My Home Page'),
),
body: Center(
child: Builder(
builder: (context) {
return Column(
children: [
const Text('Hello, World!'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
print('Click!');
},
child: const Text('A button'),
),
],
);
},
),
),
),
);
}
}
(The example above is directly taken from flutter.dev)
We do: Override, and build a widget. Then, in it, we have our (well, not exactly but for the sake of simplicity) “base widget”, the scaffold, where everything is laid. Appbar is a widget of its own, then is body as a widget. Column is a widget, in it we have text widget, sized box widget, elevated button widget… Once you get to actually realize the order of things and how they interact with each other, half the front-end job is done. The other half’s 95% is state management, and 5% is colors, fonts, and such.
Code looked scary? Will come there, don’t worry. Let us continue with the goods first.
Hot Reload is a miracle, I said. What it does is: When you change a line, or maybe a whole widget. It is reflected directly to the emulator the moment you save – or, if you’re like me, when you click the letter “r” on your keyboard in the terminal. I really don’t know how it works with RN, but I guess it needs hot restart, starting the app from scratch, for you to see if all is good. I mean, everyone loves hot reload, which makes me believe that it lacks.
VS Code support (is it called support?) is amazing. As you see in the example code above, it is a jungle of closing parantheses of all sorts. You miss one and you are in deep – but don’t worry! Unlike JS, Dart tells you, right in production, while you are coding, that there is an error in the code level. Runtime errors of course exist and there’s no way out of it, like overflown text for example, but these “you didn’t close this paranthesis” or “hey, your map function does not sound right” or “you are using a different package than you remember, and in this one this function does not exist” are really, really nice features that I benefit day in and out.
These three aren’t the only reasons, but the primary ones for me. And, in a world even my wife has flaws, of course Flutter does too. Let me mention a few.
What I Don’t Like About Flutter
Dart, the core of Flutter, once you are in the reading bits (actual code?), is easy to read and understand what is going on. But, between those readings bits, are (at times) huge (and at times even massive) blocks of parantheses. Look at the code below:
# Compact nested way
result <- sum(log(abs(rnorm(10))))
# Easier to read way
x <- rnorm(10) # generate 10 random normal numbers
y <- abs(x) # take absolute values
z <- log(y) # take natural log
result <- sum(z) # sum them all up
result
This is R and is a simple function I asked ChatGPT to produce. A stupid one, I know, but presenting real data here would not make sense.
In the first row, you see the way I like to write the R functions: Paranthesis, inside paranthesis, then another paranthesis… Not that easy to read for some, for it is read right to left, from the innermost part (in this example, and in more complex cases things easily go crazy), but is more organized for me. The second is the easier to read way, doing exactly the same thing. With Flutter, there is no compact way. I mean, yes, there is, but the moment you’d do that, you’re in deeper trouble than trying to find which paranthesis is not closed.
I wish, albeit as per its “grammar and structure” it is not possible, there was a way to do Flutter the compact nested way. I would have learned half the things lot easier and faster if it was somehow doable this way. Trying to find which paranthesis is not closed should not be part of the job but, hey! At least it tells us where the problem is unlike RN.
My second issue is that due to the limitations of Dart, I need to use JS at times and it is a problem because, yes, JavaScript sucks! I gave up on a project, one would actually make me tiniest bit famous providing not even one cent, all and only because I had to fix a package that used JS and had no alternative. I simply couldn’t. Someone knowledgeable could do, but sadly that was not me. Almost all native code has a package in pub.dev, hence using bluetooth or whatever is no problem, but the structural limitations, even if rarely, hit bad.
Third is that there is little to no job openings. Flutter, I don’t know why, is not as famous or revered as RN. Because it uses Dart? Because JS is more powerful? I don’t know. I am building small apps, and most are, as one Reddit user once said, simply database wrappers: I let the user log, or I have my own, and I show them what is there or what they input in a simple way. In terms of mobile development, I really do not get why RN is preferred, but I don’t care. Am about to release 10 apps in less than two months, all of them at once, on both Android and iOS, and that’s what matters for me. When I release, then I can start worrying why my apps don’t make (much) money or why potential customers don’t reach me. Till then, I postpone this potential depression.
I cannot compare directly to RN as my experience there is almost nil, I may add a fourth one: At times, I feel as if I am repeating some things too much. That being said, I believe it is my problem. I still cannot organize my project properly. Hence take this with a pinch of salt.
Conclusion
As you already realized, I like Flutter. It has shortcomings – Provider being a package than a core element already is disturbing, for example. But there are walkarounds and solutions to many things. If you read this far, I may repeat: Don’t lose time. Set up the environment for either one, and start building your project. You will see maniacs telling you that RN is faster than Flutter in a very very specific thing, don’t know, by 8 milliseconds or Flutter wins because it is almost as performant as native code. If you will do Kotlin, do, and build for Android alone. If you will do Swift, do Swift. Both of them have more job opportunities and, given that money is on iOS, you’ll be better-off learning Swift, actually. But if you will do cross-platform, just don’t lose time trying to get what to choose. They both will work fine, and have their superior and inferior sides. Flutter is easy to build with and fast to progress in. The rest, after that, is all down to your creativity.