As someone whose frontend development experience has largely been with React and similar libraries, Flutter looks like a promising way to create cross-platform applications that don’t run in a web browser. On mobile, Flutter is a strong competitor to both React Native and web-based solutions. And since Flutter also supports desktop, you should in theory be able to get the benefit of React-style UI plus the static typing and cohesive design of Flutter’s host language Dart as opposed to JS/TS, all without bundling a web browser.
In practice, though, Flutter is currently not a great option if you want to build a new desktop application from the ground up. What follows is a quick summary of the issues I encountered while using Flutter to do exactly this myself.
An underdeveloped ecosystem
The ecosystem of Flutter libraries that run on desktop is underdeveloped. You do get to reuse a substantial portion of Flutter libraries on desktop, but not all of them, and desktop support for many libraries is subpar. Worse, the Flutter standard library is also heavily skewed towards mobile. You have to put in the extra effort to build desktop-typical patterns into your UI. This leads to more home-grown solutions, which often don’t end up feeling as polished as components from the standard library.
I haven’t used it myself, but there is a Flutter library that implements Microsoft’s Fluent UI design system and provides a cohesive set of widgets that are more geared towards desktop apps. This library or a similar one could make it a bit easier to make desktop apps that look and feel nice.
As I developed my desktop app in Flutter, I found myself agitated with laggy and janky UI. The most glaring jankiness problem that I have encountered with Flutter is the consistently slow text selection refresh rate. I am definitely being a perfectionist on this, but it has been an ongoing issue for nearly two years. Things like this prevent your application from feeling “right” to your users. People have already learned to tolerate desktop web applications that don’t have a native look and feel, but they still expect a high amount of polish, and certainly not sluggish text selection.
There’s nothing a typical user of Flutter can do about the laggy text selection until the issue is fixed upstream. If Flutter’s jankiness problems could be fixed by improving my application’s code, that would be fine. But the vast majority of problems that I have encountered either cannot be easily fixed while preserving functionality or require workarounds.
I am far from an expert on the internals of Flutter, but if I had to guess, a low text selection refresh rate just isn’t noticeable on mobile, since users’ fingers sometimes obscure the moving end of selection. On top of that, mobile devices often snap user selections to word boundaries, which further obfuscates the slow refresh rate. As a result, it’s actually a desirable battery-saving measure on mobile to limit the refresh rate of text selection. On desktop platforms, users have a much clearer view of the selection, and so this tradeoff doesn’t work anymore.
As a result of the underdeveloped ecosystem, you’ll also find you just can’t do some things that are really common in desktop apps. For example, you can’t have multiple windows in one process. If you need two or more windows for your application to run, you will have to start a separate processes for each window and perform IPC between the processes. Another example is that you cannot customize right-click menus. You’ll have to build them yourself. Flutter even has a barebones right-click menu system specifically for text fields,
but you can’t customize it or use it anywhere else.
To be fair, these limitations are somewhat to be expected of early-stage cross-platform app development toolkits on desktop, and for some apps they don’t actually matter.
All of the problems I mentioned here can and probably will be fixed in due time. When that day comes, Flutter will be a much better option on desktop. But that day may not be right around the corner.