Development of a Desktop/Web App in Flutter — the whole experience

Neofix.ch
5 min readApr 10, 2022

Some time ago, I programmed a race management tool using the Qt framework. But as time goes by, so did my framework change — to Flutter. As I was learning all the things like themes, translations, bloc… an idea grew inside me. That was the moment where I decided to create a new version of “Racego”.

Step 1: Planning

At first, I checked all the requirements that I will need. For my “QT” version, I used a direct MySQL database connection. But because since that’s not a good practice, I will definitely need a backend now…

  • Backend: I was looking for a simple solution that I can host myself. Firebase wasn’t an option for me as I liked the added challenge of building a full backend myself. That’s how I ended up with php-crud-api on GitHub, which has met all my needs so far.

What more do we need? Hmm… Some features. But which one? I figured out what I want from my future software:

  • Support for desktop and web platforms
  • Multilingual support
  • Light and dark color theme
  • Users should be required to log in. Then you can:
  • Add/remove participants, add/remove lap times for them
  • Add race classes and create rankings
  • Edit the competitors and their previous lap times

As additional challenges, I wanted to use bloc and HTTP packages for the first time in this project.

Step 2: Code the backend

Since this article is supposed to be about Flutter, I’ll only briefly go into the backend. It’s based on php-crud-api and written entirely in PHP… just a normal backend with authentication. Link to Github repo

Step 3: Learning bloc and HTTP by creating the login screen

After a hard time trying to learn bloc, I found a very good tutorial on Youtube. Since the Qt framework was fundamentally different from Flutter, this was a big “wow” moment. Having worked with bloc for a little longer, I’m still a big fan of it. Especially when it comes to unit testing and app growth, bloc has some great advantages.

I started the login screen, which wasn’t much of a challenge, but a perfect starter project to learn the bloc and HTTP package.

It was quite difficult to work with cookies and the HTTP package, because Flutter Web stores them inside the browser and my Windows app stores them with the Secure storage package. I finally ended up using two different HTTP clients (browser and desktop) via conditional import.

Login screen for Flutter desktop app
This is the final login screen. Simple and basic.

Step 4: Home screen — this is where the action begins :)

Now where going… the home screen. Since this was the hard part of my app, it took a long time. I’ve experimented a lot with Flutters UI design, and there’s really a lot you can do :).

After some coding, learning, and more coding — there was my home screen:

Home screen of racego
Overall, I’m pretty happy with this result

Step 5: Adding additional screens for the leaderboard and participant editor

Well, the leaderboard screen was pretty easy to implement… I already got the SQL query from my first version of “Racego”, so I just had to implement that in my API and generate a list.

It was a little different for the participant editor as there are two lists and each has its own cubit. But whatever, it was basically the same as my home screen and not much of a challenge.

Racego user management
Simple, but fully functional participant editor

Step 6: Add a second theme to my app

This step was more difficult than I expected. While Flutter might provide good theme support for mobile apps, generating a sufficient desktop theme with more and nested widgets was a bit more difficult. But finally, I did managed to achieve a nice UI design for both the dark and the light theme:

dark and light theme
Took quite a long time: implementing a light theme.

Step 7: Finally — Multilingual support

I was surprised how easy it is to implement a second language. I’ve never created a multilingual app before, but it wasn’t that difficult. I just took “Flutter Intl”, a VScode extension, along with the flutter_localizations intl package.

These two components made everything very easy: I just had to put the supported locales into my MaterialApp, replace all strings inside my screens with S.of(context).translationString and quickly translate all.

Racego now officially supports English and German.

What I learned about this project

In short: a lot! I created my first PHP API, learned how to use bloc, HTTP and themes and added a second language for the first time ever. I’m going to tell you my top 5 learnings now:

  • Flutter rocks. When I compiled my first version, I was totally impressed with the performance. I immediately compared my new version to my previous, Qt-based App, and the Flutter app was definitely as performant as my previous version.
  • Translating an app is easy. Once learned, it’s easy to add the translations to the app.
  • I love the Flutter design — you have almost all the options to customize your app the way you want. I even created my own fully customized widget (input field for lap time).
  • Flutter Web is disappointing. When I put my app on the web, it took a very long time to load (even on localhost) and was not performant at all. But hey, it is JavaScript based, so not totally unexpected… and it works. My advice: you can definitely use Flutter Web, but if your users mainly use web, you should consider a web framework.
  • The bloc package is great and very well suited for large apps, or those that need to be tested.

This is it — my first HTTP, bloc, multilingual project

Feel free to use or join the project: Racego on Github
There are still a lot of things that could be done and improved. For example, adding proper tests or support for mobile devices.

So… what's next? Maybe your project, because you can always reach me. You can always contact me or contribute to my Github repos: Github.com/maheini
Or contact me on my website (German): Neofix.ch

--

--