fgvm, a friendly Godot version manager.
Important
This project was previously known as gdvm, but as of 2.0 has now been renamed to fgvm. Most users won't be significantly impacted,
but some changes were breaking and will require users to switch over to fgvm; please see this section for information on how to migrate.
fgvm is a friendly Godot version manager that lets users install and manage multiple versions of Godot with ease. It uses a hybrid CLI/TUI design, meaning that in certain places where it makes sense
it will prompt you to let you select what you're looking for instead of having to pass in confusing arguments, as well as support for passing it unstructured queries to help find the
appropriate version based on your input, like 4 dev or latest. It's released as a self-contained native executable for Windows, macOS, and Linux that can be run without installing the .NET runtime,
either by putting it somewhere on your PATH or, preferably, using a package manager.
- Version Management: Easily manage multiple Godot installations side-by-side, allowing you to try out the latest versions or keep older versions for compatibility testing, including Godot 1.0 to the latest development builds, including both standard and .NET builds.
- Export Template Management: Install, list, and remove Godot export templates for locally installed Godot versions.
- Hybrid CLI/TUI Interface: Simple command-line interface with interactive TUI prompts for easy navigation and selection when you don't specify arguments.
- Flexible Query System: Powerful query system for finding and installing versions using keywords like
latest,4 mono,3.3 rc, etc. - Project Aware: Lock a project to a specific Godot version using a
.fgvm-versionfile in the project directory.fgvm localcan automatically detect a compatible version fromproject.godotor let you manually choose one, and will prompt to install missing versions when needed.fgvm godotuses.fgvm-versionwhen present, otherwise falls back to the global default, and can launch the current project directly from the terminal. - Smart Argument Handling: Detection of arguments passed to Godot that contextually switch to an attached mode when necessary to display terminal output.
- CI-Ready: Suitable for remote installations, CI/CD pipelines, WSL, and containerized environments with its single self-contained native executable.
Note
On Windows, fgvm creates an optional Godot.url shortcut to the selected version for GUI launch compatibility.
You can still install, remove, set, and launch versions with fgvm godot if that shortcut cannot be created.
In addition, PowerShell, the default shell for Windows, doesn't support the emojis out of the box. To fix this, you simply need to update the $PROFILE/profile.ps1:
'[console]::InputEncoding = [console]::OutputEncoding = [System.Text.UTF8Encoding]::new()' | Add-Content -Path $PROFILEAlso, if you are using cmd, you can also try the beta unicode support by going to Region in the control panel, going to Administrative, clicking Change system locale, and checking the Beta:
Use Unicode UTF-8 for worldwide language support checkbox. You will have to restart your computer, but it should enable emoji support there as well.
The recommended way to install fgvm is through a package manager, which will make it easier to keep up to date and manage your installations:
If you're on macOS or Linux, you can install fgvm using Homebrew by running the following commands:
brew tap patricktcoakley/formulae
brew trust patricktcoakley/formulae
brew install fgvmHomebrew 5 requires third-party taps to be explicitly trusted before their formulae can be installed; brew trust marks the tap as trusted so brew install fgvm succeeds. See the brew trust documentation for more details.
Note that you may periodically need to run brew update if any changes are applied to the formula.
Alternatively, macOS and Linux users can use the install script. On macOS, this avoids the browser-added quarantine attribute that can cause Gatekeeper warnings for the non-notarized binaries.
mise can install fgvm directly from the GitHub release artifacts using its GitHub backend on Windows x64, macOS, and Linux:
mise use -g github:patricktcoakley/fgvm
fgvm --versionInstall mise first using the mise installation docs; Windows users can use Scoop or winget there.
For now, use the full github:patricktcoakley/fgvm tool name. The shorter mise use -g fgvm form will only work after fgvm is added to mise's registry.
If you're on Windows, you can install fgvm using Scoop by running the following commands:
scoop bucket add patricktcoakley https://github.com/patricktcoakley/scoop-bucket
scoop install patricktcoakley/fgvmIf you do not want to use a package manager, the install scripts download the latest release, verify its SHA-256 checksum, install fgvm, and update your user environment.
FGVM_HOME controls fgvm's runtime home and defaults to ~/fgvm. FGVM_INSTALL_DIR controls where the fgvm binary is installed and defaults to $FGVM_HOME/bin.
The installer adds both FGVM_INSTALL_DIR and $FGVM_HOME/bin to PATH so the fgvm binary and the godot shim work. If you override either variable, the installer persists it in your shell profile
or Windows user environment unless you skip environment changes.
macOS and Linux:
curl -fsSL https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.sh | shWindows PowerShell:
irm https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.ps1 | iexRe-run either install script to upgrade an existing install. The installer downloads the latest release again, verifies its checksum, and replaces the fgvm binary in FGVM_INSTALL_DIR; it does not remove your FGVM_HOME installations, registry, or project version files.
If you prefer to inspect the installer before running it, download it first:
macOS and Linux:
curl -fsSLO https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.sh
less installer.sh
sh installer.shWindows PowerShell:
irm https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.ps1 -OutFile installer.ps1
notepad .\installer.ps1
.\installer.ps1To install a specific version, run the downloaded script with --version VERSION on macOS/Linux or -Version VERSION on Windows. Version overrides support
v2.2.0 or later only because older release artifacts use a different layout:
sh installer.sh --version v2.2.0.\installer.ps1 -Version v2.2.0Use --no-modify-path on macOS/Linux or -NoModifyPath on Windows to skip PATH and environment-variable changes:
sh installer.sh --version v2.2.0 --no-modify-path.\installer.ps1 -Version v2.2.0 -NoModifyPathTo use a different fgvm home, set FGVM_HOME when using the one-line installer:
curl -fsSL https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.sh | FGVM_HOME="$HOME/dev/fgvm" sh$env:FGVM_HOME = "$HOME\dev\fgvm"; irm https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.ps1 | iexTo install the fgvm binary somewhere outside $FGVM_HOME/bin, set FGVM_INSTALL_DIR:
curl -fsSL https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.sh | FGVM_INSTALL_DIR="$HOME/.local/bin" sh$env:FGVM_INSTALL_DIR = "$HOME\.local\bin"; irm https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.ps1 | iexOr pass the install directory to the downloaded script:
sh installer.sh --fgvm-home "$HOME/dev/fgvm" --install-dir "$HOME/.local/bin".\installer.ps1 -FgvmHome "$HOME\dev\fgvm" -InstallDir "$HOME\.local\bin"If you prefer to install manually, download the archive for your platform from the latest release:
| Platform | Architecture | Archive |
|---|---|---|
| Windows | x64 | fgvm-win-x64.zip |
| macOS | Intel x64 | fgvm-osx-x64.tar.gz |
| macOS | Apple Silicon ARM64 | fgvm-osx-arm64.tar.gz |
| Linux | x64 | fgvm-linux-x64.tar.gz |
| Linux | ARM64 | fgvm-linux-arm64.tar.gz |
Each archive has a matching .sha256 file on the release. Windows uses ZIP files; macOS and Linux use tarballs.
Extract the executable into a directory on your PATH; on macOS and Linux, chmod +x fgvm is only needed if your filesystem or extraction tool strips executable permissions.
The Linux binaries require glibc and do not support musl-based distributions such as Alpine Linux.
The macOS binaries require macOS 12 or later and are not currently notarized. Downloads made through a browser may be quarantined by Gatekeeper. Downloading with curl does not apply the browser
quarantine attribute, so you can verify and run the release directly:
# Apple Silicon
curl -fLO https://github.com/patricktcoakley/fgvm/releases/latest/download/fgvm-osx-arm64.tar.gz -fLO https://github.com/patricktcoakley/fgvm/releases/latest/download/fgvm-osx-arm64.tar.gz.sha256 && shasum -a 256 -c fgvm-osx-arm64.tar.gz.sha256
# Intel
curl -fLO https://github.com/patricktcoakley/fgvm/releases/latest/download/fgvm-osx-x64.tar.gz -fLO https://github.com/patricktcoakley/fgvm/releases/latest/download/fgvm-osx-x64.tar.gz.sha256 && shasum -a 256 -c fgvm-osx-x64.tar.gz.sha256
tar -xzf fgvm-osx-arm64.tar.gz # Use fgvm-osx-x64.tar.gz on Intel.
./fgvm --versionAfter confirming it runs, move fgvm into a directory on your PATH, such as ~/fgvm/bin.
The GitHub CLI can download both the archive and its checksum from the latest release:
archive=fgvm-osx-arm64.tar.gz # Replace with the archive for your platform.
gh release download --repo patricktcoakley/fgvm \
--pattern "$archive" \
--pattern "$archive.sha256"Verify the downloaded archive before extracting it:
# macOS
shasum -a 256 -c "$archive.sha256"
# Linux
sha256sum -c "$archive.sha256"Extract macOS and Linux archives with tar:
tar -xzf "$archive"
./fgvm --versionOn Windows, verify the expected hash from fgvm-win-x64.zip.sha256 against the downloaded archive:
$expected = (Get-Content .\fgvm-win-x64.zip.sha256).Split()[0]
$actual = (Get-FileHash .\fgvm-win-x64.zip -Algorithm SHA256).Hash
if ($actual -ne $expected) { throw "Checksum verification failed." }See Build for instructions on how to build fgvm from source.
Install the latest stable standard build, set it as the global default, and launch Godot:
fgvm install latest --default
fgvm godotfgvm downloads and installs Godot into folders inside of ~/fgvm/ for macOS and Linux, and $env:USERPROFILE\fgvm\ for Windows. You can customize this location using the FGVM_HOME environment variable (see Environment Variables).
New installations are stored under installations/<VERSION>-<TYPE>-<RUNTIME>/<TARGET>/, and fgvm tracks them in installations.json. For example, a 4.3 stable .NET install on Linux x64 is tracked as installations/4.3-stable-mono/linux.x86_64/.
To install export templates alongside the editor, add --with-templates:
fgvm install 4.4.1 --with-templatesBy default, fgvm records the selected version in installations.json. It also creates a stable PATH shim at bin/godot on macOS/Linux or bin/godot.cmd on Windows, and best-effort creates a root symlink named Godot on Linux, Godot.app on macOS, or a Godot.url shortcut on Windows for GUI launch compatibility.
You can run fgvm godot -i to pick another installation to launch, or use fgvm set to pick the version you want to launch by default.
Godot installation availability is separate from fgvm's own release matrix. fgvm selects Godot artifacts for the detected operating system and CPU architecture, so older Godot releases may not be available on newer targets, particularly macOS ARM64. Downloading an artifact for a different target is not currently supported.
All of this is also available in the --help section of the app:
fgvm --helpbut here is a detailed summary of the available commands:
Note: Many commands support short-form aliases for faster usage (e.g.,
fgvm iforfgvm install,fgvm gforfgvm godot).
fgvm listorfgvm l[--json] will list locally installed Godot versions. Use--jsonto output in JSON format.fgvm installorfgvm i[<...strings>][-D|--default] [--with-templates] will prompt the user to install a version if no arguments are supplied, or will try to find the closest matching version based on the query, defaulting to "stable" if no other release type is supplied. It will automatically set the installed version as the default if it's the first installation. Use--default(or-D) to explicitly set the installed version as the default regardless of whether other versions are already installed. Use--with-templatesto install the matching official export template package after editor installation succeeds. If template installation fails, fgvm keeps the editor installation and prints a warning.- Queries:
latestorlatest standardwill install the latest stable, andlatest monowill install the latest .NET stable.4 monowill grab the latest stable 4.x .NET release,3.3 rcwill grab the latest rc of 3.3 standard,1would take the last stable version1, and so on.
- Examples:
fgvm install 4.3- Install 4.3 stablefgvm install 4.3 mono- Install 4.3 stable monofgvm i latest --default- Install latest stable standard and set as defaultfgvm install 4.4.1 --with-templates- Install 4.4.1 stable standard and its export templates
- Queries:
fgvm godotorfgvm g[-i|--interactive] [-a|--attached] [-P|--project] [--query <string>] [--args <string>] runs the appropriate Godot version, or resolves the optional query against installed versions and launches that match. With the--interactiveor-iflag, it will prompt the user to launch an installed version, even if a query is supplied. When run in a project directory with a.fgvm-versionfile, it will use that project-specific version. If no.fgvm-versionfile exists, it will use the global default version. The command will automatically detect and launch the project if aproject.godotfile is found.- Once a version is installed, it will launch the editor with the project directly from the terminal.
- Use
--queryto launch a specific installed version, such asfgvm godot --query "4.6 mono"or the exact installed versionfgvm godot --query "4.6.2-stable-standard". - Optionally, pass in arguments to the Godot executable directly using
--argsfollowed by a separate value, such asfgvm godot --query "4.6 mono" --args "--headless"orfgvm godot --args "--version". Multiple arguments should be passed as a quoted string, such as--args "--headless -v". Do not use--args="..."; that form is rejected by the CLI parser. - Use
--projector-Pwith explicit arguments to add the detected project path, such asfgvm godot -P --args "--dump-extension-api --quit". - Use the
--attachedor-aflag to force Godot connected to the terminal for output; by default, Godot runs in detached mode and will launch in a separate instance. Using an argument detection system, certain arguments (like--version,--help,--headless) automatically trigger this mode since they would otherwise be useless without printing to standard out. - The command will only read existing
.fgvm-versionfiles for version selection, and does not create or modify version files. Usefgvm localto manage.fgvm-versionfiles.
fgvm set [<...strings>]prompts the user to set an installed version of Godot if no arguments are supplied, or will try to find the closest matching version based on the query, including release type (stable) and version (4,4.4), or an exact match (4.4.1-stable-mono).fgvm local [<...strings>]sets the Godot version for the current project by creating or updating a.fgvm-versionfile in the current directory. If no.fgvm-versionfile exists and no arguments are provided, it will automatically detect the project version fromproject.godotand install the most recent compatible version if not already installed.- If a list of arguments are provided, it will find the best matching version based on the query (including runtime preferences like
monoorstandard) and install it if necessary.
- If a list of arguments are provided, it will find the best matching version based on the query (including runtime preferences like
fgvm which[<...strings>]displays the executable path for the effective Godot installation in the current directory:.fgvm-versionfirst, then the global default. If query arguments are supplied, it resolves them against installed versions instead. The command prints only the executable path on success and exits non-zero when no version can be resolved.fgvm removeorfgvm r[<...strings>]prompts the user to select multiple installations to delete, or optionally takes a query to filter down to specific versions to delete. If there is only one match, it will delete it directly. If there are multiple matches, it will prompt the user to select which ones to delete.- For example, if you wanted to list all of the
4.y.zversions to remove, you could just dofgvm r 4to list all of the 4 major releases. However, if you remove a specific version, like4.4.1-stable-mono, it will just delete that version directly. Deleting the currently set version will unset it and you will need to set a new one.
- For example, if you wanted to list all of the
fgvm logs[--json] [-l|--level <string>] [-m|--message <string>] displays all of the logs, or optionally takes a level or message filter. Use--jsonto output in JSON format.fgvm searchorfgvm s[<...strings>][-j|--json] [-F|--no-cache] takes an optional query to search available Godot versions. Use--jsonor-jto output in JSON format, and--no-cacheor-Fto force a remote refresh instead of using the local release cache.- Queries:
4would filter all 4.x releases, including "stable", "dev", etc.4.2-rcwould only list the4.2rcreleases, but4.2 rcwould list all4.2.xreleases with thercrelease type, including4.2.2-rc3
- Queries:
fgvm templateorfgvm tmanages Godot export templates.fgvm template installorfgvm template i[<...strings>][--force] installs the official export template package for an installed Godot version. With no query, fgvm prompts from local Godot installations. With a query, it resolves against local Godot installations only, such asfgvm template install 4.4.1orfgvm template install 4.4.1 mono.fgvm template listorfgvm template l[-j|--json] lists installed export template directories.fgvm template removeorfgvm template r[<...strings>]removes installed export template directories. With no query, fgvm prompts from installed export templates. With a query, it removes the exact match directly or prompts when multiple installed templates match.- Template commands manage full official TPZ packages. They do not install or remove individual export target files inside a package.
Godot export templates are installed separately from fgvm-managed editor binaries. fgvm uses the same standard export template root that the Godot editor uses:
| Platform | Default export template root |
|---|---|
| Windows | %APPDATA%\Godot\export_templates |
| macOS | ~/Library/Application Support/Godot/export_templates |
| Linux/BSD | ${XDG_DATA_HOME:-~/.local/share}/godot/export_templates |
Installed template directories use Godot's template version format, such as 4.4.1.stable or 4.4.1.stable.mono.
Use install --with-templates when you want editor and template installation in one command:
fgvm install 4.4.1 --with-templatesUse template install when the editor is already installed:
fgvm template install 4.4.1
fgvm template list --json
fgvm template remove 4.4.1Template installation queries intentionally resolve against local Godot editor installations. This prevents installing export templates for a version you are not managing locally with fgvm.
fgvm supports project-specific version management through .fgvm-version files. Here's how it works:
# Navigate to your project directory
cd my-godot-project
# Option 1: Auto-detect version from project.godot
fgvm local # Detects version from project.godot, creates .fgvm-version
# Option 2: Explicitly set a version
fgvm local 4.3 mono # Creates .fgvm-version with 4.3-stable-mono# In a project directory with .fgvm-version file
fgvm godot # Uses version from .fgvm-version
# Or use short form
fgvm g # Same as above
# In a project directory without .fgvm-version file
fgvm godot # Uses global default version
# In any directory
fgvm godot -i # Interactive selection from installed versions
fgvm g -i # Same as abovefgvm local- Creates/updates.fgvm-versionfile for project-specific version managementfgvm godot(orfgvm g) - Respects.fgvm-versionfile if present, otherwise uses global defaultfgvm set- Sets the global default version used when no.fgvm-versionexists
-
FGVM_HOME: Customize the installation directory for fgvm. By default, fgvm uses~/fgvm/(macOS/Linux) or$env:USERPROFILE\fgvm\(Windows). Setting this variable allows you to use a different location:macOS/Linux:
# Temporary (current session only) export FGVM_HOME=/custom/path/fgvm fgvm list # Will use /custom/path/fgvm/ directly # Persistent (add to ~/.bashrc, ~/.zshrc, or ~/.profile) echo 'export FGVM_HOME=/custom/path/fgvm' >> ~/.bashrc
Windows:
# Temporary (current session only) $env:FGVM_HOME = "C:\custom\path\fgvm" fgvm list # Will use C:\custom\path\fgvm\ directly # Persistent (for current user) [System.Environment]::SetEnvironmentVariable('FGVM_HOME', 'C:\custom\path\fgvm', 'User')
This is particularly useful for testing, CI/CD environments, or keeping your Godot installations on a separate storage device for backup purposes.
Building the project requires the .NET 10 SDK. Publishing the Native AOT executable also requires the native compiler toolchain for the target platform: Visual Studio with the Desktop development with C++ workload on Windows, Xcode Command Line Tools on macOS, or Clang and the required development libraries on Linux. See the .NET Native AOT prerequisites for platform-specific setup.
Run dotnet run --project Fgvm.Cli -- <command> [args] during development, or publish a self-contained release binary for a specific runtime identifier:
git clone https://github.com/patricktcoakley/fgvm.git
cd fgvm
dotnet restore
dotnet publish Fgvm.Cli/Fgvm.Cli.csproj -c Release -r <RID>Use one of the release RIDs: win-x64, osx-x64, osx-arm64, linux-x64, or linux-arm64. The executable is written to Fgvm.Cli/bin/Release/net10.0/<RID>/publish/.
This repo also includes an optional mise setup for installing the expected .NET SDK and running common development tasks:
mise install
mise run restore
mise run build
mise run testThe mise tasks are the recommended way to run tests because they install the expected tool versions and prepare the integration and end-to-end fixtures:
mise install
mise run test
mise run test:e2eThe more specific tasks are also available:
mise run test:unit
mise run test:integration
mise run test:e2e:detailedWithout mise, install the .NET 10 SDK and PowerShell 7, make sure dotnet and pwsh are on your PATH, and run the equivalent preparation and test commands directly:
dotnet restore
dotnet test --configuration Release Fgvm.Tests/Fgvm.Tests.csproj
dotnet run Fgvm.Tests.Integration/Fixtures/PublishCli.cs
dotnet test --configuration Release Fgvm.Tests.Integration/Fgvm.Tests.Integration.csproj
dotnet run e2e/fixtures/BuildFixtures.cs
dotnet run Fgvm.Tests.Integration/Fixtures/PublishCli.cs --output e2e/.cli
pwsh -NoLogo -NoProfile -File e2e/run.ps1 -ParallelThis project uses Conventional Commits for commit messages and Versionize for automated versioning and changelog generation.
When making changes:
- Use conventional commit format:
type(scope): description. - Supported types:
feat,fix,docs,refactor,perf,test,chore,ci,build. - The changelog is automatically generated from these commits.
Example:
git commit -m "feat(environment): Added support for OpenBSD."Also please make sure to run mise run format before committing to ensure code style consistency.
See: https://github.com/patricktcoakley/fgvm
- Add releases for Windows on ARM64
- Create a GitHub Action to simplify using
fgvmin CI
If you were using this project in the past then you'll know it used to be called gdvm. Prior to this project's creation and after, there have been several other projects with similar goals using the same name.
In an effort to differentiate this project I decided to change the name to stand out, and am also using it as an opportunity to implement some breaking changes due to some recent updates in the libraries I am using to write this tool.
What this means for you:
gdvmandfgvmare mostly the same workflow but there were minor changes to the commands that are breaking, so consult the updated documentation if you get stuck- If you are using a package manager (the recommended way to install), you will have to remove the
gdvmpackage and installfgvm- Homebrew users:
brew update && brew uninstall gdvm && brew install fgvm - Scoop users:
scoop update && scoop uninstall gdvm && scoop install fgvm
- Homebrew users:
- If you want to keep your current installations, you can copy the existing
gdvmdirectory tofgvm, which will preserve everything. Here are some one-liners that copy them over and delete the gdvm folder:- macOS & Linux users:
mkdir -p ~/fgvm && cp -r ~/gdvm/* ~/fgvm/ && rm -rf ~/gdvm - Windows users:
mkdir -Force $env:USERPROFILE\fgvm ; cp -r $env:USERPROFILE\gdvm\* $env:USERPROFILE\fgvm\ ; rm -r -Force $env:USERPROFILE\gdvm - The old updater scripts have been replaced by the simpler install scripts, which install the standalone
fgvmbinary into~/fgvm/bin.
- macOS & Linux users: