“One day, 7 apps, of course… How long was that day? 168 hours? Define ‘one day’!"
Are you looking for the definition?

The Story

Usually, every product story starts with a pain, a problem that needs to be solved. A problem that bothers you, annoys you, you face it frequently and probably you are not alone with it.
This case was not different either.

A few months ago we started to use a new HR system that has a lot of advantages compared to the old one. But it had disadvantages too… Missing functionality, missing information… or the information is there, but hard to get it out from the system.

That's when the idea of Pandoo (the holiday planner) was born.

Pandoo Icon

The Problem

The new tool did lack some features that we got used to.

A nice(r) and clean(er) way to see all of your holidays, your team's holidays (and type of those holidays), and book them in a bunch.

Disclaimer: Maybe some of these problems are manageable with admin configurations or with educating the users.. but usually, when people switch tools they just expect that “it works” and they have all the things they had previously plus nice extras.

The goal of this article is not to blame the tool, it is about the solution and the key learnings.

The Solution

I wanted to bring back the functionalities from the old tool. I wanted to see my holidays as I was used to, I wanted to book my holidays as I used to. And I was not alone with this.

The Requirements

  • I don't want to waste too much time on the MVP, just get it to work with the basic functionality and make me happy.
  • There is no way that I will build multiple apps using multiple programming languages.
  • Mobile-first, but bigger screen support would be nice where I can see more data.
  • Challenge myself.

The Choice

Flutter

Flutter logo

Why?

  • Flutter's promise

Flutter is a cross-platform tool made by Google, that helps you build native mobile apps from a single codebase.
(Edit (19/09/2020): This has been changed a bit as you will see it later. )

  • I had some experiences already.

I have built Edengreen, a tool that helps you check your available meal vouchers.
It is a really basic app, but it taught me the basics of how Flutter works. At this time Flutter was still in beta.

One of my other projects was CoronaVirus Alert, a tool that monitors the infections country by country and sends you push notifications.
In this project, I have played with Firebase, serverless functions, and custom scripts here and there. I have learned that there is a big pool of third-party libraries for Flutter and the community is growing rapidly too.

  • Web support

I have never tried, but apparently, there was rudimentary Web support too.

  • The challenge

My previous projects helped me to understand the basics but I wanted to achieve more and the Web support was sounded interesting too.

Know Your Stuff

I needed a giant scrollable table view where horizontally I can show the days of the year and vertically all of my colleagues and their holidays.
This sounds easy, but in reality, it never is. Weird, annoying edge-cases when you are almost done, lack of Flutter knowledge from my side, unforeseen platform limitations, etc…

I wanted to see what is available already by the community, maybe there is something that is similar and it can fit my needs (with minimal tweaking). Luckily I have found the horizontal_data_table package, that provided 90% of what I have needed… I have forked the package and did some fine-tuning for my needs on the way.

Getting the data from the HR tool was pretty easy, they provide a nice REST API to interact with the back-end.

When you connect the dots you have to be cautious. You need to know what you expect from your tool, how it is going to work. How does it get the data? Do we need to store the data locally? Do we need an extra server-side logic too? Do we plan to use any exotic UI elements?

These are important questions, because when you pick a library/package in Flutter and e.g. if it works on Android it does not mean automatically that it works on iOS too… or even on the Web. You need to pick libraries that rely on the default native support and no additional native third-party libraries. (Or the reliance on those libraries needs to be complete on every side.)

For example, if you would like to use Firebase services in your app, you need to check which platforms are supported. If your target is not, probably you will face a runtime crash when Flutter tries to access the non-existent APIs.

When you search for a Flutter package in the official Dart/Flutter package repository, you can also see which platforms are supported.

Package Platform support

3 Apps at Once

Based on past experiences in the MVP I did not choose any special external library (except the horizontal_data_table) because I wanted to limit the compatibility issues between iOS, Android, and Web.

After I was done with the minimal version, I tested the implementation on Android and iOS.
It worked and looked nice! (Sure, it had some performance issues here and there while scrolling through the holidays of the whole company… but on a limited dataset it was good.)

Android support

Pandoo on Android

iOS support

Pandoo on iOS

So now we have two apps ready to use!

Let's see how it works on the Web.
Of course, it crashed in a few places 😀. But nothing serious that a good old “if-else” could not solve. I have still used some APIs that were not available on the Web, so I needed to use kIsWeb constant to differ the logic between Web and native mobile.

It also had some UI quirks due to unsupported/buggy UI elements (with gradients), but it was good enough for the current phase.

Web support - table view

Pandoo on Web with rendering issues (grey boxes, weird dividers)

Web support - balance view

Pandoo on Web showing the Holiday Balance

We have the third app too, and you could say “Ok, you are done, you have it all, Web runs on all platforms”.

But wait, there is more!

The Meetup and The Extra 3 Apps

I really like Meetups. I can meet with like-minded people, listen to good and interesting presentations, and sometimes I give a talk too 😊.

There was a promising Meetup from GDG Brussels on Flutter topic. Based on the presentation summary, it intended to be a basic Flutter intro and the experiences of the author.
So it could be nothing interesting for me, I am kinda done with the basics… but I always like to repeat similar things, because maybe I can discover a new bit of information that can change my perspective and start me thinking. For the same reason, I read/listen to books on similar topics too… even the 95% is the same as a previous book, the remaining 5% is worth the time.

Luckily this case was not different either.
The presenter walked through their app development challenges and how quickly they have re-implemented the apps from scratch in Flutter.

Then he showed something interesting. His app was in a weird-looking window. It looked like a browser or a bezel-less iOS simulator. Apparently, it was his application compiled into a native MacOS app. It turned out that Flutter added support for Desktop platforms. Obviously, this was even in an earlier stage than the Web support, but it is worth a try.

The next day I tried it, it worked! I had Pandoo as a native MacOS app. Meanwhile, I have discovered that there is also really basic support for Linux and Windows… After the initial setup of the environments in VirtualBox, I could compile Pandoo as a native Windows and Linux app too! 🎉

Sure, there were some extra limitations on Windows and Linux, I had to do some extra “if-else” conditions. E.g. there was no persistent storage API available on these platforms, so I could not save any data to the disk.
(Edit (19/09/2020): Later I did polyfill these missing features by using the default Dart file reading and writing APIs.)

Extra three apps are done. Sounds good, doesn't it?

Ubuntu support

Pandoo on Ubuntu

Windows support

Pandoo on Windows

MacOS support

Pandoo on MacOS showing the Holiday Balance

+1

We can argue on this if it counts as the seventh app or not. But it was such a nice surprise to me, so please allow me to count it as +1.

While I was testing Pandoo in the Chrome Browser on my phone, I got a popup that asked me if I would like to add Pandoo to my home screen. Sure, why not. But this icon on my home screen looked different from another page link. And… it also appeared between my apps in the Launcher. What?

It turned out that the Web apps built by Flutter are PWA applications too. So even if the device is offline, you can open and use the web apps. Or, you could… if a webpage is made for that. In my case I don't cache any data from the HR tool, I fetch all the data from the API every time. That means when Pandoo is loaded inside the browser and you try to use it without an Internet connection, it shows an API error (just like all the other versions of the app). I could save the last fetched data locally and load it immediately at app start (while the new is loading)… but for now, it is ok as it is.

Conclusion

I think Flutter is a strong candidate in the app development era. Not only for mobile but in general.

I did not write a single line of code to have a Mac OSX app. Although I have some experiences with Mac OSX apps (Mike) so I would have an idea where to start, it is not a copy/paste from an iOS app, you need to put some work there. Hopefully Mac Catalyst will help with this in the future.

Write an app for Windows and Linux? I would not even think about it.

The additional Web support is really nice, and it can be really useful. For example, if you have a Revolut and TransferWise account you probably noticed that the mobile apps are very similar to each other, and they also provide a Web version too with a limited feature set. I don't know what technologies they use, but (if not Flutter already) I can imagine in the future these kinds of services will consider Flutter for their apps.

Definition of ‘One Day’

Probably at this point, you think “How on Earth was this possible in one day”?

My definition of one day: 14-16 hours.

In this timeframe, I was able to develop the most important part of the app, the giant table view with all the data in it, the holiday balance view, and the way of requesting holidays one by one.
I don't count the extra menus, extra functionalities, going to the Meetup 😀.
For the additional basic Desktop support, I don't count any minute. Basically, there was no code change done, except when I saw a crash I did put an “if-else” around the problematic part and it was “fixed”. Also, the later polyfill changes were not taken into account.

Key learnings

In general:

  • To build a prototype, Flutter is one of the best tools now on the market.
  • You don't have to over-engineer an MVP.
  • Better to know the limitations of your tool upfront than being surprised later.
  • Meetups are great to meet interesting people and gather new information.

About Flutter:

  • It supports Android, iOS, Web, Windows, MacOS, Linux (and Fuchsia).
  • If a native third-party library exists, but there is no Flutter support yet, you can make it Flutter compatible.
  • The core Dart libraries are available on all platforms, so in the worst case, you can fall-back on them.
  • The community is huge.

Support

Did you enjoy my story? There is more in the pipeline… 😉

Do you want to know more insights? Would you like to discuss the used techniques, or would you like to see some part of the code? Then consider becoming a monthly supporter on Patreon via my Tweaked.Tech initiative.

Become a Patron Become a Patron

Why?

  • The articles are published on Patreon first.
  • There is a follow-up article that shares insights, used techniques, architecture, infrastructure.
  • You can get early access to projects in the Beta phase.
  • We can discuss your ideas, your doubts, and the current issues you face in your project.
  • You keep me going, it is a big boost to my motivation!

I really appreciate a one time support too, you can do it via Buy Me A Coffee.

Buy me a coffee Buy me a coffee

Thanks for reading my story, I am grateful that you were here until the end.
Stay tuned for the next one!