sprout is a minimalist, source-based package manager built with Bun. It automatically detects build systems, resolves dependencies, compiles from source, and manages installations all from Git repositories.
- Git-Native: Install packages directly from any Git repository
- Auto-Detection: Automatically detects and uses the appropriate build system
- Multi-Version Support: Install multiple versions of the same package side-by-side
- Dependency Resolution: Automatically installs dependencies from
pkgdepsfiles - Build System Support: Cargo, CMake, Make, Meson, Go, Python (pipx), Zig, Nimble, and more
- Custom Build Scripts: Support for custom
blditbuild scripts - Source-Based: Always compiles from source for your specific system
- Decentralized: No central registry requiredβany Git repo can be a package
- Git
- Root/sudo access (for system-wide installation)
- Build tools for your target packages (gcc, make, cmake, cargo, etc.)
Download the latest release from GitHub Releases:
# Download the binary for your platform # Make it executable chmod +x sprout-linux-x64 # Install system-wide (requires sudo) sudo mv sprout-linux-x64 /usr/local/bin/sproutIf you prefer to build from source using Bun.js:
# Clone the repository git clone https://github.com/phukon/sprout.git cd sprout # Install dependencies bun install # Build sprout bun run build:binaries # Make it available system-wide (requires sudo) sudo ln -s $(pwd)/dist/cli.js /usr/local/bin/sprout# Add a package repository sprout ar https://github.com/aristocratos/btop # Install a package sprout i btop # Install a specific version sprout i btop:v1.2.13 # Install directly from a Git URL sprout ir https://github.com/aristocratos/btop v1.2.13 # List installed packages sprout l # Search for packages sprout s keyword # Update all packages sprout u # Remove a package sprout r btop # Switch between versions sprout switch btop v1.2.13 # List available versions sprout versions btopsprout follows a pipeline architecture:
Repository β Clone β Dependencies β Build β Install β Symlink Repositories are stored as plain text URLs in /etc/sprout/repos/repos:
https://github.com/aristocratos/btop https://github.com/sharkdp/fd https://github.com/BurntSushi/ripgrep When you install a package, sprout searches through registered repositories to find a matching package name.
Packages are cloned into /var/sprout/build/[package]/[version]/:
# Example structure /var/sprout/build/ βββ btop/ β βββ HEAD/ # Latest from main/master β βββ v1.2.13/ # Specific version βββ ripgrep/ βββ HEAD/sprout uses shallow clones (--depth 1) for faster downloads.
Dependencies are declared in pkgdeps files:
Project-level (/path/to/repo/pkgdeps):
https://github.com/user/dependency1 https://github.com/user/dependency2 v1.0.0 User-defined (/etc/sprout/deps/[package].pkgdeps):
https://github.com/user/custom-dep Dependencies are installed recursively before building the main package.
sprout automatically detects the build system by looking for specific files:
| Build System | Detection File | Install Command |
|---|---|---|
| Cargo | Cargo.toml | cargo install --git |
| CMake | CMakeLists.txt | cmake .. && make |
| Make | Makefile | make |
| Meson | meson.build | meson setup build && meson compile |
| Go | go.mod | go install |
| Python | pyproject.toml | pipx install |
| Zig | build.zig | zig build |
| Nimble | *.nimble | nimble install |
| Autotools | configure | ./configure && make |
| pnpm | pnpm-lock.yaml | pnpm install && pnpm run build |
Detection Order:
- Custom bldit script in
/etc/sprout/bldit/[package] - Project bldit script in repository root
- Registered build strategies (tried in order)
For packages with complex build processes, you can create custom bldit scripts:
System-wide: /etc/sprout/bldit/[package]
#!/bin/bash bldit() { cd "$1" # Build directory passed as first argument # Custom build commands ./autogen.sh ./configure --prefix=/usr make -j$(nproc) }Project-level: Repository root bldit file (shipped with the package)
After building, sprout scans the build directory for:
- Executables: Files with execute permissions
- Libraries:
.so,.a,.ofiles - Headers:
.h,.hppfiles - Special directories:
include/,lib/,bin/
Files are copied to:
/var/sprout/pkgs/[package]/[version]/ # Executables /usr/lib/ # Libraries /usr/include/ # Headers Executables are symlinked to /usr/bin/ for easy access:
# Standard symlink (points to active version) /usr/bin/btop -> /var/sprout/pkgs/btop/v1.2.13/btop # Version-specific symlinks (always point to specific versions) /usr/bin/btop:v1.2.13 -> /var/sprout/pkgs/btop/v1.2.13/btop /usr/bin/btop:v1.3.0 -> /var/sprout/pkgs/btop/v1.3.0/btop /usr/bin/btop:HEAD -> /var/sprout/pkgs/btop/HEAD/btopThis allows:
- Multiple versions to coexist
- Easy version switching (change standard symlink target)
- Run specific versions directly:
btop:v1.2.13 - Clean uninstallation
/var/sprout/ βββ pkgs/ # Installed packages β βββ [package]/ β βββ HEAD/ # Latest version β βββ v1.0.0/ # Specific versions β βββ v2.0.0/ βββ build/ # Build directories (temporary) βββ [package]/ βββ [version]/ /etc/sprout/ βββ repos/ β βββ repos # List of package repositories βββ deps/ β βββ [package].pkgdeps # Custom dependencies βββ bldit/ βββ [package] # Custom build scripts /usr/bin/ # Symlinks to executables βββ package # Standard symlink (points to active version) βββ package:v1.0.0 # Version-specific symlink βββ package:v2.0.0 # Version-specific symlink /usr/lib/ # Shared libraries /usr/include/ # Header files From a file:
sprout arp repos.txtFrom a URL:
sprout arp https://example.com/repos.txtCreate a custom dependency file:
sudo nano /etc/sprout/deps/mypackage.pkgdepsAdd dependencies:
https://github.com/user/dep1 https://github.com/user/dep2 v1.0.0 Create a custom build script:
sudo nano /etc/sprout/bldit/mypackage#!/bin/bash bldit() { local build_dir="$1" cd "$build_dir" # Your custom build commands ./configure --with-custom-flags make -j$(nproc) make install DESTDIR="$2" # $2 is the install directory }Make it executable:
sudo chmod +x /etc/sprout/bldit/mypackage# Install specific version sprout i package:v1.2.3 # Install latest (HEAD) sprout i package # Install multiple versions sprout i package:v1.0.0 sprout i package:v2.0.0 sprout i package:HEAD # Switch active version sprout switch package v1.0.0 # List available versions sprout versions package # Remove specific version (keeps other versions) sprout r package:v1.2.3 # Remove all versions sprout r package # List all versions of a package sprout l | grep package# See all files installed by a package sprout f btopTo make your project installable with sprout, ensure:
- It's a Git repository (obviously!)
- It has a supported build system (Cargo.toml, Makefile, CMakeLists.txt, etc.)
- (Optional) Include a
pkgdepsfile in the root for dependencies - (Optional) Include a
blditscript for custom build logic
# Dependencies for my project https://github.com/dependency/one https://github.com/dependency/two v2.1.0 #!/bin/bash bldit() { local build_dir="$1" local install_dir="$2" cd "$build_dir" # Custom build process ./autogen.sh ./configure --prefix="$install_dir" make -j$(nproc) make install }# Make sure the repository is added sprout ar https://github.com/user/package # Or install directly sprout ir https://github.com/user/package# Check if required build tools are installed which make cmake cargo go # View build directory for manual inspection ls -la /var/sprout/build/[package]/[version]/# sprout needs root access for system-wide installation sudo sprout i package# Install locales in your system/container sudo apt-get install locales sudo locale-gen en_US.UTF-8 # Or run with UTF-8 forced btop --force-utf- Parallel dependency installation
- Build caching
- Binary package support (optional)
- Dependency graph visualization
- Version pinning and lock files
- Plugin system for custom build strategies
- Package metadata and descriptions
- Rollback mechanism
Advantages:
- No central registry bottleneck
- Always get the latest code
- Optimized for your specific system
- Full source transparency
- Easy to package your own projects
- Multiple versions coexist peacefully
Inspired by pkgit
