Skip to main content

Virtual dependency directories for package managers, backed by a shared FUSE store.

Project description

uvl

uvl lets tools keep using their normal dependency directories while a FUSE filesystem redirects the physical files into a shared global store.

Your project still sees node_modules, .venv, vendor, or any other entry directory the tool expects. The bytes live under:

~/.uvl/store/<manager>

That means existing tools, editors, and runtime resolution keep working, but duplicated dependency files can be stored once and mounted back into each project as a read-only virtual directory.

Install

From PyPI:

pipx install uvl-fuse
# or
uv tool install uvl-fuse

From this repository:

git clone https://github.com/ShinapriLN/uvl.git
cd uvl
make build
uv tool install .

Prebuilt wheels include the native engine, so installation does not compile anything. On Linux, runtime mounting still needs FUSE support and permission to mount filesystems.

If you build from source instead of using a prebuilt wheel, install:

  • cmake
  • a C compiler such as gcc or clang
  • pkg-config
  • FUSE 3 development headers
  • OpenSSL development headers
  • Python 3.8+ and uv if you want to build the wheel locally

Platform Support

Current published wheels:

  • Linux x86_64

Runtime requirements:

  • Linux kernel FUSE support
  • /dev/fuse access
  • fusermount3 or an equivalent FUSE unmount helper

Source builds are still possible from this repository, but the published PyPI package is intended for Linux x86_64 users who want a prebuilt wheel.

Build From Source

The repository currently has two runnable paths:

  • build/uvl: a single native binary built by CMake. It handles the CLI, tool wrapping, object storage, and FUSE mount mode in one executable.
  • Python package entrypoint: kept for packaging compatibility while the native binary matures.

Use the Makefile wrapper for day-to-day commands:

make          # configure CMake and build the native binary
make build    # same as make
make check    # build C code and run Python import/CLI checks
make wheel    # build a wheel with the bundled native binary
make clean    # remove build outputs and Python bytecode

The native build output is created at:

build/uvl

The native binary starts its own internal FUSE mode by re-executing itself as uvl __mount ..., so there is no separate uvl_fuse binary in the CMake build. The Python wheel bundles this binary at uvl/native/uvl so users do not need to compile it during install.

Mount A Tool

Register the tool binary and the dependency directory it owns:

uvl --fuse bun --mnt node_modules
🚀 bun has been mounted with uvl.
👍 now you can use `uvl bun ...` with any bun arguments.
✨ node_modules will physically store at ~/.uvl/store/bun

💥 Caution: While a directory is mounted by uvl, avoid deleting or modifying it directly.
Unmount it first with `uvl --unmnt node_modules`.

Then run the tool through uvl when dependencies may change:

uvl bun install
uvl bun add vite
uvl bun remove vite

After the tool finishes, uvl scans the dependency directory, moves physical files into ~/.uvl/store/bun/objects, updates the project .uvl binary manifest, clears the local directory, and mounts the virtual view back at node_modules.

The directory still works as normal:

bun run index.ts
uvl bun run index.ts

But disk usage in the project directory is near zero:

du -sh node_modules
# 0 node_modules

Python Example

Register uv with its virtual environment directory:

uvl --fuse uv --mnt .venv

Create or sync a project through uvl:

uvl uv init app
cd app
uvl uv sync

uvl mounts .venv after uv sync, while the stored files live under:

~/.uvl/store/uv

Running through either command still works:

uvl uv run main.py
uv run main.py

Unmount

Mounted dependency directories are intentionally read-only. If you want to delete, inspect, or rebuild the directory directly, unmount it first:

uvl --unmnt .venv
✅ Unmounted .venv
⚡ You can now delete or modify anything inside

After unmounting, the mount point is just a normal directory again.

Commands

uvl --fuse <tool> --mnt <dir>    Register a tool mount directory
uvl --fiss <tool>                Remove a tool from ~/.uvl/config.json
uvl <tool> [args...]              Run a mounted tool
uvl --unmnt <dir>                 Unmount a virtualized directory
uvl --status                      Show current project mount status
uvl --list                        List registered tools
uvl --has <tool>                  Check if a mounted tool is installed
uvl --version                     Print the version

uvl has defaults for common tools, so this is also valid:

uvl --fuse bun
uvl --fuse uv
uvl --fiss bun

How It Works

  1. uvl --fuse <tool> --mnt <dir> saves a registration in ~/.uvl/config.json.
  2. uvl --fiss <tool> removes the tool from ~/.uvl/config.json.
  3. uvl <tool> ... runs the real tool binary with the same arguments.
  4. If the registered entry directory exists and is not already mounted, uvl scans the result.
  5. Files are content-addressed by SHA-256 and stored under ~/.uvl/store/<tool>/objects.
  6. A binary project .uvl manifest stores every mounted tool, mount directory, and virtual path map for fast loading. One project can track entries such as .venv and node_modules at the same time.
  7. A C FUSE daemon mounts a read-only virtual filesystem at the original dependency directory.

The goal is simple: tools keep their normal layout; projects stop holding duplicate physical dependency trees.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

uvl_fuse-0.0.1-py3-none-manylinux_2_28_x86_64.whl (1.8 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

File details

Details for the file uvl_fuse-0.0.1-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for uvl_fuse-0.0.1-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f39d080af2cf1cd537f5966d69870e1554f683db4cf197dba0f8b522f2e10e04
MD5 e8cdb954c1c2565003bdcf2a7a0be300
BLAKE2b-256 31a34730eddca8170cf542cd5a8ff4e86806ffd75d672b91d26ddb16682dab4e

See more details on using hashes here.

Provenance

The following attestation bundles were made for uvl_fuse-0.0.1-py3-none-manylinux_2_28_x86_64.whl:

Publisher: build-wheel.yml on ShinapriLN/uvl

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page