Flutter 3.38.6 and the `engine.version` Bump: Reproducible Builds Get Easier (If You Pin It)
Flutter 3.38.6 bumped engine.version, and that matters for reproducible builds. Learn how to pin the SDK in CI, avoid engine drift, and diagnose 'what changed' when builds break with no code changes.
Flutter 3.38.6 landed with an “engine.version bump” release entry, and that small phrase matters more than it looks. If your CI builds have ever drifted because one machine picked a slightly different engine artifact, pinning becomes the difference between “it works” and “we can reproduce this build next week”.
Release entry: https://github.com/flutter/flutter/releases/tag/3.38.6
engine.version is the hidden pin behind the SDK
When you run flutter --version, you are not just picking a framework version. You are implicitly selecting a specific engine revision, and that revision controls:
- Skia and rendering behavior
- Platform embedder changes
- Tooling behavior that depends on engine artifacts
An update to engine.version is Flutter saying: “this SDK tag maps to this engine revision”. In other words, it is a reproducibility signal, not just a chore for the release process.
Pin Flutter 3.38.6 in CI the boring way
The boring way is the best way: use a version manager and commit the version you want.
If you use FVM, pin Flutter explicitly and make CI fail if it drifts:
# One-time on your machine
fvm install 3.38.6
fvm use 3.38.6 --force
# In CI (example: verify the version)
fvm flutter --version
If you are not using FVM, the important idea is the same: do not let “whatever is installed on the runner” decide your engine. Install Flutter 3.38.6 as part of the pipeline, cache it, and print flutter --version in the logs so you can diagnose drift.
The “why did my build change” checklist
When a Flutter build changes with no code changes, I check this order:
- Flutter SDK tag: are we still on 3.38.6?
- Engine revision: does
flutter --version -vshow the same engine commit? - Dart version: SDK drift can change analyzer and runtime behavior.
- Build environment: Xcode/Android Gradle Plugin versions can create differences.
The reason I like calling out engine.version is that it makes the second bullet actionable. Once you treat the Flutter SDK as an immutable input, the rest of the pipeline gets easier to reason about.
If you maintain multiple apps, make the pin visible. A README snippet or a CI check that verifies Flutter 3.38.6 is cheap, and it saves hours the first time someone asks: “what changed?”.