Why PVM
PVM brings modern tooling standards to Perl. The same quality of developer experience that Python developers enjoy — lockfiles, isolated execution, inline script metadata, static analysis — available today, in a single binary.
Coming from plenv or perlbrew
If you already use plenv or perlbrew, PVM will feel immediately familiar. It reads .perl-version files, understands your existing installations, and slots into your current workflow without disruption.
pvm import-system # Import your existing system Perl
pvm versions # See all available versions
pvm use 5.40.2 # Switch — same as plenv use
The difference is what PVM adds on top of version management.
Module management with lockfiles
plenv and perlbrew manage Perl versions. For modules you reach for cpanm separately. PVM includes pm, a module manager that works with cpanfile and produces a cpanfile.snapshot for reproducible installs — no separate tooling needed.
pm install Mojolicious # Install a module
pm add DBI # Add to cpanfile
pm sync # Reproduce a locked install
Isolated script execution
pvx runs scripts in isolated environments with automatic dependency detection. You choose the isolation level: global (use the active Perl), local (project deps only), or clean (a fresh environment). plenv and perlbrew have no equivalent.
pvx app.pl # Auto-detect deps, run
pvx --require DBI --require Moo app.pl
pvx --isolation clean script.pl # Completely fresh environment
Inline script metadata
Declare dependencies directly inside your script. PVM supports both a comment format and a POD block format. pvx reads these automatically — no separate cpanfile needed for standalone scripts.
# /// pvm
# [dependencies]
# requires = ["Mojolicious", "DBI"]
# ///
use Mojolicious;
use DBI;
=begin pvm
[dependencies]
requires = ["Mojolicious"]
=end pvm
Static analysis
psc performs type inference on your Perl code without requiring any annotations. It catches type mismatches, suggests guard patterns, and serves diagnostics to your editor via LSP. Nothing else in the Perl ecosystem does this.
psc check lib/ # Type-check a directory
psc analyze lib/MyModule.pm # Detailed analysis
psc lsp # Start the LSP server
Single binary, no bootstrap
plenv and perlbrew are shell scripts that need a working Perl to install themselves. PVM is a compiled Go binary. Download it, make it executable, run it. No Perl required to manage Perl.
Feature parity with modern tooling
The best language tooling today is fast, self-contained, and complete. PVM brings that standard to Perl. Here's how it compares across ecosystems.
| Category | PVM (Perl) | uv (Python) | npm / bun (JS) |
|---|---|---|---|
| Version Management | pvm install / pvm use |
uv python install |
nvm / built into bun |
| Package Management | pm install / pm add |
uv pip install / uv add |
npm install / bun add |
| Lockfile | cpanfile.snapshot |
uv.lock |
package-lock.json / bun.lock |
| Script Execution | pvx with auto-detect deps |
uv run |
npx / bunx |
| Tool Management | pvm tool add / pvm tool run |
uv tool install / uvx |
npx / bunx |
| Static Analysis | psc check / psc lsp (integrated) |
ty (separate tool by Astral) |
tsc (separate tool) |
| Isolation | pvx --isolation global/local/clean |
uv venv (virtualenvs) |
node_modules (per-project) |
| Inline Metadata | # /// pvm + =begin pvm |
PEP 723 (# /// script) |
— |
| Single Binary | Yes (pure Go) | Yes (Rust) | bun: yes / npm: needs Node |
Where PVM stands out
Integrated static analysis. Python has ty, JavaScript has tsc — both are separate tools you install and configure independently. psc ships inside PVM. One binary, zero extra setup. It infers types from your Perl code without annotations, catches mismatches, suggests guard patterns, and serves diagnostics to your editor via LSP.
Isolation + detection in one step. Python has virtualenvs. JavaScript has node_modules. These work well but require separate setup. pvx combines isolation with auto-dependency detection from source code in a single command — scan your use statements, install what's needed, run in an isolated environment. One command instead of a multi-step workflow.
Everything in one binary. bun achieved this for JavaScript. uv achieved it for Python. PVM achieves it for Perl — version management, package management, script execution, and static analysis, all in a single Go binary with no external dependencies.