How nvm Handles io.js (Deprecated) Installations and Migrations

nvm treats io.js as a separate runtime flavor using prefix-aware helper functions in nvm.sh to manage versioning, downloads, and migrations without duplicating core logic.

The nvm (Node Version Manager) project maintains legacy support for the discontinued io.js runtime through a flavor abstraction system implemented in its core shell script. Even though the io.js project merged back into Node.js in 2015 with the release of Node 4.0.0, nvm continues to handle io.js installations and migrations using dedicated prefix helpers that intercept version strings before they reach the standard Node management pipeline. This architecture allows users to install historical io.js releases, switch between io.js and Node versions, and migrate projects to modern Node runtimes seamlessly.

Prefix Helpers – The Foundation of io.js Detection

All io.js specific logic in nvm relies on four essential helper functions defined in nvm.sh that normalize version strings by adding or removing the iojs- prefix.

  • nvm_iojs_prefix (line 1419): Returns the literal string iojs used to identify the flavor throughout the script.
  • nvm_is_iojs_version (line 1426): Tests whether a version string begins with iojs- to determine which code path to execute.
  • nvm_add_iojs_prefix (line 1431): Adds the iojs- prefix to a plain semantic version (e.g., transforms 1.0.0 into iojs-1.0.0).
  • nvm_strip_iojs_prefix (line 1435): Removes the iojs- prefix to return a canonical version number for internal comparison.

These functions enable higher-level commands like nvm_resolve_alias and nvm_version to handle io.js versions transparently. When nvm encounters a version string, it first calls nvm_is_iojs_version to detect the flavor, uses nvm_strip_iojs_prefix to work with the raw semver internally, and applies nvm_add_iojs_prefix when displaying results to the user.

Listing Installed and Remote io.js Versions

Local Listing with nvm ls

When you run nvm ls with an io.js pattern, the script detects the flavor and routes the request appropriately.

  1. Flavor Detection: The code checks nvm_is_iojs_version (lines 1550‑1556) to determine if the search pattern refers to io.js.
  2. Directory Resolution: It selects the $NVM_DIR/versions/iojs directory via nvm_version_dir iojs rather than the standard Node versions directory.
  3. Prefix Management: After stripping the prefix for internal matching against installed directories, nvm re-adds it for display output.

Remote Listing with nvm ls-remote iojs

To fetch available io.js releases from the legacy mirror:

  • The entry point nvm_ls_remote_iojs (line 1635) acts as a thin wrapper.
  • It delegates to nvm_ls_remote_index_tab with the flavor argument set to iojs, which injects the iojs- prefix before each version number (lines 1663‑1665).
  • The index file downloads from https://iojs.org/dist/index.tab, as resolved by nvm_get_mirror (line 2226).

This allows nvm ls-remote iojs to display historical releases like iojs-3.3.1 and iojs-3.2.0 even though the project is no longer actively maintained.

Downloading and Installing io.js Artifacts

The installation pipeline for io.js reuses the same core logic as Node, with only the mirror URL and directory structure differing.

When you execute nvm install iojs-3.3.1, the following occurs:

  1. Normalization: nvm_strip_iojs_prefix removes the prefix to obtain the canonical version v3.3.1.
  2. Slug Generation: nvm_get_download_slug (lines 3767‑3769) constructs the filename for binary or source archives using the iojs flavor identifier.
  3. Mirror Selection: nvm_get_mirror returns https://iojs.org/dist (line 2226) instead of the Node.js distribution URL.
  4. Extraction: nvm_download fetches the tarball, and either nvm_install_binary or nvm_install_source extracts it into $NVM_DIR/versions/iojs/iojs-3.3.1.

Switching Between io.js and Node Versions

The nvm use <version> command resolves the installation path and updates your shell's PATH environment variable. When switching to an io.js version:

  • The resolved path uses nvm_add_iojs_prefix to ensure the directory name includes the prefix (e.g., iojs-3.3.1).
  • nvm prepends $NVM_DIR/versions/iojs/iojs-3.3.1/bin to your PATH.
  • Upon successful activation, the script outputs: Now using io.js 3.3.1 (npm v2.14.12) (referenced at line 3978).

Uninstalling io.js Versions

Removing an io.js installation follows the standard uninstallation flow, with flavor-specific messaging. When you run nvm uninstall iojs-3.3.1, the script removes the directory and prints an explicit confirmation: Uninstalled io.js 3.3.1 (line 3776).

Migrating from io.js to Modern Node

Because nvm normalizes versions internally, migrating from the deprecated io.js line to modern Node requires only standard nvm commands. The --reinstall-packages-from flag (documented at line 3127) facilitates global package migration between flavors.


# Install the latest stable Node

nvm install node

# Copy global npm packages from iojs-3.3.1 to the current Node version

nvm reinstall-packages iojs-3.3.1

# Remove the deprecated io.js version

nvm uninstall iojs-3.3.1

Even though io.js ended at version 3.3.1, these code paths remain functional in nvm, ensuring legacy projects can continue running or transition cleanly to the unified Node.js runtime.

Summary

  • Flavor Abstraction: nvm uses prefix helpers (nvm_is_iojs_version, nvm_strip_iojs_prefix, nvm_add_iojs_prefix) to treat io.js as a distinct runtime flavor within nvm.sh.
  • Legacy Mirror Support: Downloads resolve to https://iojs.org/dist via nvm_get_mirror, while installations store files in $NVM_DIR/versions/iojs/.
  • Unified Commands: Standard nvm install, nvm use, nvm ls, and nvm uninstall commands work with iojs- prefixed versions without requiring separate subcommands.
  • Migration Tools: The nvm reinstall-packages command transfers global packages between io.js and Node installations, simplifying upgrades from the deprecated runtime.

Frequently Asked Questions

Can I still install io.js with nvm today?

Yes. nvm continues to support installing historical io.js versions from the legacy mirror at iojs.org. You can run nvm install iojs-3.3.1 or any previous release, and the binaries will download and install into $NVM_DIR/versions/iojs/ just as they did when the project was active.

How do I migrate global npm packages from io.js to Node?

Use the nvm reinstall-packages command. First install your target Node version with nvm install node, then run nvm reinstall-packages iojs-<version> where <version> is your old io.js release. This copies globally installed packages from the io.js environment to the currently active Node version.

Where does nvm store io.js versions on disk?

io.js versions reside in a separate directory hierarchy at $NVM_DIR/versions/iojs/ rather than $NVM_DIR/versions/node/. Each version is stored in a subdirectory named with the iojs- prefix (e.g., iojs-3.3.1), ensuring no filename collisions with Node.js releases of the same version number.

Will nvm remove support for io.js in future releases?

There are no plans to remove io.js support. The implementation in nvm.sh is non-intrusive, relying on the same core functions used for Node management. Maintaining backward compatibility for the deprecated runtime requires minimal overhead while preserving functionality for legacy codebases that still depend on io.js-specific behavior.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →