Skip to main content
Screenshot 2026-08-18 at 20 58 54

Lightweight Virtual Environment Manager for Python

Refract centralizes your Python virtual environments in a single location, providing simple commands to create, manage, and switch between project contexts—without the complexity of traditional virtual environment tools.

Demo

refract demo

Features

  • Centralized Management: All environments stored in ~/.refract/envs/
  • Simple Commands: Intuitive syntax that's easy to remember
  • Global Access: Use refract from anywhere in your system
  • Zero Dependencies: Only requires Python standard library
  • Seamless Switching: Instant environment activation with new shell sessions
  • Colored Prompts: Clear visual indication of active environment in shell prompt
  • Clean Organization: Automatic directory structure management

Table of Contents

Installation

Refract itself depends only on Python's standard library. The refract command and refract install (shell integration) are separate steps.

macOS and Linux only. Windows is not supported.

Prerequisites

  • Python 3.10 or higher
  • bash or zsh

pip is optional. pipx is optional.

From source (Python 3 only)

Best for minimal servers that may not have pip:

git clone git@github.com:YakShavingCatHerder/refract.git
cd refract
./install.sh
source ~/.zshrc    # bash: source ~/.bashrc

This copies refract.py to ~/.local/bin/refract, then runs refract install.

From source with pip

git clone git@github.com:YakShavingCatHerder/refract.git
cd refract
./install.sh --pip
source ~/.zshrc    # bash: source ~/.bashrc

From source with pipx (optional)

./install.sh --pipx
source ~/.zshrc    # bash: source ~/.bashrc

From PyPI

The distribution name is refract-venv. The command is refract.

pip install refract-venv
refract install
source ~/.zshrc    # bash: source ~/.bashrc

If you already use pipx for CLI tools:

pipx install refract-venv
refract install
source ~/.zshrc    # bash: source ~/.bashrc

What refract install does

  • Creates ~/.refract/ and refract.json (default colorway: green/black)
  • Installs prompt integration in ~/.zshrc and ~/.bashrc
  • Installs the shell wrapper in both files (reloads after refract colorway)
  • Tells you to restart or source your shell

It does not install the refract executable. Re-running it is idempotent: existing snippets are updated, not duplicated.

Uninstall

From a source checkout:

./uninstall.sh

If you installed the package:

pip uninstall refract-venv
# or: pipx uninstall refract-venv

Virtual environments in ~/.refract/envs/ are left in place. Remove them with rm -rf ~/.refract.

Quick Start

After installation, you can immediately start using refract:

# Create your first environment
refract init myproject

# List all environments
refract list

# Activate an environment
refract use myproject

# Remove an environment when done
refract rm myproject

Commands Reference

refract init <name>

Creates a new virtual environment with the specified name.

Parameters:

  • environment_name: Must be a valid Python identifier (letters, numbers, underscores only)

Example:

$ refract init django_project
Created new virtualenv at /path/to/.refract/envs/django_project

What happens:

  • Creates a new virtual environment in ~/.refract/envs/<name>/
  • Uses Python's built-in venv module
  • Validates the environment name format
  • Prevents duplicate environment creation

refract list

Displays all available virtual environments.

Example Output:

$ refract list
Available virtualenvs:
  * django_project
  * flask_api
  * data_analysis
  * machine_learning

What happens:

  • Scans ~/.refract/envs/ directory
  • Lists all subdirectories as available environments
  • Shows helpful message if no environments exist

refract use <name>

Activates the specified virtual environment by opening a new shell session.

Example:

$ refract use django_project
[refract] Switching to environment 'django_project'...

What happens:

  1. Validates the environment exists
  2. Creates a temporary activation script that:
  • Sources your shell profile files (.bash_profile, .zshrc, etc.)
  • Activates the virtual environment
  • Opens a new shell session with the environment active
  • Sets up colored prompt showing the active refract environment with [refract:name] prefix
  1. Runs the script in a new shell process
  2. Removes the temporary script as a cleanup process

After activation, you'll see:

[refract:django_project] user@machine ~ %

refract rm <name>

Removes the specified virtual environment.

Example:

$ refract rm old_project
Removed environment 'old_project'

What happens:

  • Validates the environment exists
  • Completely removes the environment directory
  • Provides confirmation message

refract current

Shows the currently active refract environment.

Example:

$ refract current
Currently in refract environment: django_project

What happens:

  • Checks for the REFRACT_ENV environment variable
  • Displays the active environment name in light gray if one is active
  • Shows "No refract environment currently active" if none is active

refract install

Initializes Refract config and shell integration. The executable must already be on your PATH (via ./install.sh, pip, or pipx).

What happens:

  • Creates ~/.refract/ and refract.json if needed
  • Writes prompt hooks and the shell wrapper into ~/.zshrc and ~/.bashrc
  • Does not create a symlink or install the refract command

Usage Examples

Example 1: Web Development Workflow

# Create environments for different projects
$ refract init frontend
Created new virtualenv at /Users/path/.refract/envs/frontend

$ refract init backend
Created new virtualenv at /Users/path/.refract/envs/backend

# List all environments
$ refract list
Available virtualenvs:
  * frontend
  * backend

# Switch to frontend work
$ refract use frontend
[refract] Switching to environment 'frontend'...

# In the new shell session:
[refract:frontend] $ npm install
[refract:frontend] $ npm start

# Switch to backend work (in another terminal)
$ refract use backend
[refract] Switching to environment 'backend'...

# In the new shell session:
[refract:backend] $ pip install django
[refract:backend] $ python manage.py runserver

Example 2: Data Science Workflow

# Create specialized environments
$ refract init data_analysis
$ refract init ml_experiment
$ refract init visualization

# Switch between different analysis contexts
$ refract use data_analysis
[refract:data_analysis] $ pip install pandas numpy matplotlib

$ refract use ml_experiment
[refract:ml_experiment] $ pip install scikit-learn tensorflow

$ refract use visualization
[refract:visualization] $ pip install plotly seaborn bokeh

Example 3: Project Cleanup

# List all environments
$ refract list
Available virtualenvs:
  * old_project
  * experiment_1
  * experiment_2
  * current_project

# Remove completed experiments
$ refract rm experiment_1
Removed environment 'experiment_1'

$ refract rm experiment_2
Removed environment 'experiment_2'

# Verify cleanup
$ refract list
Available virtualenvs:
  * old_project
  * current_project

Directory Structure

Refract creates and manages the following structure:

~/.refract/
├── envs/                    # All virtual environments
│   ├── project_a/
│   │   ├── bin/
│   │   ├── lib/
│   │   └── ...
│   ├── project_b/
│   │   ├── bin/
│   │   ├── lib/
│   │   └── ...
│   └── ...
└── refract.json            # Configuration file

Colored Prompts Feature

Refract automatically modifies your shell prompt to show the active environment:

  • Format: [refract:environment_name] appears at the beginning of your prompt
  • Color: Green background with black text by default to make current venv easily visible
  • Shell Support: Works with both bash and zsh
  • Environment Variable: Sets REFRACT_ENV for programmatic access

Troubleshooting

Common Issues

"command not found: refract"

Problem: The refract command isn't available globally.

Solution:

# From a source checkout, install the command then shell integration
./install.sh

# If the command exists but shell hooks do not
refract install

# Make sure ~/.local/bin is on PATH
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Refract environment is active, but prompt prefix is missing

Problem: refract use <name> activates the environment, but [refract:<name>] is not shown in your prompt.

Why this happens: Some shell themes/frameworks rebuild the prompt and can override custom prompt text.

How to verify activation:

echo $REFRACT_ENV
which python

If active, REFRACT_ENV should contain your environment name and which python should point to ~/.refract/envs/<name>/bin/python.

"Permission denied: refract"

Problem: The installed script does not have execute permissions.

Solution:

chmod +x ~/.local/bin/refract

"Environment 'name' does not exist"

Problem: Trying to use an environment that hasn't been created.

Solution:

# Check available environments
refract list

# Create the environment first
refract init name

"Environment name must be a valid identifier"

Problem: Using invalid characters in environment names.

Solution: Use only letters, numbers, and underscores:

#  Valid names
refract init my_project
refract init project123
refract init _private

#  Invalid names
refract init my-project    # hyphens not allowed
refract init "my project"  # spaces not allowed
refract init my.project    # dots not allowed

Debug Mode

Enable debug output to troubleshoot issues:

refract --debug list

This will show additional information about paths and configuration.

Manual Environment Management

If you need to manually manage environments:

# List all environments
ls ~/.refract/envs/

# Remove an environment manually
rm -rf ~/.refract/envs/environment_name

# Check refract configuration
cat ~/.refract/refract.json

Contributing

Development Setup

  1. Clone the repository
  2. Install from source:
    ./install.sh --pip
    

Testing

CLI tests use a temporary HOME and require refract on PATH (install the wheel or run ./install.sh --pip first):

python -m unittest discover -s tests -v -p 'test_cli.py'

./install.sh methods are tested in CI with REFRACT_TEST_INSTALL_SH=1.

Regenerate the README GIF with VHS:

./demo/record.sh

Code Style

  • Follow PEP 8 guidelines
  • Use descriptive variable names
  • Add docstrings to functions
  • Include error handling

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Built with 1 dependency: Python's standard library
  • Inspired by the need for simpler, cli-native management of virtual environments; perfect for deploying to lightweight servers when needed
  • Thanks to the Python community for the excellent venv module; this isn't a diss, just a specific use-case ;)

**Happy coding with refract! **

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

refract_venv-0.1.0.tar.gz (16.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

refract_venv-0.1.0-py3-none-any.whl (10.7 kB view details)

Uploaded Python 3

File details

Details for the file refract_venv-0.1.0.tar.gz.

File metadata

  • Download URL: refract_venv-0.1.0.tar.gz
  • Upload date:
  • Size: 16.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for refract_venv-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0afac20286c80e7010c49e27dc85815d47de92050db1f680e5f7567aa632dbe5
MD5 8ba3ca5b4611b3e580d8fa22f65531e7
BLAKE2b-256 4c8d464df98f18f4481026d380913c14212f481132388dfcbb653054a2cec6af

See more details on using hashes here.

Provenance

The following attestation bundles were made for refract_venv-0.1.0.tar.gz:

Publisher: release.yml on YakShavingCatHerder/refract

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file refract_venv-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: refract_venv-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for refract_venv-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2b38b2e26f22fd0caff0979ce0abd69420c39a8f0a692e475def493ad0f15998
MD5 49ea7d641991c041c11eb253cba4b857
BLAKE2b-256 fe0daef66609bfb4b9eb5bef67b1a0d43bb7ab706c1e777b928c3cea2882f931

See more details on using hashes here.

Provenance

The following attestation bundles were made for refract_venv-0.1.0-py3-none-any.whl:

Publisher: release.yml on YakShavingCatHerder/refract

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page