Shared global environment package installer using symlinks — like pnpm for Python
Project description
pepip
Alternative to "conda" to share each dependency version in a shared global environment to save storage space
Overview
pepip (performance pip) solves a common pain point in Python development: each project typically has its own virtual environment, so large packages like torch or transformers are downloaded and stored multiple times — once per project.
pepip takes inspiration from pnpm for Node.js:
- Packages are installed once into a single shared global virtual environment (
~/.pepip/global-venv), usinguvfor fast downloads. - Inside each project's
.venv, symlinks point back to the global copies, so Python can import the packages as normal. - Re-installing a package that is already in the global environment is near-instant — no download required.
Requirements
- Python 3.8+
uv— installed automatically as a dependency
Installation
pip install pepip
Usage
Install packages
# Install one or more packages
pepip install numpy pandas
# Install from a requirements file
pepip install -r requirements.txt
# Use a custom local venv path (default: .venv)
pepip install numpy --venv /path/to/my-env
After running pepip install, a .venv directory is created (or updated) in the current directory. Activate it as usual:
source .venv/bin/activate
python -c "import numpy; print(numpy.__version__)"
How it works
~/.pepip/
└── global-venv/
└── lib/
└── python3.12/
└── site-packages/
├── numpy/ ← real package files (downloaded once)
├── numpy-2.0.dist-info/
├── torch/
└── ...
my-project/
└── .venv/
└── lib/
└── python3.12/
└── site-packages/
├── numpy -> ~/.pepip/global-venv/lib/.../numpy (symlink)
├── numpy-2.0.dist-info -> ... (symlink)
└── ...
The global environment path can be overridden via the PEPIP_HOME environment variable:
PEPIP_HOME=/shared/team-env pepip install torch
Development
# Clone and install in editable mode
git clone https://github.com/perf-pip/pepip
cd pepip
pip install -e .
# Run tests
pip install pytest
pytest
Evaluation — pepip vs uv
The eval/benchmark.py script measures installation latency and disk usage
when setting up N projects with the same packages, comparing pepip against a
plain uv workflow.
# 3 projects, default packages (tomli, packaging)
python eval/benchmark.py
# 5 projects, larger dependency set
python eval/benchmark.py --projects 5 --packages requests certifi charset-normalizer idna urllib3
# Keep the temp directories for manual inspection
python eval/benchmark.py --no-cleanup
Sample results (3 projects, packages: tomli packaging)
┌──────────────┬─────────────────┬─────────────┬──────────────────────┐
│ pepip vs uv — evaluation (3 project(s), packages: tomli packaging) │
├──────────────┬─────────────────┬─────────────┬──────────────────────┤
│ Metric │ uv (baseline) │ pepip │ Improvement │
├──────────────┼─────────────────┼─────────────┼──────────────────────┤
│ Latency │ 0.34 s │ 0.35 s │ +3.5 % │
│ Disk usage │ 2.98 MB │ 1.10 MB ★ │ -63.2 % │
└──────────────┴─────────────────┴─────────────┴──────────────────────┘
★ = better result
Sample results (5 projects, packages: requests certifi charset-normalizer idna urllib3)
┌──────────────┬─────────────────┬─────────────┬───────────────────────────────────────────────────────┐
│ pepip vs uv — evaluation (5 project(s), packages: requests certifi charset-normalizer idna urllib3) │
├──────────────┬─────────────────┬─────────────┬───────────────────────────────────────────────────────┤
│ Metric │ uv (baseline) │ pepip │ Improvement │
├──────────────┼─────────────────┼─────────────┼───────────────────────────────────────────────────────┤
│ Latency │ 0.76 s │ 0.50 s ★ │ -33.8 % │
│ Disk usage │ 9.46 MB │ 2.06 MB ★ │ -78.2 % │
└──────────────┴─────────────────┴─────────────┴───────────────────────────────────────────────────────┘
★ = better result
Key observations:
-
Storage savings are consistent regardless of project count: because each package version is stored exactly once in the global venv, the local
.venvdirectories contain only tiny symlinks (~dozens of bytes each) instead of full copies. With 5 projects and therequestsdependency tree (~2 MB each), pepip saves 7.4 MB compared to separate venvs. -
Latency savings grow with project count: the first project pays the same download + install cost as plain
uv. Every subsequent project only needs venv creation + symlink creation, which is nearly instant. For tiny packages (cached by uv), the difference is negligible at n=3, but reaches −34 % at n=5 with a larger dependency set. For real-world packages liketorchortransformers(GB-scale), the savings per extra project would be proportionally larger.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pepip-0.0.1.tar.gz.
File metadata
- Download URL: pepip-0.0.1.tar.gz
- Upload date:
- Size: 15.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9dd0969037c3db84e7be65cabe78056d026b17e3b730d485933301f1475f049e
|
|
| MD5 |
69d91dd0a500181e6aa79099232c6f3c
|
|
| BLAKE2b-256 |
b8f9d3485dc69ea7d52ab21fd29838e4967b0dfd31500b6bb0cf29ff378748f2
|
Provenance
The following attestation bundles were made for pepip-0.0.1.tar.gz:
Publisher:
publish-pypi.yml on perf-pip/pepip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pepip-0.0.1.tar.gz -
Subject digest:
9dd0969037c3db84e7be65cabe78056d026b17e3b730d485933301f1475f049e - Sigstore transparency entry: 1283198387
- Sigstore integration time:
-
Permalink:
perf-pip/pepip@2d3245bf9f40d39fdbf99f85bcbac357ed3a7f1f -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/perf-pip
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@2d3245bf9f40d39fdbf99f85bcbac357ed3a7f1f -
Trigger Event:
release
-
Statement type:
File details
Details for the file pepip-0.0.1-py3-none-any.whl.
File metadata
- Download URL: pepip-0.0.1-py3-none-any.whl
- Upload date:
- Size: 8.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b02d329c7fccf909ebbeac31a5c84a965c722fe54af2aa68b644e434b3c58c58
|
|
| MD5 |
fe0dbb08ef70ab667a57b87742fea90b
|
|
| BLAKE2b-256 |
cea31f804753d54bb62b7f2738ff50b63650c91bdd7688952e7e877b36634545
|
Provenance
The following attestation bundles were made for pepip-0.0.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on perf-pip/pepip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pepip-0.0.1-py3-none-any.whl -
Subject digest:
b02d329c7fccf909ebbeac31a5c84a965c722fe54af2aa68b644e434b3c58c58 - Sigstore transparency entry: 1283198391
- Sigstore integration time:
-
Permalink:
perf-pip/pepip@2d3245bf9f40d39fdbf99f85bcbac357ed3a7f1f -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/perf-pip
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@2d3245bf9f40d39fdbf99f85bcbac357ed3a7f1f -
Trigger Event:
release
-
Statement type: