How to Determine the Correct Flutter Version for an Existing Project

Run flutter --version --machine to output the exact SDK version as structured JSON, or inspect the environment.flutter constraint in the project's pubspec.yaml to identify the minimum required version.

When working with an existing Flutter project, you need to determine the correct Flutter version to ensure compatibility and stable builds. The Flutter SDK provides multiple mechanisms to identify the exact version required by a project, ranging from machine-readable JSON outputs to Git-based version detection. Understanding these methods helps developers and CI systems validate they are using the correct SDK for any given codebase.

How Flutter Determines SDK Version (Runtime Detection)

The Flutter tooling determines the SDK version using two complementary mechanisms implemented in the FlutterVersion class.

The FlutterVersion Class and Cache File

The primary source of version truth is a JSON cache file generated at first launch. When you run flutter --version, the tool reads bin/cache/flutter.version.json, which contains structured metadata about the framework version, channel, and revision hashes.

According to the source code in packages/flutter_tools/lib/src/version.dart, the _FlutterVersionFromFile.tryParseFromFile method attempts to parse this JSON file first. If successful, it returns a FlutterVersion instance populated with fields like frameworkVersion, channel, and repositoryUrl.

Git-Based Fallback Mechanism

If the cache file is missing or corrupted, the SDK falls back to Git metadata. The FlutterVersion.fromRevision constructor interrogates the repository using GitTagVersion.determine (implemented around line 317 in packages/flutter_tools/lib/src/version.dart).

This method locates the most recent tag matching the current commit. If no exact tag exists, it constructs a dev version string using the latest tag plus the number of commits ahead (e.g., 3.19.0-0.0.pre‑42). This ensures the version is reproducible even on fresh clones without cached artifacts.

Checking Project-Specific Version Constraints

While the SDK knows its own version, individual projects declare which Flutter versions they support.

Reading pubspec.yaml Environment Constraints

Every Flutter project specifies SDK constraints in pubspec.yaml under the environment section:

environment:
  sdk: '>=3.0.0 <4.0.0'
  flutter: ">=3.16.0 <3.17.0"

The flutter key accepts semantic version constraints. When you run flutter pub get, the tool validates that the installed SDK satisfies these constraints. This implementation references packages/flutter/lib/src/services/flutter_version.dart, which provides the FlutterVersionInfo service exposing the SDK version to the package manager.

Validating SDK Compatibility

If the installed Flutter version violates the constraint, the tooling emits a warning or error before resolving dependencies. This prevents runtime incompatibilities caused by API changes between major versions.

Practical Methods to Determine the Correct Version

Using the CLI for Machine-Readable Output

The most reliable way to determine the exact Flutter version is using the machine-readable flag:

flutter --version --machine

This outputs structured JSON:

{
  "frameworkVersion": "3.19.0",
  "channel": "stable",
  "repositoryUrl": "https://github.com/flutter/flutter.git",
  "frameworkRevision": "b5d8c0d3e4...",
  "engineRevision": "b5d8c0d3e4...",
  "dartSdkVersion": "3.3.0",
  "devToolsVersion": "2.30.0",
  "flutterVersion": "3.19.0"
}

The frameworkVersion field represents the canonical Flutter version. This JSON is generated by the FlutterVersion.toJson method and written to bin/cache/flutter.version.json via FlutterVersion.ensureVersionFile.

Parsing the Version Cache File Programmatically

If you need to check the version without executing the Flutter CLI (e.g., in a custom CI script), read the cache file directly:

import 'dart:convert';
import 'dart:io';

Future<void> printFlutterVersion() async {
  final versionFile = File('bin/cache/flutter.version.json');
  if (!await versionFile.exists()) {
    stderr.writeln('Version file not found – run `flutter --version` first.');
    return;
  }
  final Map<String, dynamic> data = jsonDecode(await versionFile.readAsString());
  print('Flutter ${data['frameworkVersion']} (${data['channel']} channel)');
}

Extracting Constraints from Project Configuration

To verify if your current SDK matches a project's requirements:

import 'dart:io';
import 'package:yaml/yaml.dart';

void printSdkConstraint() {
  final pubspec = File('pubspec.yaml');
  if (!pubspec.existsSync()) {
    print('Not a Flutter project.');
    return;
  }
  final yaml = loadYaml(pubspec.readAsStringSync()) as Map;
  final env = yaml['environment'] as Map?;
  final flutterConstraint = env?['flutter'];
  print('Project requires Flutter SDK: $flutterConstraint');
}

Handling Missing Cache Files and Edge Cases

Git Tag-Based Version Reconstruction

When bin/cache/flutter.version.json is absent, the SDK reconstructs the version from Git metadata. The GitTagVersion.determine method in packages/flutter_tools/lib/src/version.dart executes git describe --tags --match "[0-9]*.*.*" to find the nearest version tag.

If the current commit exactly matches a tag (e.g., 3.19.0), that becomes the version. If the commit is ahead of the tag, the tool appends the commit count and hash to create a pre-release version identifier.

Development Branch Versioning

On the master or main branches, you may see versions like 3.20.0-1.0.pre-123. This format indicates:

  • 3.20.0: The upcoming release version
  • 1.0.pre: Pre-release designation
  • 123: Commits since the last tag

This versioning scheme ensures that every commit on the development branch has a unique, sortable version string even before it receives an official stable tag.

Summary

  • Run flutter --version --machine to output canonical version data as JSON, including frameworkVersion, channel, and engineRevision.
  • Check bin/cache/flutter.version.json directly if you cannot execute the Flutter CLI; this file is generated by FlutterVersion.ensureVersionFile on first run.
  • Inspect pubspec.yaml for the environment.flutter constraint to see the minimum SDK version required by a specific project.
  • Understand the fallback mechanism: If the JSON cache is missing, FlutterVersion reconstructs the version from Git tags using GitTagVersion.determine in packages/flutter_tools/lib/src/version.dart.
  • Handle development builds: Versions on non-stable branches follow the format X.Y.Z-N.0.pre-M, constructed from the nearest tag plus commit count.

Frequently Asked Questions

How do I check the Flutter version from the command line?

Run flutter --version for human-readable output or flutter --version --machine for structured JSON. The machine-readable format includes the frameworkVersion field, which represents the canonical version string (e.g., 3.19.0). This command reads from bin/cache/flutter.version.json or falls back to Git metadata if the cache is absent.

What file stores the Flutter version metadata?

The authoritative cache file is bin/cache/flutter.version.json located in the Flutter SDK root. This JSON file is generated by the FlutterVersion.ensureVersionFile method when you first run flutter --version. It contains fields like frameworkVersion, channel, frameworkRevision, and engineRevision, providing a snapshot of the SDK state without requiring Git operations.

How does Flutter determine the version without the cache file?

If bin/cache/flutter.version.json is missing, the SDK falls back to Git-based detection implemented in packages/flutter_tools/lib/src/version.dart. The FlutterVersion class calls GitTagVersion.determine, which executes git describe --tags to find the nearest version tag matching the current commit. If the commit is ahead of the tag, Flutter constructs a dev version string (e.g., 3.19.0-0.0.pre‑42) by appending the commit count.

Where do I specify the required Flutter version for my project?

Declare the minimum Flutter SDK version in your project's pubspec.yaml file under the environment section:

environment:
  flutter: ">=3.16.0 <4.0.0"

The flutter key accepts semantic version constraints. When you run flutter pub get, the tooling validates that the installed SDK satisfies this constraint, emitting warnings if the installed version is too old or incompatible. This constraint is distinct from the SDK's own version declaration and ensures project portability across different developer machines.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →