English | 简体中文
xenv is a local development environment manager for SDK versions, environment variables, and PATH entries. It is designed for developers who switch between projects that need different toolchains or local runtime settings.
- Discover and activate locally installed SDKs, such as Go and Node.js.
- Manage global, project-local, and shell-session environment variables.
- Manage global, project-local, and shell-session
PATHentries. - Load project state from
.xenv.tomlwhen you enter a directory through the shell integration. - Check effective SDKs and project tool requirements.
- Generate shell hooks for bash, zsh, PowerShell, and cmd/clink.
Install by Eget:
eget install inhere/xenvInstall the latest version with Go:
go install github.com/inhere/xenv/cmd/xenv@latestEnable shell integration first. This lets xenv use, xenv set, and xenv path add update the current shell instead of only printing shell script output.
Bash:
eval "$(xenv shell --type bash)"Zsh:
eval "$(xenv shell --type zsh)"PowerShell:
Invoke-Expression (&xenv shell --type pwsh)Initialize the default configuration explicitly if you want to create it before first use:
xenv config initThe default configuration file is created at:
~/.config/xenv/config.yaml
Then index locally installed SDKs and activate a version:
xenv sdk index
xenv sdk list
xenv use go:latestSave project-local settings to .xenv.toml:
xenv use -s go:1.24
xenv set -s APP_ENV local
xenv path add -s ./binInspect status and run checks:
xenv status
xenv checkGenerate shell integration scripts:
xenv shell --type bash
xenv shell --type zsh
xenv shell --type pwsh
xenv shell --type cmdInstall the hook into your shell profile:
# PowerShell
xenv shell --install -t pwsh --profile $PROFILE.CurrentUserAllHosts
# bash or zsh
xenv shell --install -t $SHELLPowerShell can also load the hook directly:
Invoke-Expression (&xenv shell --type pwsh)
# or
xenv shell --type pwsh | Out-String | Invoke-ExpressionWhen shell integration is active, xenv keeps a shell-session state file and can automatically load matching .xenv.toml files when you change directories.
Most environment-changing commands support four scopes:
| Scope | Flag | Storage | Use case |
|---|---|---|---|
| Session | none | ~/.config/xenv/session/<session_id>.json |
Temporary changes for the current hooked shell |
| Project | -s, --save, or -d |
nearest .xenv.toml |
Project-specific SDKs, env vars, and paths |
| Global | -g or --global |
~/.config/xenv/global.toml |
Defaults shared by all projects |
| System | -S or --system |
OS user environment: HKCU\Environment on Windows, the shell startup file (~/.bashrc, ~/.zshrc) xenv block on Linux/macOS |
Values that must be visible to new processes without the xenv hook |
Examples:
# Current shell session
xenv use go:latest
xenv set APP_ENV local
xenv path add ./bin
# Project .xenv.toml
xenv use -s go:1.24
xenv set -s APP_ENV local
xenv path add -s ./bin
# Global state
xenv use -g go:1.24
xenv set -g GOPROXY https://proxy.golang.org,direct
xenv path add -g ~/.local/bin
# OS user environment
xenv set -S GOPROXY https://proxy.golang.org,direct
xenv unset -S GOPROXY
xenv path add -S ~/.local/bin
xenv path remove -S ~/.local/bin-S/--system can not be combined with -g/--global or -s/--direnv. New PATH entries are prepended, so they take priority. Run xenv from a hooked shell to also update the current shell immediately.
xenv run (alias exec) builds an SDK/ENV/PATH environment from options and runs a command inside it. Nothing is written to xenv state and no shell hook is required, so it also works from editors, CI runners and GUI-launched processes.
xenv run -u go:1.24,node:22 -p ./bin -e APP_ENV=local -- go build ./...
xenv exec -u go:1.24 --cwd D:/work/proj -- go test ./...
xenv run -u go --print -- go version| Option | Description |
|---|---|
-u, --use <spec,...> |
SDK specs to activate, repeatable and comma separated (go, go:1.24, go@1.24) |
-p, --path <dir> |
Directory prepended to PATH, repeatable |
-e, --env <KEY=VALUE> |
Environment variable to set, repeatable |
-c, --cwd <dir> |
Working directory for the command |
--print |
Print the resolved environment and command without running it |
Rules:
- ENV order: inherited environment, then SDK
active_env, then--env; the last value wins. - PATH order:
--pathentries, then SDK bin directories, then the inheritedPATH; duplicate entries are dropped and new entries win. - Options of the target command must be placed after
--, otherwise they are parsed asxenv runoptions. - The exit status is the child's status,
127when the command is not found and2forxenvside errors.
xenv status: Show current state for this directory and shell, including Effective State, Session Context, and Runtime State.xenv sdk list: List local SDK inventory.xenv env list: List xenv-managed environment variable state.xenv path list: List xenv-managedPATHstate.xenv check: Check whether Effective State and project tool requirements are satisfied.
Top-level xenv list / xenv ls is not kept in v0; use xenv status for state diagnostics.
Project state is stored in .xenv.toml. The shell hook can load it automatically when you enter the project directory.
Example:
paths = [
"./bin",
"windows:C:/Program Files (x86)/NSIS",
"linux:/opt/nsis/bin",
"darwin:/opt/homebrew/bin",
]
[sdks]
go = "1.24"
node = "20"
flutter = "windows:3.27"
[envs]
APP_ENV = "local"
[tools]
rg = "*"
golangci-lint = ">=1.60,required"Sections:
paths: Project-local entries added toPATH. Prefix an entry withwindows:,linux:, ordarwin:to load it only on that OS; the prefix is stripped before adding it toPATH.sdks: SDK versions activated for the project. Prefix a version withwindows:,linux:, ordarwin:to activate it only on that OS; the prefix is stripped before version matching.envs: Environment variables loaded for the project.tools: External tool requirements checked byxenv check tools.
SDKs are configured in config.yaml, then indexed from local installation directories.
Common commands:
xenv sdk index
xenv sdk list
xenv sdk list --all
xenv sdk show go
xenv sdk where go:1.24
xenv sdk where --bin go:1.24
xenv sdk which go:1.24Version specs can use either name:version or name@version:
xenv use go:1.24
xenv use node@20When the version is omitted, latest is used:
xenv use goActivate or deactivate multiple SDKs at once:
xenv use go:1.24 node:20
xenv unuse go:1.24 node:20List environment variables managed by xenv:
xenv env
xenv env listSet and unset values:
xenv env set APP_ENV local
xenv env unset APP_ENVTop-level shortcuts are also available:
xenv set APP_ENV local
xenv unset APP_ENVUse -s for project state or -g for global state:
xenv set -s APP_ENV local
xenv unset -g GOPROXYUse -S to write to the OS user environment, so new processes read the value without the xenv hook:
xenv set -S GOPROXY https://proxy.golang.org,direct
xenv unset -S GOPROXYOn Windows the value is written to HKCU\Environment; on Linux/macOS it is written to the xenv block of ~/.bashrc or ~/.zshrc. -S can not be combined with -g or -s.
List the OS user environment variables in addition to the xenv-managed state:
xenv env list -SList managed PATH entries:
xenv path
xenv path listAdd, remove, and search entries:
xenv path add ./bin
xenv path remove ./bin
xenv path search goUse -s for project state or -g for global state:
xenv path add -s ./bin
xenv path add -g ~/.local/binUse -S to add or remove an entry in the OS user PATH:
xenv path add -S ~/.local/bin
xenv path remove -S ~/.local/binThe entry is prepended, and the original value type and %VAR% references are preserved on Windows. Adding or removing a path that does not change anything fails with a message instead of writing a duplicate entry.
List the OS user PATH entries in addition to the xenv-managed state:
xenv path list -SRun all checks:
xenv checkCheck SDK availability for Effective State:
xenv check sdkCheck project tool requirements from .xenv.toml:
xenv check toolsTool requirements live under [tools]:
[tools]
rg = "*"
golangci-lint = ">=1.60,required"Default files:
~/.config/xenv/config.yaml
~/.config/xenv/global.toml
~/.config/xenv/session/<session_id>.json
~/.config/xenv/sdks.local.json
~/.config/xenv/hooks
Show the active configuration summary:
xenv configRead selected configuration values:
xenv config get bin_dir
xenv config get shell_hooks_dirExport configuration:
xenv config export zip
xenv config export jsonConfiguration files support environment variable expansion in values, for example ${HOME} or ${XENV_SDK_ROOT}.
Example config.yaml:
bin_dir: "~/.local/bin"
eget_enable: false
eget_store_file: ""
check_tools_on_direnv: false
source_project_scripts: false
allow_up_match: 1
shell_hooks_dir: "~/.config/xenv/hooks"
global_env: {}
global_paths: []
sdks:
- name: go
alias: golang
install_dir: "${XENV_SDK_ROOT}/go{version}"
bin_dir: "bin"
active_env:
GOROOT: "{install_dir}"
- name: node
install_dir: "${XENV_SDK_ROOT}/node-v{version}"
bin_dir: "bin"SDK fields:
| Field | Description |
|---|---|
name |
SDK name used in commands, such as go |
alias |
Optional alias for display or lookup |
install_dir |
SDK installation directory template; {version} is replaced by the selected version and is used to strictly match indexed directory names; {anyword} matches one non-empty path-name segment |
bin_dir |
SDK binary directory relative to install_dir |
active_env |
Environment variables exported when the SDK is active |
other_versions |
Additional versions that should be considered by the SDK index |
| Command | Description |
|---|---|
xenv sdk index |
Scan configured SDK directories and update the local SDK index |
xenv sdk list |
List installed SDKs |
xenv sdk list --all |
List all configured SDKs, including uninstalled ones |
xenv sdk show <name> |
Show details for one SDK |
xenv sdk where [--bin] <name:version> |
Print an SDK installation or binary path |
xenv use [-g] [-s] <name:version>... |
Activate SDK versions |
xenv unuse [-g] [-s] <name:version>... |
Deactivate SDK versions |
xenv env list |
List managed environment variables, -S also lists the OS user environment |
xenv env set [-g] [-s] [-S] <name> <value> |
Set an environment variable |
xenv env unset [-g] [-s] [-S] <name...> |
Remove environment variables |
xenv path list |
List managed PATH entries, -S also lists the OS user PATH |
xenv path add [-g] [-s] [-S] <path> |
Add a PATH entry |
xenv path remove [-g] [-s] [-S] <path> |
Remove a PATH entry |
xenv path search <value> |
Search current PATH entries |
xenv run [-u spec,...] [-p dir] [-e KEY=VALUE] [-c dir] [--print] -- <cmd> [args...] |
Run a command with a one-shot environment |
xenv status |
Show Effective State for the current directory |
xenv status --layers |
Show Global State, Directory State, and Session Context layers |
xenv status --runtime |
Show Runtime State detection details when implemented |
xenv check |
Run SDK and tool checks |
xenv check sdk |
Check SDK availability for Effective State |
xenv check tools |
Check project tool requirements |
xenv shell --type <shell> |
Print shell hook script |
xenv shell --install -t <shell> |
Install shell hook into a shell profile |
xenv config |
Show configuration summary |
xenv config get <name> |
Read a supported configuration value |
xenv config export <zip|json> |
Export configuration |
Aliases:
xenv sdksforxenv sdkxenv stforxenv statusxenv eforxenv envxenv pforxenv pathxenv cfgforxenv configxenv sdk refreshorxenv sdk scanforxenv sdk indexxenv sdk whichforxenv sdk wherexenv path rmorxenv path deleteforxenv path remove
Run tests:
go test ./...Build without release compression:
go build ./cmd/xenvBuild with the project Makefile:
make buildThe Makefile uses UPX for compression on supported targets, so upx must be available for those build targets.