tfv
v6.1.4
Published
Terraform & OpenTofu version manager
Maintainers
Readme
tfv — Terraform & OpenTofu Version Manager for macOS, Linux & Windows
_ ________ __
_| |__ / _____|\ \ / /
|_ ___\ | |___ \ \ / /
| | | ___| \ \ / /
| |___ | | \ \/ /
\______\_| \__/
Happy terraforming! 😍🥂
---------------------------------tfv lets you install, switch, and manage multiple versions of Terraform and OpenTofu without sudo. All binaries live in ~/.tfv/ — upgrading tfv itself never wipes your installed versions.

Installation
npm install -g tfvtfv automatically adds ~/.tfv/bin to your PATH on install (shell configs + Windows User PATH). Restart your terminal once after install.
How it works
npm install -g tfv
│
▼
postInstall.js
├── creates ~/.tfv/bin/, ~/.tfv/store/, ~/.tfv/cache/
└── adds ~/.tfv/bin to PATH (shell configs / Windows registry)
│
▼
tfv install 1.9.0
├── fetches version list → ~/.tfv/cache/terraform-versions.json (1hr TTL)
├── downloads zip → system temp dir (with progress bar)
├── verifies SHA256 → HashiCorp / OpenTofu checksums
├── extracts binary only → ~/.tfv/store/terraform/1.9.0
└── records arch → ~/.tfv/store/terraform/arch.json
│
▼
tfv use 1.9.0
├── copies ~/.tfv/store/terraform/1.9.0 → ~/.tfv/bin/terraform
└── writes active version → ~/.tfv/active.json
│
▼
terraform plan ← resolves to ~/.tfv/bin/terraform (same binary as tfv)
tfv plan ← spawns ~/.tfv/bin/terraform directly (no PATH lookup)Both terraform and tfv commands always use the exact same binary.
Store layout
~/.tfv/
bin/
terraform ← active terraform binary (no sudo, no symlinks)
tofu ← active opentofu binary
store/
terraform/
1.9.0 ← installed versions (binary renamed to version number)
1.7.3
arch.json ← { "1.9.0": "arm64", "1.7.3": "amd64" }
opentofu/
1.8.0
arch.json
cache/
terraform-versions.json ← remote list cached for 1 hour
opentofu-versions.json
active.json ← { "terraform": "1.9.0", "opentofu": null }Commands
Install
tfv install latest # latest stable
tfv install 1.9.0 # exact version
tfv install 1.9.^ # latest 1.9.x patch
tfv install 1.8.0-beta1 # explicit pre-release (warns you)
tfv install latest --provider tofu # OpenTofu
tfv install 1.9.0 --arch amd64 # override architectureAliases: tfv i
Switch version
tfv use 1.9.0
tfv use latest # latest installed version
tfv use 1.8.0 --provider tofuNo sudo. Copies binary to ~/.tfv/bin/terraform.
Auto-switch
Detects and switches to the version your project requires. Installs it if not already in store.
tfv auto-switch
tfv as # alias
tfv as --provider tofuReads version from (in priority order):
.terraform-versionfile in current directoryterraform.tfstate→terraform_versionfieldrequired_versionin any.tffile — supports all constraint operators:=,>=,>,<=,<,!=,~>, and compound">= 1.3, < 2.0"
Shell hook — auto-switch on cd
Wraps cd so that entering a directory automatically switches the terraform version — but only if the directory looks like a terraform project. Non-terraform folders have zero overhead (one filesystem check, no subprocess).
A directory is considered a terraform project if it contains:
- a
.terraform-versionfile, or - any
*.tffiles
cd ~/Downloads # no .tf files → nothing happens
cd ~/projects/react-app # no .tf files → nothing happens
cd ~/projects/infra # has main.tf → auto-switch runs silently
cd ~/projects/platform # has .terraform-version → auto-switch runs silentlySetup (one-time, add to your shell config):
# Bash
printf '\neval "$(tfv shell-init bash)"\n' >> ~/.bashrc
# Zsh
printf '\neval "$(tfv shell-init zsh)"\n' >> ~/.zshrc
# Fish
printf '\ntfv shell-init fish | source\n' >> ~/.config/fish/config.fish
# PowerShell
Add-Content $PROFILE "`nInvoke-Expression (tfv shell-init powershell | Out-String)"After setup, entering a terraform project switches the version automatically — no manual tfv as needed.
shell-init also installs tab completions for all tfv commands and installed versions. After running the setup command above, tfv <tab> will complete commands, tfv use <tab> will complete installed versions, and tfv --provider <tab> will complete provider names.
List versions
tfv list # installed versions (default)
tfv ls --remote # all available versions from HashiCorp
tfv ls --remote --provider tofu # all available OpenTofu versionsActive version is marked with 🚀.
Current version
tfv current # shows active version + PATH status
tfv which # alias
tfv current --provider tofuExample output:
Active terraform version: 1.9.0
Binary: /Users/you/.tfv/bin/terraform
Reported: Terraform v1.9.0
PATH OK — 'terraform' resolves to tfv-managed binaryPin version
Writes a .terraform-version file in the current directory so teammates get the same version via tfv auto-switch:
tfv pin # pin currently active version
tfv pin 1.9.0 # pin a specific version
tfv pin --provider tofuUpgrade
tfv upgrade # upgrade active 1.6.3 → latest 1.6.x patch
tfv upgrade 1.9 # install + use latest 1.9.x
tfv upgrade latest # install + use absolute latest
tfv upgrade --provider tofuAlso re-anchors ~/.tfv/bin in PATH to ensure it takes precedence over any system-installed terraform.
Remove
tfv remove 1.7.3
tfv rm 1.7.3 1.6.6 # remove multiple
tfv rm 1.8.0 --provider tofuWarns if you're removing the currently active version.
Prune
Remove all non-active versions at once to free disk space.
tfv prune # remove everything except the active version
tfv prune --keep 2 # keep the 2 most recent + the active version
tfv prune --provider tofu
tfv prune --yes # skip confirmation promptThe active version is always kept regardless of --keep.
Exec
Run a single command with a specific installed version without changing the active version. Useful for cross-version testing and CI.
tfv exec 1.9.0 -- version
tfv exec 1.8.0 -- plan -var="env=prod"
tfv exec 1.7.3 --provider tofu -- validatePass all terraform/tofu flags after --.
Doctor
Run a full health check: store directories, active binaries, PATH order, PATH conflicts, and shell config.
tfv doctorExample output:
tfv doctor
Store
✔ ~/.tfv/store/terraform/ exists
✔ ~/.tfv/store/opentofu/ exists
Active versions
✔ terraform: active version is 1.9.0
✔ terraform: binary exists
✔ terraform: executes (Terraform v1.9.0)
– tofu: not set up (no versions installed)
PATH
✔ ~/.tfv/bin is in PATH
✔ ~/.tfv/bin precedes system dirs in PATH
✔ 'terraform' resolves to tfv-managed binary
✔ PATH block found in shell config (~/.zshrc)
Cache
✔ terraform version cache exists
– opentofu version cache not yet created
All checks passed. tfv is healthy.Exits with code 1 if any issue is found.
Terraform commands (via tfv)
All commands use the tfv-managed binary and accept extra terraform flags after --:
tfv init
tfv validate
tfv fmt
tfv fmt -- -recursive
tfv plan
tfv plan --file main.tf # extract targets from file
tfv plan --file main.tf --file network.tf # multiple files
tfv plan --file main.tf -- -var="env=prod" # with extra terraform flags
tfv apply --file main.tf -- -auto-approve
tfv destroy --file main.tf -- -auto-approve--file parses .tf files and auto-generates -target flags for every resource, data, and module block found. Comments are stripped before parsing.
All commands support --provider tofu to use OpenTofu instead.
OpenTofu support
Every command works with OpenTofu via --provider tofu (or --provider opentofu):
tfv install latest --provider tofu
tfv use 1.8.0 --provider tofu
tfv list --remote --provider tofu
tfv current --provider tofu
tfv plan --provider tofuOpenTofu binaries are stored separately from Terraform in ~/.tfv/store/opentofu/ and activated as ~/.tfv/bin/tofu.
Windows support
Everything works on Windows without administrator privileges:
- Store:
%USERPROFILE%\.tfv\ - PATH: updated via
[Environment]::SetEnvironmentVariable("PATH", ..., "User")(User scope, no admin) - Shell hooks: PowerShell profile integration via
tfv shell-init powershell
Help
tfv --help
tfv <command> --help