One question people often ask me is:
How do I build an eCommerce / food ordering / Uber clone app in Flutter?
While my full time job is to create Flutter tutorials and courses, I don't have the time to make tutorials for every app out there.
Most importantly, you shouldn't need to rely on tutorials in order to build your own apps.
Here I share my mental process for how I build complex apps, along with some tips about how to learn effectively.
TL;DR: by continuously learning, practicing and getting feedback things, you'll be able to progress a lot faster:
Let's dig into all the details. 👇
Coding = Playing Lego (kinda)
The way I see this, is that building apps is like playing Lego.
When you play Lego, you can make complex things by putting together smaller building blocks made of - uh - Legos. 😅
And when it comes to app development, you make complex apps by putting together smaller building blocks made of code.
So if you want to get good at build complex Flutter apps, you need some in-depth knowledge of:
- the Dart language
- Flutter foundations and APIs
These are your tools for the job. And you need to learn them well.
But that's not enough. You'll also need to know about:
- programming principles (SOLID)
- design patterns
- debugging
- some core packages, so that you don't have to reinvent the wheel
and much more.
Learning all the above takes time.
But what takes even longer is trying to build a complex app before you understand the foundations well enough.
If you don't have a solid foundation you'll struggle, get stuck, and wait hours or days for an answer on StackOverflow. ðŸ˜
The flip side is that once you do have a solid foundation, you'll have at least some sense of how to proceed without much outside help.
All this sounds nice, but you may be thinking: "ok but... I'm not there yet and I still don't know how to build complex apps. Welp!".
How I build complex apps
As it turns out, I spent the last few months building a complex habit tracking app and creating an entire Flutter course about it. And I'm about to share how I did it.
This app is a clone of one of the top Health & Fitness apps on the App Store, and here's the final result as a Flutter web demo:
Even though I've built many complex apps over the years, this was still a challenge for me because this app has a lot of custom UIs & animations. I didn't know how to implement many of these features upfront, nor did I know much about Flutter animations before I started.
So I'd like to share my thought process as I tried to build this complex app.
And I can assure that I had a few false starts and went through a lot of trial and error before completing this project. But I did not get stuck, and found a solution to every problem I faced along the way.
So how did I do it?
Reverse-engineering an existing app
The goal of this project was to create a working clone of an existing app. So I downloaded the Streaks app from the App Store, and spent a lot of time figuring out what were the main building blocks and how each feature could be implemented.
Some of the most challenging features were:
- An animated task completion ring controlled with a tap-and-hold gesture
- A 3D page flip transition that could be triggered programmatically or with gestures
- Completely custom animated theming: multiple color themes, multiple variants for each theme
When I started I had no idea how to build any of these features. But I knew they all involved animations.
Documentation & Googling can go a long way
Luckily, the Flutter documentation has a very good introduction to animations, along with useful codelabs to get some practice with the basics.
So I read the documentation (multiple times), and tried to create a mental map of which animation APIs could be used for which app features:
Reading the documentation can give you a broad understanding of a given topic, and some intuition about what's possible and what's not.
And then I started building the features, one at a time.
Some things, such as the task completion ring, were not too complex because I already had some prior knowledge about how to use custom painters and explicit animations:
But other things like the page flip transition were out of my league, and I didn't see an obvious way to apply the Flutter animation APIs to get the effect I wanted.
So I got Googling and I found two useful tutorials, which set me in the right direction.
I experimented with the code from one of the tutorials, breaking it down and re-assembling it (like you would do with Legos), and I created my first solution from it. But the sample code wasn't good enough for my use case, and I needed to take things further.
At this stage, what I didn't do was to go back online looking for other tutorials.
Rather, I improved my solution with what I learned from the Flutter documentation, creating something entirely new that no-one had done before.
This was valuable, so I decided to open-source it as a page_flip_builder package that could be used by others. And I shared two full tutorials about how I created it:
- Flutter Animations: Interactive Page Flip Widget
- Flutter Animations: Interactive Page Flip Widget [Part 2]
Sometimes there just isn't a ready-made tutorial or package for what you need. So you need to build things from scratch or by combining what's already there. This is a great way to learn. If you figure out something hard, you can share the result for bonus points. 💯
Bonus challenge: iOS First Jank
Eventually I managed to build all the complex UI features, but my app suffered from the infamous iOS first jank issue, and I wasn't going to release a Flutter animations course with a severe animation performance issue.
So I submitted a detailed issue on the Flutter repo. This is probably beyond what you'll need to do as you build your Flutter apps. But doing this was worthwhile for me because one of the answers pointed out that the issue was related to text rendering. And it turned out that by disabling a custom font that I was using, the issue disappeared almost entirely.
Take-away: sometimes asking for help in public and providing useful reproducible steps goes a long way in helping everyone (yourself included).
Never getting stuck (for long)
Even though I was creating a clone, I was quite deliberate in choosing an app with complex animations and I have faced many challenges along the way.
But how I was able to take on a complex app in the first place, is that I was comfortable with all the fundamentals:
- I never had to worry about what syntax to use, because I know Dart very well
- My code was well organized from the start, because I know how to write maintainable code
- I encountered errors along the way but I didn't get stuck, because I know how to debug and use
GoogleDuckDuckGo
And the same can be true for you.
I'm not saying that you can master Flutter app development in a few months.
I'm saying that learning the foundations well will save you a ton of time going forward.
But... I want to build an eCommerce / Uber clone / TODO list for my granma
I get it. Every app is different and has different requirements.
You'll always encounter things you don't know.
But rather than watching tutorial after tutorial and trying to learn "how to build app X", focus on the fundamental techniques and design patterns used to build mobile apps.
Get better at using Google DuckDuckGo, and learn how to debug your apps using breakpoints and the Flutter inspector.
If I need to go online and find answers, I ask myself:
- Is this answer a good match for my use case?
- Does it fit well inside my codebase / do I need to tweak or rewrite it?
- Will it work for all edge cases?
- Do I understand this code completely? If not, I dig deeper and try to gain deeper knowledge.
Doing this over and over will give you super-powers. You'll become stuck less often and manage to solve things without asking (and waiting) for help. You'll also build muscle memory about what works and what doesn't.
You can go a long way just by reading the documentation and practicing things.
So that leaves us with a question:
Are tutorials and courses a waste of time and money?
After all, the #1 advice given to people stuck in tutorial hell is: build your own apps.
That's how I have learned, and how I still do things today.
But you know what? I have 15+ years experience and I still buy courses, when I know that they will save me time.
If a topic / language / package is well documented and easy to understand, you don't need a tutorial or course about it.
But that's not always the case.
Take CSS for example. Many developers hate CSS because they have an incomplete mental model of how it works, and are just looking for "tricks" for specific situations (e.g. center something vertically). I've been battling with CSS myself for a long time and most tutorials/articles/answers didn't seem to work when I applied them.
So for me, it was much more time-effective to take a very good but expensive course on CSS rather than continue to struggle.
Courses are also great when you're completely new to a certain language / framework and want to quickly get up to speed, following a structured approach.
Where to find good tutorials and courses?
That is a good question. An even better one is: who makes them?
I think this is key. You want to learn from someone who's an expert in their field, and is good at explaining complex concepts concisely and in simple terms.
So hang out on Twitter and Reddit and figure out who's consistently posting valuable stuff. You can even find the best developer blogs on any tech stack.
As far as Flutter goes, this is what I strive to do: create good content and help others fast-track their learning.
For example, it took me 60 hours to build the entire habit tracking app, and I've condensed all my learnings into a 7-hour course covering Flutter animations in detail. If this is a topic that you need to learn about, then taking the course may save you a lot of time.
Learn and Practice as a feedback loop
In summary, I see tutorials/courses and deliberate practice as complementary tasks.
Alongside reading the documentation, watching tutorials, and taking courses, you need to practice building apps by yourself, and learn from your mistakes.
By creating a continuous loop of learning and practicing things, you'll be able to progress a lot faster.
Note how this is a loop. It's about practicing what you learn right after you learn it. If you only watch tutorial after tutorial after tutorial, you won't retain anything meaningful because you didn't practice.
Likewise, if you only ever practice on your own, your coding style will suffer. This is where joining open source projects and working with others can have an outsized impact.
At the end of the day, a lot of this is about exposing yourself to different ways of doing things, learning trade-offs, and finding what works for you and your project.
For more details, you can see my list of 23 top tips to become a better software engineer.
Join my newsletter
If you're looking for good resources about Flutter app development, you should check out my newsletter.
I spent a lot of time putting together a curated list of resources, guiding you through the most important topics, and helping you choose the right tools and packages. My newsletter brings this all together into a single email course that you can join today - for free. 👇
Happy coding!