A CLI tool for managing environment variable profiles with seamless shell integration.
- Profile-based environment management: Switch between different sets of environment variables with a single command
- Clean profile switching: Old profile variables are automatically unset when switching to a new profile
- Multi-shell support: Works with bash, zsh, and fish
- Simple configuration: TOML-based config file in
~/.setenv/config.toml - No environment pollution: Only manages variables it sets, leaves your other env vars untouched
# 1. Install the binary
cargo install setenv-cli
# 2. Run the automatic wrapper installer
curl -fsSL https://raw.githubusercontent.com/joeyism/setenv-cli/master/install-wrapper.sh | bash
# 3. Reload your shell (or restart terminal)
source ~/.bashrc # or ~/.zshrc for zshFor bash/zsh users:
# 1. Install the binary
cargo install setenv-cli
# 2. Add wrapper function to ~/.bashrc (or ~/.zshrc)
cat >> ~/.bashrc << 'EOF'
# setenv shell wrapper
setenv() {
if [ $# -eq 0 ] || [ "$1" = "list" ] || [ "$1" = "current" ] || [ "$1" = "edit" ] || [ "$1" = "new" ] || [ "$1" = "add" ] || [ "$1" = "help" ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
command setenv "$@"
else
eval "$(command setenv "$@")"
fi
}
EOF
# 3. Reload your shell
source ~/.bashrcNow you can use: setenv <profile-name>
If you have Rust installed:
cargo install setenv-cliDownload the latest release for your platform from the releases page:
- Linux (x86_64):
setenv-linux-amd64 - Linux (musl):
setenv-linux-amd64-musl - macOS (Intel):
setenv-macos-amd64 - macOS (Apple Silicon):
setenv-macos-arm64 - Windows:
setenv-windows-amd64.exe
Then move it to your PATH:
# Linux/macOS
sudo mv setenv-* /usr/local/bin/setenv
sudo chmod +x /usr/local/bin/setenv
# Windows
# Move setenv-windows-amd64.exe to a directory in your PATHgit clone https://github.com/joeyism/setenv-cli.git
cd setenv-cli
cargo build --release
sudo cp target/release/setenv /usr/local/bin/setenv will only print commands but won't actually set variables.
The tool outputs shell commands that need to be evaluated in your current shell. Add this wrapper function to your shell config:
Add to your ~/.bashrc:
source /path/to/setenv-cli/wrappers/setenv.bashOr copy the function directly:
setenv() {
if [ $# -eq 0 ] || [ "$1" = "list" ] || [ "$1" = "current" ] || [ "$1" = "edit" ] || [ "$1" = "new" ] || [ "$1" = "add" ] || [ "$1" = "help" ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
command setenv "$@"
else
eval "$(command setenv "$@")"
fi
}Add to your ~/.zshrc (same as bash):
source /path/to/setenv-cli/wrappers/setenv.bashAdd to your ~/.config/fish/config.fish:
source /path/to/setenv-cli/wrappers/setenv.fishOr copy the function directly:
function setenv
set -l cmd $argv[1]
if test (count $argv) -eq 0; or test "$cmd" = "list"; or test "$cmd" = "current"; or test "$cmd" = "edit"; or test "$cmd" = "new"; or test "$cmd" = "add"; or test "$cmd" = "help"; or test "$cmd" = "--help"; or test "$cmd" = "-h"
command setenv $argv
else
eval (command setenv $argv)
end
endAfter adding the wrapper, reload your shell:
source ~/.bashrc # for bash
source ~/.zshrc # for zsh
source ~/.config/fish/config.fish # for fishThe config file is located at ~/.setenv/config.toml. It will be created automatically on first run with a default profile.
[profiles.default]
EXAMPLE_VAR = "example_value"
ANOTHER_VAR = "another_value"
[profiles.backend]
API_KEY = "backend-api-key"
DB_HOST = "backend.database.com"
DB_PORT = "5432"
DEBUG = "true"
[profiles.frontend]
API_KEY = "frontend-api-key"
API_URL = "https://api.example.com"
NODE_ENV = "development"- Must start with a letter or underscore
- Can contain only letters, numbers, and underscores
- Cannot use reserved names:
SETENV_VARS,SETENV_PROFILE
- Can contain alphanumeric characters, underscores, and dashes
- Cannot contain spaces or special characters
⚠️ Before using: Make sure you've completed both installation steps (binary + shell wrapper). If you only installed the binary, variables won't actually be set. See Troubleshooting if you're seeing export commands instead of set variables.
setenv backendThis will:
- Unset all variables from the previous profile
- Set all variables from the
backendprofile - Update
SETENV_PROFILEandSETENV_VARStracking variables
setenv listOutput shows all profiles, with * marking the currently active one:
Available profiles:
* backend
default
frontend
setenv currentsetenv editOpens the config file in your $EDITOR (falls back to vim, vi, or nano).
setenv new <profile-name>Creates a new empty profile. Example:
setenv new productionsetenv add <profile-name> <KEY> <VALUE>Adds or updates a variable in an existing profile. Example:
setenv add production API_KEY "prod-api-key-123"
setenv add production DB_HOST "prod.database.com"When you switch profiles, setenv ensures a clean transition:
- Tracks managed variables: The tool stores which variables it manages in the
SETENV_VARSenvironment variable - Unsets old variables: Before switching, all variables from the previous profile are unset
- Sets new variables: Variables from the new profile are then exported
- Updates tracking:
SETENV_PROFILEandSETENV_VARSare updated
This ensures no variable "leakage" between profiles while leaving your other environment variables untouched.
Starting state:
$ echo $MY_VAR
my_valueSwitch to backend profile:
$ setenv backend
$ echo $API_KEY
backend-api-key
$ echo $MY_VAR
my_value # Your original vars are untouchedSwitch to frontend profile:
$ setenv frontend
$ echo $API_KEY
frontend-api-key # Changed to frontend value
$ echo $DB_HOST
# Backend's DB_HOST was unset
$ echo $MY_VAR
my_value # Still untouchedMake sure:
- The binary is in your PATH
- You've added the shell wrapper to your shell config
- You've reloaded your shell configuration
Check your config file:
setenv list # See available profiles
setenv edit # Edit config if neededSymptom: When you run setenv <profile>, you see output like:
export API_KEY="value"
export DB_HOST="localhost"
...But the variables aren't actually set in your shell.
Cause: You haven't set up the shell wrapper function (Step 2 of installation).
Solution: Add the wrapper function to your shell config and reload:
# For bash, add to ~/.bashrc:
setenv() {
if [ $# -eq 0 ] || [ "$1" = "list" ] || [ "$1" = "current" ] || [ "$1" = "edit" ] || [ "$1" = "new" ] || [ "$1" = "add" ] || [ "$1" = "help" ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
command setenv "$@"
else
eval "$(command setenv "$@")"
fi
}
# Then reload
source ~/.bashrcThe wrapper is required because the binary can only output commands - it can't directly modify your shell's environment. The wrapper uses eval to execute those commands in your current shell.
If your config file has syntax errors:
setenv edit # Fix the TOML syntaxCommon issues:
- Missing quotes around values with spaces
- Invalid variable names (must start with letter/underscore)
- Using reserved names (
SETENV_VARS,SETENV_PROFILE)
cargo testcargo buildcargo run -- <args>Note: Without the shell wrapper, this will only print the commands, not execute them.
MIT