CLI tool
justjavac/dvm avatar
justjavac/dvm

justjavac/dvm: a Deno version manager written in Rust

Deno Version Manager - Easy way to manage multiple active deno versions.

710 stars39 forksRustMIT

At a glance

What is it?
dvm installs Deno binaries into ~/.dvm and switches between them per shell or per directory through a .dvmrc file. It is a small, single-purpose tool, and the README is honest about its two hard requirements: unzip on Unix, PowerShell on Windows.
Who is it for?
Adopt dvm if you keep several Deno versions on one machine and want a per-directory .dvmrc so a checkout pins its own runtime. Skip it if you only ever run the latest Deno, or if you are on Windows without PowerShell, since the README states PowerShell is required there.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 36 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What dvm solves, and who it is for

Deno ships as a single executable, and updating it replaces that executable in place. That is fine until two projects on the same machine depend on different Deno releases, or until a runtime upgrade changes behaviour and you need the previous version back. dvm exists for that case. It keeps each installed Deno in its own directory under ~/.dvm and points your shell at one of them at a time.

The audience is narrow and specific: developers who run several Deno projects locally, CI jobs that need a pinned runtime, and anyone who wants the same per-directory version file that nvm or rbenv users already expect. It is not a general toolchain manager. It manages Deno and nothing else.

How dvm stores and switches Deno versions

The first time you run dvm with no arguments, the README shows it creating the home directory for the tool:

console
➜  ~  dvm
Creating /Users/justjavac/.dvm

Every version you install lands inside that directory. Switching is a matter of pointing the active Deno at one of those subdirectories, which is why dvm list marks the current one:

console
➜  ~  dvm list
 * 0.1.0
   0.1.1
   0.1.2

The asterisk is the version currently in use. The command surface is deliberately small. The README's help output lists completions, info, install, list, list-remote, uninstall, use and alias. There is no plugin system, no shim directory full of wrapper scripts, and no separate daemon. The binary is the whole tool.

The interesting design choice is .dvmrc. Running dvm use with the --local flag writes the chosen version into the current directory instead of the home config. After that, dvm use and dvm install fall back to that file when no version is given on the command line. The README shows the resulting interaction, including the line "No version input detect, try to use version in .dvmrc file". That fallback is what makes the tool useful in a repository: a checkout can carry its own runtime pin, and a teammate who runs dvm use without arguments gets the version the project expects.

Versions are resolved as semver ranges, not only exact strings, and the alias subcommand maps a name to a range. The README truncates the alias help text, so the exact alias syntax is not documented in the README available here; check dvm alias --help on an installed binary before relying on it.

Installing dvm and pinning a project version

The README offers two installers, one for shells and one for PowerShell, plus prebuilt binaries on the releases page. On macOS or Linux the shell installer is a single curl pipe:

bash
curl -fsSL https://raw.githubusercontent.com/justjavac/dvm/main/install.sh | sh

On Windows the equivalent uses PowerShell:

powershell
irm https://raw.githubusercontent.com/justjavac/dvm/main/install.ps1 | iex

After either one, confirm the binary is on your PATH:

bash
dvm -V

The README states this prints dvm's version when the installation succeeded. If it prints nothing, the shell profile was not updated or the binary is not on PATH; the README does not document a manual PATH fix, so check the installer output for where it placed the binary.

A first real use is pinning a Deno release to a project directory. The README's example uses 1.17.0:

bash
dvm use --local 1.17.0

If that version is not installed yet, dvm tells you so and names the command to fix it, as the README shows with "deno v1.2.0 is not installed. Use `dvm install 1.2.0` to install it first." So the practical sequence is dvm install 1.17.0 followed by dvm use --local 1.17.0. From then on, running dvm use with no argument in that directory reads the .dvmrc file and reports the range it resolved. Commit the .dvmrc file if you want the pin to travel with the repository.

Where dvm stops being the right tool

The README has a caveats section, and it is worth reading before you install anything. The shell installer requires unzip, because it extracts a zip archive. On a minimal container image without unzip, the install fails with an explicit error pointing at the README anchor. The documented fixes are brew install unzip on macOS and apt-get install unzip -y on Ubuntu, Debian or Deepin.

On Windows, the PowerShell requirement is not a suggestion. The README says dvm uses the PowerShell profile to set environment variables, so a Windows setup without PowerShell is not supported. The shell installer can run under WSL, MSYS or equivalent, but that is the Unix path inside Windows, not a native Windows path.

There is a second boundary that matters more for teams. dvm manages Deno and only Deno. If a project needs Node, Python and Deno at once, dvm covers one third of the problem and you will still need something else for the rest. And if your workflow is simply to run the newest Deno everywhere, dvm adds a layer of indirection with no benefit; the built-in upgrade path is shorter.

The README also does not document rollback of a failed install, checksum verification of downloaded binaries, or a proxy configuration for restricted networks. Those gaps are not disqualifying for local development, but they are the questions to answer before putting dvm in an automated pipeline.

dvm compared with deno upgrade and nvm

The direct alternative is Deno's own upgrade command. It replaces the installed binary with a newer release. The difference is state: deno upgrade keeps one version and discards the old one, while dvm keeps each version in ~/.dvm and switches between them. If you have ever needed to reproduce a bug on the previous release, that difference is the whole point. If you have not, deno upgrade is one command instead of two.

The other comparison is nvm, which many readers already know. nvm manages Node versions and is distributed as a shell function that you source; dvm is a compiled Rust binary that you install and run. dvm's per-directory mechanism is a .dvmrc file, which is the same shape as nvm's .nvmrc, so the mental model transfers even though the implementation does not. What does not transfer is ecosystem: nvm cannot install Deno, and dvm cannot install Node. A polyglot repository needs both, or a different tool entirely.

Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-08-25, the same day as the v1.10.1 release. The release history shows an uneven cadence rather than a steady one: v1.9.3 in February 2025, then v1.10.0 in August 2026 and v1.10.1 later that month. Two releases close together after a long gap is a pattern worth noting if you depend on prompt fixes.

The project is MIT licensed, as stated in both the README and the license field of Cargo.toml. That is a permissive licence; it does not impose copyleft obligations on your own code. This is a description of what the files say, not legal advice, and if dvm is redistributed inside a product you should read the bundled LICENSE file and talk to whoever handles licensing.

Upgrade cost is low by construction. dvm is a single binary with no service to restart and no configuration schema beyond the home config and any .dvmrc files. Installing a new dvm does not touch the Deno versions already under ~/.dvm. The dependencies listed in Cargo.toml are ordinary crates (clap, semver, serde, native-tls with vendored TLS), and the release profile is tuned for binary size with lto, opt-level 'z' and panic = 'abort'. If you build from source, note that panic = 'abort' means a panic terminates the process without unwinding, which is normal for a CLI but relevant if you were embedding the crate rather than running the binary.

Editorial conclusion

Adopt dvm if you keep several Deno versions on one machine and want a per-directory .dvmrc so a checkout pins its own runtime. Skip it if you only ever run the latest Deno, or if you are on Windows without PowerShell, since the README states PowerShell is required there. Before trusting it in a build pipeline, verify that dvm use --local writes the .dvmrc your project expects and that dvm list-remote resolves the version you need.

Frequently asked questions

How do I install dvm on macOS or Linux?

Run the shell installer from the README: curl -fsSL https://raw.githubusercontent.com/justjavac/dvm/main/install.sh | sh. The README states that unzip is required for this installer, so install it first if it is missing. You can also download a release binary from the releases page.

What does the .dvmrc file do in dvm?

Adding the --local flag to dvm use writes the chosen version into the current directory instead of the home config. Afterwards, dvm use and dvm install read that file when no version is supplied on the command line, so a project can pin its own Deno release.

Why does dvm require PowerShell on Windows?

The README states that dvm uses the PowerShell profile to set environment variables, so PowerShell is required on Windows. The shell installer can still be used under WSL, MSYS or equivalent tools, which is the Unix path rather than a native Windows one.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/justjavac-dvm.svg)](https://hysenlabs.com/projects/justjavac-dvm)