🐍 pepip
uv and pip, but shared. Install packages once. Use them everywhere.
pepip is the pnpm of Python — a drop-in alternative to pip / uv that stores each resolved package version once in a shared store and wires your project .venv to it via symlinks. No more downloading torch and transformers five times across experiments. It internally uses uv for package resolution and venv management, so you get the uv command surface and compatibility, but with a fraction of the disk usage and faster installs for subsequent projects.
Built for package-heavy Python workflows, pepip is especially useful for AI/ML projects that repeatedly create envs for model prototyping, training, and inference.
🤔 The Problem
Every Python project gets its own virtual environment. That means every project downloads and stores its own copy of every dependency — including the big ones.
project-a/.venv/ → numpy 1.0 (34 MB) torch 2.4 (2.2 GB)
project-b/.venv/ → numpy 2.0 (35 MB) torch 2.4 (2.2 GB)
project-c/.venv/ → numpy 2.0 (35 MB) torch 2.5 (2.3 GB)
↑ stored 3× for no reason
✅ The Solution
pepip keeps an immutable shared package-version store and symlinks each project's .venv back to the exact versions it resolved. Same Python import behaviour. A fraction of the disk usage.
~/.pepip/packages/ → numpy 1.9 (34 MB) numpy 2.0 (35 MB) torch 2.4 (2.2 GB)
torch 2.5 (2.3 GB) ← stored once per version
project-a/.venv/ → numpy 1.0 (symlink) torch 2.4 (symlink) → ~bytes
project-b/.venv/ → numpy 2.0 (symlink) torch 2.4 (symlink) → ~bytes
project-c/.venv/ → numpy 2.0 (symlink) torch 2.5 (symlink) → ~bytes
🔍 Comparison
| Feature | uv / pip | conda | pepip |
|---|---|---|---|
| Shared package store | ❌ | ✅ | ✅ |
| Disk usage (multi-project) | 🔴 | 🟢 | 🟢 |
| Install speed (repeat packages) | 🟡 | 🟡 | 🟢 |
| Virtual env compatibility | ✅ | ❌ | ✅ |
| Multiple versions for each env | ✅ | ❌ | ✅ |
| Installation size | 🟢 | 🔴 | 🟢 |
Key differences:
- Speed and download size: While uv and conda cache helps, they still copy packages. If cache is cleared, they redownload. pepip only downloads once per version, then symlinks for every project, allowing instant installs for subsequent projects.
As pepip is based on uv, it has same advantages as uv, without the repeated download and storage cost.
🚀 Installation
pip install pepip
or using uv:
uvx pepip
Requirements: Python 3.8+ · uv (auto-installed) · Linux / macOS / Windows
On Windows, creating symlinks typically requires Developer Mode or an elevated shell. pepip now raises a clear error if the OS blocks symlink creation.
Platform compatibility
pepipsupports Linux, macOS, and Windows.- Shared-store reuse works across projects on the same machine/OS, while each OS keeps its own compatible store layout.
📦 Usage
Install packages using pepip
# Install one or more packages
pepip install numpy pandas
# AI/ML stack example
pepip install torch transformers accelerate datasets
# 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
Use pepip as a uv replacement
Every pepip command except install is forwarded to uv unchanged. That means
you can keep using the rest of the uv workflow through pepip:
pepip sync --all
pepip run python -m pytest
pepip venv .venv --python 3.12
pepip pip install ".[all]"
pepip --version
pepip install ... remains the shared-store install path, while the rest of the
CLI behaves like uv.
or
uvx pepip install numpy pandas
Then activate and use your .venv exactly as you normally would:
# macOS / Linux
source .venv/bin/activate
python -c "import numpy; print(numpy.__version__)"
# Windows PowerShell
.venv\Scripts\Activate.ps1
python -c "import numpy; print(numpy.__version__)"
pepip is compatible with existing uv environments. If a target venv already
exists (for example created with uv venv), pepip install --venv <path>
reuses it and links packages into that environment.
Usage using "uv"
uvx pepip install numpy pandas
This can be executed without installing pepip or creating a virtual environment, as long as uv is installed.
Override the global store location
PEPIP_HOME=/shared/team-env pepip install torch
This is handy for sharing a global store across a whole team on a shared machine.
🗂 How it works
~/.pepip/
├── global-venv/ ← build interpreter for uv installs
└── packages/
└── cpython-312-linux-x86_64/
├── numpy-1.0/
│ ├── numpy/ ← real files, stored once
│ └── numpy-1.0.dist-info/
├── numpy-2.0/
│ ├── numpy/ ← real files, stored once
│ └── numpy-2.0.dist-info/
├── torch-2.4/
│ ├── torch/ ← real files, stored once
│ └── torch-2.4.dist-info/
└── torch-2.5/
├── torch/ ← real files, stored once
└── torch-2.5.dist-info/
my-project-1/
└─ .venv/
└─ lib/
└─ python3.12/
└─ site-packages/
├─ numpy ───→ ~/.pepip/packages/.../numpy-2.0/numpy (symlink, ~bytes)
└─ pandas ───→ ~/.pepip/packages/.../pandas-2.2/pandas (symlink, ~bytes)
my-project-2/
└─ .venv/
└─ lib/
└─ python3.12/
└─ site-packages/
├─ torch ───→ ~/.pepip/packages/.../torch-2.4/torch (symlink, ~bytes)
└─ numpy ───→ ~/.pepip/packages/.../numpy-1.0/numpy (symlink, ~bytes)
- First install of a package version — downloads once into the shared store, then symlinks.
- Every subsequent project using the same package version — symlinks only. Near-instant, zero extra disk.
- Different projects can use different versions — for example, one project can link to
numpy==1.0while another links tonumpy==2.0. Each version is stored once, and projects link to the version they resolved.
📊 Benchmarks
The eval/benchmark.py script measures installation latency and disk usage across N projects compared to a plain uv workflow.
# 5 projects, mixed real-world packages
python eval/benchmark.py --projects 5 --packages tomli packaging requests numpy pandas
# Keep temp directories for manual inspection
python eval/benchmark.py --no-cleanup
Latest results — 5 projects · tomli packaging requests numpy pandas
| Metric | uv (baseline) | pepip | Improvement |
|---|---|---|---|
| ⏱ Latency | 0.56 s | 0.33 s ★ | 0.23s |
| 💾 Disk usage | 475.19 MB | 95.22 MB | 379.97 MB |
Why the savings get better over time
- Storage savings are consistent from project one: each package version lives exactly once in the global store, so local
.venvdirectories contain only tiny symlinks (dozens of bytes each) instead of full copies. - Latency savings grow with project count: the first project pays the same download cost as plain
uv. Every additional project only needs venv creation + symlink creation, which is nearly instant. For large packages liketorchortransformers(GBs in size), these savings per extra project are proportionally enormous. - Best fit for AI iteration loops: if you spin up multiple repos for finetuning runs, eval pipelines, or inference services,
pepipavoids repeatedly materializing the same heavy dependencies.
More usage instructions are at docs/USAGE.md.
Documentation related to production readiness is at docs/Production_Tests.md.
💡 Inspired by
pnpm — the Node.js package manager that pioneered content-addressable, symlink-based shared stores. pepip brings the same idea to the Python ecosystem.
Acknowledgements
- uv — used for venv management, package resolution, and shared download caching.
Made with ❤️ for developers tired of downloading torch over and over again.
Metadata
Release files for pepip 0.0.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pepip-0.0.10.tar.gz | 325.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pepip-0.0.10-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 343.6 kB
Release files / pepip-0.0.10.tar.gz
| Download URL | pepip-0.0.10.tar.gz |
|---|---|
| Size | 325.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f3f2a3a1375d2116ff0fbdbedb86ee0fd565e6288d1d9d9a50d1361352c91a89
|
|
BLAKE2b-256 checksum How to use checksums |
aca5dc92643bc11c5fb29f38ecce0057bf8cdc6586e21b0817200d64dad3eaf7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 18, 2026.
Transparency logRelease files / pepip-0.0.10-py3-none-any.whl
| Download URL | pepip-0.0.10-py3-none-any.whl |
|---|---|
| Size | 17.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1c5a09d7a6cad47067a0add1b99cbc7df90a454f578beaf0086b6de29fc8c4cf
|
|
BLAKE2b-256 checksum How to use checksums |
33d79f2c078e2a7e1c8a4ecc9ef9072fa2000c97af5f09688d5ad3f8f28d3b69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 18, 2026.
Transparency logSecurity for pepip 0.0.10
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pepip-0.0.10.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 18, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.