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.