Over the last month, some significant events have happened in 1) the Flutter ecosystem, 2) the broader market of multi-platform app development, and 3) the tech industry in general:
- Tim Sneath leaving the Flutter team
- Increased competition from SwiftUI and other multi-platform frameworks
- Google facing some backlash after shutting down another popular product (Google Domains, which will be bought by Squarespace)
On the surface, these events may raise some level of concern (or at least unease) about the future of Flutter.
And while the app development landscape is evolving and Flutter faces increasing competition, some more careful analysis leaves me optimistic about the future of Dart and Flutter.
So read on to get my usual recap of the last month in Flutter!
The Stack Overflow 2023 Developer Survey is Out
Every year, the Stack Overflow Developer Survey offers many insights into how developers feel about languages, frameworks, and the tech industry overall.
In particular, these two blog posts highlight the latest trends and the increasing role of AI in our daily work:
- 2023 Developer Survey results are in: the latest trends in technology and work from the Stack Overflow community
- Hype or not? AI’s benefits for developers explored in the 2023 Developer Survey
And if you’ve got some time to spare, the whole survey is worth a read:
🎯 But what about Dart and Flutter?
As it turns out, Dart reached 18th place in the list of the most popular programming languages.
What I found most interesting is the chart below, showing how desired and admired these languages are, where:
- desired shows how much users want to use a technology
- admired shows how much people want to continue using it after they tried it
It also appears that amongst popular languages, Dart is the lowest paid. Most likely, this is because Flutter has wider adoption with startups and small companies that often choose a multi-platform framework to reduce costs (rather than developing the same product on multiple platforms with the native SDKs, like the bigger players).
Times are Changing
The StackOverflow Developer survey offers a good snapshot of the latest trends within the developer community.
But let’s take a closer look at the most recent news in the Flutter ecosystem. 👇
📝 A fond farewell to Flutter and Dart (by Tim Sneath)
Since joining the team in November 2017, Tim Sneath has led the Flutter project from an early alpha all the way to the latest 3.10 release.
All along, I've been impressed by his enthusiasm, charisma, passion, and dedication to Flutter and its community.
So it’s certainly sad to see him go, and you can read more on his personal blog:
So what’s next for Flutter?
As it turns out, Flutter is in very good hands, and the baton has been taken by Michael Thomsen, who has been leading the Dart team and reinventing Dart from the early days to the latest 3.0 release.
I’m looking forward to seeing how the Flutter team will continue to make progress in 2023 and beyond.
📝 It’s time for Flutter to adjust its market strategy
When Flutter first went public six years ago, React Native was its only competition as a cross-platform framework.
And at the beginning, Flutter was blazing its own trail, and there was no need for to position itself as a competitor.
But these days, some emerging alternatives exist, such as Jetpack Compose, SwiftUI, Kotlin Multiplatform, and MAUI.
And as Matt Carroll correctly points out, these competitors will try their best to chip away at Flutter’s market share. And in this article, he shares some good suggestions about what Flutter needs to do to thrive:
💻 Declarative code in SwiftUI vs Flutter
As Flutter developers, we got used to declaring UI layouts by composing various widgets in this fashion:
Widget build(BuildContext context) {
return const Padding(
padding: EdgeInsets.only(right: 8),
child: Padding(
padding: EdgeInsets.only(left: 20, top: 20),
child: Text("Hello, world"),
),
);
}
But recently, some folks have criticised the Flutter syntax for being too verbose and pointed out that the SwiftUI way (using a feature called view modifiers) is much more readable and concise.
These folks argue that by using extension methods, we can follow the tracks of SwiftUI and write “better” or “cleaner” code that looks like this:
Widget build(BuildContext context) {
return const Text("Hello, world")
.padding([Edge.leading, Edge.vertical], 20)
.padding([Edge.trailing], 8);
}
Indeed, this is the approach that has been adopted by the popular flutter_animate package:
Text("Hello World!").animate()
.fadeIn() // uses `Animate.defaultDuration`
.scale() // inherits duration from fadeIn
.move(delay: 300.ms, duration: 600.ms) // runs after the above w/new duration
.blurXY() // inherits the delay & duration from move
A whole debate raged on Twitter, resulting in some (not always constructive) discussions.
To counter that, Matt Carroll shared a very well-reasoned take on why this approach may be creating more problems than it solves, and I recommend giving this a read:
My pragmatic take on this is that the modifier-based syntax makes sense in some very specific cases (e.g. in the flutter_animate package). But, if abused, it can indeed be confusing and create more problems down the line.
Videos by the Flutter Team
Over the last month, the Flutter Team published two new videos. 👇
📹 Building custom fragment shaders
The standard way to build UIs in Flutter is by composing widgets together to get the layout we want. And when we do that, we use high-level APIs from the Flutter framework and ignore what happens under the hood.
But occasionally, we may use a CustomPainter
to draw directly on screen using the canvas API.
And recently, it has become possible to take this further and write completely custom fragment shaders that give us full control over how each pixel is painted on screen.
For all the details, watch this excellent video by Craig Labenz:
📹 Draggable (Widget of the Week)
Many UI patterns involve dragging elements from one place to another (such as when moving one document from one folder to another).
To make this possible in Flutter, you can use the Draggable widget.
To learn how to use it in combination with the DragTarget class, watch this video:
Articles by the community
When Flutter 3.10 was announced, all the biggest changes got the most attention.
But sometimes, small and important details go unnoticed, and the community has done a good job by highlighting them with these articles. 👇
📝 When not to use Dart Records
Since the release of Dart 3.0, people have started experimenting with records, patterns, and all the latest language features.
While records can help you write more concise code, using them incorrectly can lead to bugs that are hard to diagnose. So if you want to learn when you should not use records (and why), read this article:
📝 MediaQuery updates in Flutter 3.10
MediaQuery
is a handy widget that lets you query many useful properties (such as the window size, orientation, view insets, and so on).
For example, to get the window size, you could write this inside the build
method of your widgets:
MediaQuery.of(context).size
But there’s a problem with the code above: the widget will rebuild if any of the properties inside MediaQuery
changes, which can lead to subtle bugs and performance issues.
To address this, MediaQuery
has been refactored to extend the InheritedModel
class.
And as a result, the code above can be rewritten as:
MediaQuery.sizeOf(context)
The benefit of this approach is that the widget will rebuild only if the size changes (but not when the other properties change).
For all the details, read this article:
And here's the original PR describing what's changed:
New Packages
Over the last month, I discovered some new packages that can make life easier. 👇
🧱 Retry
When we load data from the network, intermittent errors can happen for many reasons (server unavailable, lost connection, etc.).
And sometimes, the best strategy is to retry.
If that’s what you want, consider using this package, which implements the retry logic with an exponential back-off strategy that can be configured as needed:
🧱 Awesome Flutter Extensions
As Flutter developers, we work with things like sizes, text styles, colors, themes, strings, and many other BuildContext
-related APIs on a daily basis.
These APIs can be quite verbose. Example:
Theme.of(context).textTheme.titleLarge
But they don’t have to be, and if we write some BuildContext
extension methods, we can do this:
context.textStyles.titleLarge
To make life easier, this package offers many helper methods that help us do the same with a more concise syntax:
🧱 Sliver Tools
The Flutter framework already ships with many useful sliver classes such as SliverAppBar, SliverList, SliverGrid, etc.
But what if you need a specific sliver that is not included in the Flutter SDK?
Before you bite the bullet and roll your own, check this new package which includes many additional sliver widgets:
Latest from Code with Andrea
Since the last edition, I’ve published three new articles, updated some of my GitHub example apps to Flutter 3.10, and added a new module about the Firebase Local Emulator and Cloud Functions to my Flutter & Firebase masterclass. 👇
📝 Flutter Bottom Navigation Bar with Stateful Nested Routes using GoRouter
Stateful nested navigation has been a highly requested feature in GoRouter, and our wishes have finally been granted.
This allows us to create apps with multiple tabs (such as when we use NavigationBar
or NavigationRail
) and preserve the state of the routes inside each tab.
And in this (updated) article, I show how to use the new GoRouter stateful APIs, share a reference implementation, and answer some common questions too:
📝 Flutter Exception Handling with try/catch and the Result type
Exception handling is a way of dealing with these potential errors in our code so our app can gracefully recover from them.
The standard way to do this is to use try
and catch
.
But if we want, we can leverage the type system to handle errors more explicitly by creating a Result
type using sealed classes and pattern matching (which were introduced in Dart 3).
And this (updated) article covers all the details:
📝 Flutter & Firebase Auth on macOS: Resolving Common Issues
If you’ve used the Firebase Auth package before, you’ve probably noticed that macOS is listed as one of the supported platforms.
But as it turns out, getting even a very basic Flutter & Firebase app to run on macOS is a challenge, fraught with many perils.
And to help you overcome all the hurdles, I’ve prepared this step-by-step guide:
🐙 Updated GitHub repos
People often ask me for reference code about how to implement certain features or how to organize projects following my Riverpod app architecture and project structure.
And over time, I’ve built a sizeable catalogue of example Flutter apps on GitHub.
Admittedly, it’s very challenging to keep them up to date (and I need to balance my time carefully).
But since Dart 3 has landed, I’ve managed to fully update these two:
Until Next Time (and maybe see you at FlutterCon?)
That’s all for today, and I hope you’ve enjoyed this newsletter.
P.S. I very rarely attend Flutter conferences in person. But FlutterCon (the biggest conference in Europe) takes place in Berlin on July 5-7, and it has an amazing speaker lineup. So I couldn’t pass on the opportunity to meet all the folks I’ve come to know and admire for their contributions to the Flutter community.
If you happen to be there, come and say hello - I would love to meet you in person. 🙂
Happy coding!