Google released Flutter 3.38 and Dart 3.10 on November 12, 2025. This isn't a flashy feature release. It's something better: a maturity milestone that proves Flutter remains a serious long-term investment for mobile development.
The release includes 825 commits from 145 contributors, with changes that directly address compliance deadlines, performance bottlenecks, and daily developer friction. If you're running a Flutter app in production, you need to understand what's changed and why it matters.
Here's the headline: from November 1, 2025, Google Play requires all apps targeting Android 15 to support 16KB memory pages. Apps that don't comply will be rejected.
This isn't arbitrary bureaucracy. Modern ARM64 processors perform better with larger memory pages. Google's own testing shows 5-10% overall performance improvements, up to 30% faster app launches for some apps, and 4.5% better battery efficiency.
The catch? Any app using native code (C/C++ libraries, NDK components) compiled for the old 4KB page alignment will crash on 16KB devices. The operating system simply can't map unaligned memory segments correctly.
Flutter 3.38 solves this by updating to NDK r28, which compiles all shared libraries with 16KB alignment by default. But there's a dependency cascade:
If you're using third-party plugins with pre-compiled native code, you'll need to audit them. A plugin compiled against an older NDK will break your app on Android 15 devices, regardless of your own build configuration.
Dart 3.10 introduces dot shorthands, and they're the kind of small change that compounds across thousands of lines of UI code.
Before 3.10, you'd write:
Container(
padding: EdgeInsets.all(16),
alignment: Alignment.center,
child: Text(
'Hello',
style: TextStyle(color: Colors.blue),
),
)Now you can write:
Container(
padding: .all(16),
alignment: .center,
child: Text(
'Hello',
style: TextStyle(color: .blue),
),
)The compiler infers the type from context. Where the expected type is unambiguous (like EdgeInsets for a padding parameter), you can drop the class name and keep only the constructor or static member.
This isn't dynamic typing. It's compile-time inference with full type safety. The shorthand only works where the type is "obviously typed" from context. Writing var x = .start fails because there's no contextual type to infer from.
The practical impact? Community estimates suggest 10-15% reduction in boilerplate characters for UI-heavy files. That's fewer keystrokes, cleaner diffs in code reviews, and less visual noise when reading widget trees.
The stabilisation of Build Hooks (previously called Native Assets) might be the most underappreciated feature in this release.
Historically, integrating a C or Rust library into a Flutter app meant:
A version mismatch on one developer's machine could break builds for the entire team. Distributing packages with pre-compiled binaries bloated package sizes and couldn't account for all architectures.
Build Hooks in Dart 3.10 move the build logic into Dart itself. A hook/build.dart file in your package defines how native code gets compiled:
import 'package:native_toolchain_c/native_toolchain_c.dart';
void main(List<String> args) async {
await build(args, (config, output) async {
final cbuilder = CBuilder.library(
sources: ['src/native_lib.c'],
name: 'native_lib',
);
await cbuilder.run(config: config, output: output);
});
}The toolchain handles invoking the correct compiler for each platform, respecting target architecture and OS version. Your CI/CD pipeline becomes simpler because dart build becomes the single source of truth for both Dart and native code.
Impeller has been the default rendering engine on iOS since Flutter 3.29. With 3.38, it's now the default on Android for devices running API 29+ with Vulkan support.
The shift matters because of Android's GPU driver fragmentation. Adreno, Mali, and PowerVR chips all behave differently. Skia's approach of compiling shaders at runtime caused "shader jank" when new visual effects first rendered.
Impeller pre-compiles a smaller, simpler set of shaders at build time. First frames render as smoothly as subsequent ones.
There's a fallback mechanism for devices without Vulkan or with known driver issues. Certain Exynos chips, for instance, are blocklisted and automatically fall back to the legacy OpenGL renderer. You get Impeller's benefits where they work reliably without sacrificing stability on edge cases.
The 3.38 release also patches a memory leak affecting Android Activity destruction that existed since 3.29. If you've noticed memory not being reclaimed when backgrounding your app, this update fixes it.
Dart macros have been cancelled. The Dart team announced in early 2025 that they couldn't achieve acceptable performance for a feature that required deep semantic introspection during compilation.
The problem was Hot Reload. Macros needed to re-execute during incremental compilation to determine if code semantics had changed. That slowed the first step of Hot Reload enough to damage the developer experience Flutter is known for.
Instead, the team is shipping augmentations: the ability to split a class definition across multiple files using the augment keyword. This preserves the foundation for better code generation tools while keeping compilation fast.
// lib/user.dart
class User {
final String name;
User(this.name);
}
// lib/user.augment.dart
augment class User {
@override
String toString() => 'User($name)';
}Augmentations aren't macros. They're a cleaner pattern for what part files and build_runner do today. The practical impact won't arrive until tooling catches up, but the language foundation is now stable.
Apple deprecated direct UIWindow manipulation in AppDelegate with iOS 18. Apps must now delegate UI lifecycle events to a SceneDelegate for correct multitasking behaviour on iPad.
Flutter 3.38 handles this automatically for new projects and includes migration tooling for existing apps. Deep linking now works correctly in the scene context, and state restoration logic has been updated for scene-based preservation.
If your app handles background/foreground transitions or needs to restore state after system termination, verify behaviour after upgrading.
Stateful Hot Reload on web is now stable and enabled by default. Change UI code, see it update instantly without losing form data or navigation state.
The new web_dev_config.yaml file solves a persistent pain point: CORS restrictions during development. You can define proxy rules to forward API requests to your backend, configure local SSL certificates, and share these settings via version control.
proxy:
- path: /api
target: http://localhost:8080
server:
port: 5000
ssl:
cert: ./certs/localhost.crt
key: ./certs/localhost.keyCheck this file into your repo and every team member gets the same debugging environment.
Widget Previews now render directly in your IDE instead of a separate window. A new MultiPreview class lets you define configuration sets (dark mode, large fonts, different locales) and apply them with a single annotation.
@MultiPreview([
Preview(name: 'Light', theme: ThemeData.light()),
Preview(name: 'Dark', theme: ThemeData.dark()),
Preview(name: 'Large Text', textScaleFactor: 1.5),
])
Widget myWidget() => MyWidget();The preview surface supports interaction and live theme switching. For teams doing design system work, this cuts the feedback loop significantly.
Flutter 3.38 is a governance release. It's not about new widgets or experimental platform targets. It's about making Flutter apps compliant, performant, and maintainable on the operating systems that actually matter.
Google and the Flutter team invested substantial engineering effort into:
That pattern signals maturity. The framework is past the phase of adding capabilities and into the phase of ensuring those capabilities work reliably at scale.
If you're maintaining a Flutter app, here's what to do:
pubspec.yaml for native code. Verify 16KB support or find alternatives before the November deadline.At Foresight Mobile, we've been building Flutter apps since the framework's early days. If you're facing a complex upgrade path, dependency conflicts, or want to ensure your app meets the November deadline without disruption, we can help.
Get in Touch to discuss your Flutter project.
Sources: