In FVM, how do fvm spawn, fvm flavor and fvm exec differ from fvm flutter, and when would you use each?
answer
- fvm flutter follows the pin
- spawn names a version once
- flavor names a version in .fvmrc
- exec runs any command
- FVM flavors are not build flavors
basics
~20 sfvm flutter runs the pinned SDK; fvm spawn <version> runs one command on another version with the pin unchanged; fvm flavor <name> uses a version named in .fvmrc; fvm exec runs any command with the pinned SDK on PATH.
solid answer
~40 s`fvm flutter <args>` and `fvm dart <args>` run the SDK selected by the project pin, falling back to the global version. `fvm spawn 3.44.3 test` runs one Flutter command on a named version, installing it if needed, while `.fvmrc` stays unchanged, which suits checking whether tests pass on the next SDK. `fvm flavor production build apk` runs a Flutter command on the version that `.fvmrc`'s `flavors` map assigns to `production`; `fvm use production` switches the pin to it, and `fvm use 3.44.3 --flavor production` records it. `fvm exec <command>` runs any program, such as a script or Melos, with the pinned SDK's `bin` first on `PATH`. FVM flavors are named SDK versions and have nothing to do with Flutter's `--flavor` build variants.
code
bash · 5 linesfvm flutter test # the project's pinned SDK
fvm spawn 3.47.5 test # rehearse the next SDK; pin unchanged
fvm use 3.44.3 --flavor production # record a named SDK version in .fvmrc
fvm flavor production build apk # one command on the production flavor's SDK
fvm exec ./scripts/generate.sh # any command with the pinned SDK first on PATHgo deeper
Know that fvm flutter uses the project's version and that FVM can run a command on another version without changing it.
Explain spawn, flavor and exec, what each selects, and that none of them edits .fvmrc.
Use spawn for upgrade rehearsals and exec for tooling, and keep FVM flavors distinct from app build flavors in pipelines.
Decide whether a team keeps parallel SDK tracks with FVM flavors or a single pin with rehearsed upgrades.
## Four ways to run with FVM | Command | Which SDK | What it runs | Changes the pin? | |---|---|---|---| | `fvm flutter <args>` / `fvm dart <args>` | nearest `.fvmrc`, else global, else `PATH` | the `flutter` or `dart` tool | no | | `fvm spawn <version> <args>` | the version you name | the `flutter` tool | no | | `fvm flavor <flavor> <args>` | the version `.fvmrc` maps to that flavor | the `flutter` tool | no | | `fvm exec <command>` | the project's selected SDK | any program, with that SDK on `PATH` | no | None of these change `.fvmrc`; only `fvm use` does. ## fvm spawn: try another version once `fvm spawn` takes a version as its first argument and passes the rest to that version's `flutter`: - `fvm spawn 3.47.5 test` runs the tests on 3.47.5 while the project stays pinned to, say, 3.44.3. - If the version is not cached, FVM installs it first. - It suits **upgrade rehearsals**: run analysis and tests on the next SDK before changing the pin, or check whether a bug reproduces on an older SDK. ## fvm flavor: named versions in .fvmrc An **FVM flavor** is a name mapped to an SDK version in `.fvmrc`: ```json { "flutter": "3.47.5", "flavors": { "production": "3.44.3", "next": "beta" } } ``` - `fvm use 3.44.3 --flavor production` adds or updates the mapping (`--env` is an alias). - `fvm use production` switches the project's pin to the flavor's version. - `fvm flavor production build apk` runs one command on the flavor's version without switching. - Channel names are rejected as flavor names, and `fvm flavor` fails for a flavor that `.fvmrc` does not define. This is useful when a team ships a production app from a conservative SDK while preparing the next release on a newer one. ## fvm exec: anything else `fvm exec` runs an arbitrary command with the selected SDK's `bin` directories first on `PATH`. Typical uses: - a shell script that calls `flutter` and `dart` many times; - tools that shell out to `flutter` themselves, such as a workspace manager or a code generator wrapper; - one-off diagnostics like `fvm exec which flutter`. Without it, those tools would call whichever `flutter` the shell finds. ## A naming trap: two meanings of flavor - **FVM flavor** — a named *SDK version* in `.fvmrc`. - **Flutter build flavor** — `flutter run --flavor staging`, a variant of the *app* with its own identifier, icons or configuration, defined in Gradle and Xcode. They can coexist: `fvm flavor production build apk --flavor prod` builds the app's `prod` build flavor with the SDK FVM's `production` flavor names. Mixing up the two in an interview answer is a clear signal of shallow knowledge. ## Choosing 1. Day-to-day work: `fvm flutter`. 2. Try an SDK once: `fvm spawn`. 3. Keep named SDK tracks for the project: `flavors` plus `fvm flavor` or `fvm use <flavor>`. 4. Run other tools with the pinned SDK: `fvm exec`.
- How would you check whether a project's tests pass on the next Flutter release before changing the pin?Run `fvm spawn <next-version> test`, and likewise `analyze`. FVM installs that version if needed and runs the command on it while `.fvmrc` stays on the current version. If everything passes, change the pin with `fvm use <next-version>` in a reviewed commit.
- Why would fvm exec be needed for a script that calls flutter internally?The script's own `flutter` calls resolve through `PATH`, which may point at a global or different SDK. `fvm exec ./script.sh` starts the script with the pinned SDK's `bin` directories first on `PATH`, so every nested `flutter` or `dart` call uses the project's version.
saying these in an interview costs you the question
- Thinks fvm flavor selects a Flutter build flavor such as staging
- Uses fvm use to try a version once and forgets to switch back
- Believes fvm spawn rewrites .fvmrc
- Expects scripts that call flutter to follow the pin without fvm exec
- Names an FVM flavor stable or beta