In Flutter, what are the stable, beta and main channels, and how do flutter channel, flutter upgrade and flutter downgrade move the SDK?
answer
- the SDK is a git checkout
- channel equals branch
- stable quarterly, beta monthly
- upgrade refuses local changes
- downgrade undoes one upgrade
basics
~20 sThe Flutter SDK is a git checkout and a channel is its branch: stable for production, beta monthly, main for contributors. flutter channel switches branch, flutter upgrade moves to the channel's latest release, flutter downgrade undoes the last upgrade.
solid answer
~40 sThe SDK is a git clone of the Flutter repository, and a channel is the branch it tracks. **stable** is updated about every three months and is the one for production apps; **beta** gets the same testing but ships monthly, and stable is cut from it; **main** is the development line for Flutter contributors. `flutter channel` lists channels with `*` on the current one; `flutter channel beta` fetches, checks out that branch and re-downloads artifacts, then tells you to run `flutter upgrade`. `flutter upgrade` fetches, hard-resets to the channel's latest release, refuses if the checkout has local changes unless you pass `--force`, then precaches artifacts, upgrades the enclosing project's packages and runs doctor. `flutter downgrade` takes no version: it only returns to the revision you had before the last `flutter upgrade` on this channel.
code
bash · 6 linesflutter channel # lists channels, * marks the current one
flutter channel beta # fetch, checkout beta, precache artifacts
flutter upgrade # newest beta build; also runs doctor
flutter upgrade --verify-only # only report whether an update exists
flutter channel stable && flutter upgrade
flutter downgrade # back to the revision before the last upgrade on this channelgo deeper
Know the three channels, that stable is for production, and the commands flutter channel and flutter upgrade.
Explain that the SDK is a git checkout, what channel switching and upgrade do under the hood, and why downgrade only undoes the last upgrade.
Recover a broken SDK: detached HEAD after a manual checkout, upgrade refusing local changes, and the pub upgrade that runs when upgrading from inside a project.
Set a team policy for channels: when beta is justified, how upgrades are scheduled around releases, and how SDK versions stay consistent across machines.
## The SDK is a git checkout Whatever way you installed it — a downloaded bundle or a clone — the Flutter SDK directory is a **git working copy** of the Flutter repository. The engine binaries and the Dart SDK are not in git; the tool downloads them into `bin/cache` on first run and after every version change. Almost everything in this topic follows from that: a channel is a **branch**, a version is a **tag**, and the SDK commands are wrappers around `git fetch`, `git checkout` and `git reset`. ## The channels | Channel | Cadence | Intended for | |---|---|---| | `stable` | about every three months, plus hotfixes | new users and production app releases | | `beta` | monthly | experienced users who want features sooner; stable is updated to the latest beta | | `main` | continuous | contributors to Flutter itself | The tool also lists `master`, the contributors' development branch that `main` follows, and the retired `dev` channel is treated as obsolete: switching to it prints a suggestion to use `beta` instead, and `flutter upgrade` from it transitions you to `beta`. Plugin and package maintainers test against the latest stable, which is one more reason app teams stay there. ## flutter channel - `flutter channel` with no argument lists the official channels present on the remote and marks the current one with `*`. On an unofficial branch it prints `Currently not on an official channel.` - `flutter channel <name>` runs `git fetch`, checks out the branch, and by default downloads all binary artifacts (`--cache-artifacts` defaults to true, the equivalent of precaching every platform). It ends by suggesting `flutter upgrade` so you are on that channel's newest build. ## flutter upgrade The upgrade runs in two halves: 1. **Fetch and check.** `git fetch --tags`, then compare the local revision with the upstream one. `flutter upgrade --verify-only` stops here and only reports whether a newer version exists. 2. **Refuse risky states.** If the checkout has uncommitted changes, it stops with a message suggesting `git stash` or `--force`. If `HEAD` is not on a branch, it stops with `Your Flutter checkout is currently not on a release branch`. If the upstream remote is not the standard one, it asks you to set `FLUTTER_GIT_URL` or reinstall. 3. **Record and reset.** It records the current revision as this channel's last active version, then runs `git reset --hard` to the new revision. A reset rather than a fast-forward is deliberate: release branches carry cherry-picks, so there may be no fast-forward path. 4. **Continue.** A re-invoked tool precaches the new engine artifacts, runs a **pub upgrade on the project enclosing the current directory** if there is one, and runs `flutter doctor`. The pub step surprises people: running `flutter upgrade` from inside an app upgrades that app's dependencies within their constraints and rewrites its lock file. Run it from outside the project if you do not want that. ## flutter downgrade `flutter downgrade` is an **undo for the last upgrade on the current channel**, not a version picker: - It reads the revision recorded before the last upgrade on this channel, asks for confirmation, `git reset --hard`s to it and checks the channel branch out again. - It rejects any positional argument; `flutter downgrade 3.44.0` fails with a message that it does not support specifying a version. - If you never upgraded on this channel, it exits explaining that there is nothing to undo. To move the global SDK to one specific release, the documented route is `git checkout <version>` inside the SDK directory. That leaves a **detached HEAD**, so a later `flutter upgrade` refuses until you switch back with `flutter channel stable`. Keeping different projects on different SDK versions is a separate problem with its own tool. ## Choosing sensibly 1. Ship from `stable`; try `beta` on a branch or a second SDK when you need a feature early. 2. Read the breaking-changes page before a minor upgrade; it lists migrations and the `dart fix` rules that apply some automatically. 3. Treat the SDK directory as tool-managed: local edits make `flutter upgrade` refuse, and `--force` discards them.
- After running git checkout 3.44.0 in the SDK, why does flutter upgrade fail, and how do you recover?Checking out a tag detaches `HEAD` from any branch, and `flutter upgrade` needs a branch with an upstream, so it stops with `Your Flutter checkout is currently not on a release branch`. Run `flutter channel stable` to return to the branch, then `flutter upgrade`.
- What does flutter upgrade --force change, and when is it acceptable?Without `--force`, upgrade refuses when the SDK checkout has uncommitted changes, or when it cannot identify the current tag, to avoid destroying local work. `--force` skips those guards and the hard reset discards the changes. It is fine when the edits were accidental; if you patched the SDK on purpose, stash or commit them first.
The SDK is a bookmarked book: the channel chooses which edition you read, upgrade moves the bookmark to that edition's newest chapter, and downgrade only moves it back to where it was before the last move.
saying these in an interview costs you the question
- Uses flutter downgrade 3.44.0 to pick a specific version
- Recommends the main channel for production apps
- Thinks beta receives less testing than stable
- Believes flutter upgrade only touches the SDK, never the current project
- Still names dev as a current Flutter channel