Maintaining Consistency Across Devices with Flutter

A few months ago, I shared my excitement about Flutter, Google’s new portable UI-toolkit. I have continued to spend time learning Flutter outside of work, and it has been a lot of fun but left me wanting more. One of my favorite parts about learning something new is figuring out how I can leverage it to solve the problems that I currently have. There’s one problem in particular that I face on a daily basis while working on native mobile apps: consistency.

What’s the Problem with Consistency?

It’s a lot of work to make all the necessary updates to an application and track the status of those changes in a backlog management system. And that work is amplified when a single team is responsible for making those changes to both iOS and Android while ensuring they look and behave the same.

Supporting all of the different device configurations (screen sizes, device orientations, font sizes, etc.) requires a great deal of focused, detail-oriented work, especially for multiple platforms. It can certainly be done, but you will be spending a lot of your time trying to keep the two platforms consistent.

The problem becomes even larger if you begin localizing your app because internationalizing an app in order to support multiple locales can drastically change the UI from its original design. Making sure all of the UI changes are implemented correctly on both platforms adds to the amount of extra overhead that’s required to keep native apps consistent with one another.

How Does Flutter Help with Consistency?

Like other cross-platform tools, Flutter is a single codebase that builds the iOS and Android apps for you. As I mentioned in my previous post, it ships with the Skia Graphics Library and is responsible for rendering all of the pixels while your app is in the foreground. This helps reduce some of the issues that other cross-platform tools have with translating UI abstractions into the native components for each platform.

However, Flutter still has to deal with a wide variety of possible device configurations. Its ability to hot-reload whenever you make changes is great, but it is still only running on a single device with a single configuration.

Surely we can’t utilize this across multiple device configurations to speed up the process of verifying our changes work in all cases. Or can we?

We Certainly Can!

When you install Flutter, you also get the Flutter CLI, which has a wide range of commands to help you manage your Flutter project, including the ability to run your current project on a simulator or connected device. Simply by typing flutter run from the root of your project, the Flutter CLI will take care of performing the necessary Xcode or Gradle build (depending on the target simulator/emulator/device) and deploy the app for you. But what happens when there are multiple possible targets at the same time?

When there are multiple possible targets, Flutter will let you know that you need to specify a device to target. Recently, I learned about an option that lets you run your app on ALL of the possible simulators/emulators/devices. If you type flutter run -d all, Flutter will perform all of the necessary builds (for iOS or Android) and deploy your app on all of the possible devices. Now that your app is deployed on all of the devices, the Flutter CLI can hot-reload all of the devices that are running your app when you make changes to your code!

Running the same Flutter app in two iOS simulators that are using different language settings.

You can do this with any combination of iOS/Android simulators as well as physical devices that are connected to your machine. These devices can be in any configuration that you want, covering a wide range of device orientations, language settings, font sizes, etc. Being able to make a change in your code and see it reflected across multiple device configurations without reloading the state of each app is a game-changer for maintaining consistency in your mobile app. You can also use the screenshot tool in the Flutter CLI to capture screenshots of every device at the same time.

The ability to hot-reload your Flutter app across multiple devices simultaneously is incredible. Here are a few more examples of this in action.

Running the same Flutter app in two iOS simulators that are using different language settings while also being rendered as an Android app.

Running the same Flutter app in two iOS simulators in landscape mode that are using different language settings while also being rendered as an Android app.

Running the same Flutter app in two iOS simulators in landscape mode that are… do you see where I’m going with this?

Flutter continues to amaze me every time I use it, and I know that it will only get better with time and the hard work of the open-source community. Have you had a chance to try Flutter yet?