仕事でコードを書かなくなって久しいですが、仕事以外では色々書いています。
相変わらずNode.jsがメインで、最近はランタイムのバージョン管理ツールをいろいろ検討していました。
欲しいもの
自動的にバージョンを切り替えてくれるやつがほしい!
- 手動での切り替え不要
nodeコマンドを実行したディレクトリー(またはそこから親を辿った先)にあるバージョン指定情報を参照して自動的に切り替える- 必要なバージョンがインストールされていなければ自動的にインストールしてくれる
package.jsonのdevEnginesとかを読んでくれるとうれしい
遍歴
Voltaが一番好みに近かったですね。
インストールするとnodeやnpmコマンドのシンボリックリンク先がvoltaになり、nodeコマンドを実行した時に自動的にpackage.jsonを探してvoltaフィールドの値に切り替えてくれます。
devEnginesフィールドではないですが、それ以外はほぼ希望通りです。
Rust製でめちゃくちゃ快適だったのもプラスポイントです。
Voltaが開発停止
そんな感じで便利に使っていたんですが、数ヶ月前に “Volta is unmaintained.” というお知らせが…
https://github.com/volta-cli/volta
移行先としてmiseが推奨されています。 Voltaと同じように便利に使えるんだろうか…
miseを使ってみる
「まいす」「まいず」ではなく「みーず」と読むそうです。 正式名称は “mise-en-place” 、フランス語で「設定(setup)」だそうな。
Node.jsだけじゃなくてPythonやRubyにも対応しているらしい、というわけでとりあえずNode.jsで使ってみます。
まずはそれまで使っていたバージョン管理ツールやNode.jsなどをアンインストールして、node, npm, yarnなどのコマンドが使えない状態にしてください。
インストール
miseのインストールは、公式サイトにあるコマンド一発でできました。
curl https://mise.run | sh
インストール後にmiseアクティベーション用コマンドが表示されるので、忘れずに実行しておいてください。
別ターミナルを開いて、miseがインストールされたことを確認
$ mise -v
_ __
____ ___ (_)_______ ___ ____ ____ / /___ _________
/ __ `__ \/ / ___/ _ \______/ _ \/ __ \______/ __ \/ / __ `/ ___/ _ \
/ / / / / / (__ ) __/_____/ __/ / / /_____/ /_/ / / /_/ / /__/ __/
/_/ /_/ /_/_/____/\___/ \___/_/ /_/ / .___/_/\__,_/\___/\___/
/_/ by @jdx
2026.3.9 macos-arm64 (2026-03-13)
設定
最低限LTSが動くようにグローバルにNode.jsをインストール。
ついでにNPMとYarnも。
お好みでbunやpnpmなどもどうぞ。
mise use --global node@lts
mise use --global npm@latest
mise use --global yarn@1
多分必要な設定はこれだけ。
いよいよ動作テスト
適当なディレクトリーに.tool-versionsを作成して動作テスト。
書き方は、asdfの.tool-versionsと同じ形式です。
今回は、このディレクトリーでNode.js v22を使うように設定してみます。
node 22
ファイルを作成した後でこのディレクトリーに移動すると、こんな警告が表示されます。 「Node.js 22が指定されているけどインストールされていないよ」と言われています。
mise WARN missing: node@22.22.1
気にせずにnodeコマンドを使ってみます。
$ node -v
node@22.22.1 10.9.4 ✔
v22.22.1
自動的にインストールが始まり、v22が表示されました!
サブディレクトリーでも使える?
.tool-versionsがあるディレクトリーだけでなく、そのサブディレクトリー内でも自動的にダウンロードや切り替えができるかチェックしてみます。
今度は.tool-versionsに別のバージョンを指定してみます。
node 20
その後で、サブディレクトリーを作成してnodeコマンドを実行。
$ mkdir test
$ cd test
mise WARN missing: node@20.20.1
$ node -v
node@20.20.1 10.8.2 ✔
v20.20.1
サブディレクトリーでもOK!
パッケージマネージャーも管理したい
Node.js本体だけじゃなくて、NPMとかYarnとかのパッケージマネージャーも同じように自動的に切り替えたいので、.tool-versionsを変えてみました。
node 22
npm 10
yarn 1.20
同じようにバージョンを確認
$ npm -v
10.9.4
$ yarn -v
1.20.0
無事切り替わりました。
ところで、以下のようにNode.jsのバージョンを24にすると、NPMのバージョンは10ではなく11になりました。
node 24
npm 10
$ node -v
v24.14.0
$ npm -v
11.9.0
NPMはピンポイントで自由にバージョンを指定できるわけではなく、対応するNode.jsがサポートしている最低バージョン以降を使えるのでしょうか。
package.jsonから自動判別したい
こちらによると、Node.js関連のツールはpackage.jsonを参照して切り替える機能があるようです!
素敵やん。
Pull Request(と元になったディスカッション)を見る限り、packageManagerとdevEnginesフィールドを参照するようです。
Voltaは専用のvoltaフィールドを参照していたので、これよりも汎用性が高いですね。
素敵やん。
早速これも試してみましょう。
まず、以下のコマンドを実行してください。
node, npm, yarnのバージョン参照にpackage.jsonを使えるようになります。
お好みでbunやpnpmなどもどうぞ。
mise settings add idiomatic_version_file_enable_tools node
mise settings add idiomatic_version_file_enable_tools npm
mise settings add idiomatic_version_file_enable_tools yarn
次に.tool-versionsを削除して、package.jsonを作成。
{
"devEngines": {
"runtime": {
"name": "node",
"version": "18"
},
"packageManager": {
"name": "yarn",
"version": "1.19"
}
}
}
そして実験。
$ node -v
v18.20.8
$ yarn -v
1.19.2
ちゃんと切り替わりました!
ただし、こちらもnpmは対応するNode.jsの最低バージョン以降に限定されるようです。
{
"devEngines": {
"runtime": {
"name": "node",
"version": "24"
},
"packageManager": {
"name": "npm",
"version": "10"
}
}
}
$ node -v
v24.14.0
$ npm -v
11.9.0
また、packageManagerの各プロパティーが配列の場合は最初の1つしか認識しないようで、たとえば以下のようにするとnodeやyarnのバージョンを切り替えてくれません。
コメントで明記されているので、おそらくこれは仕様でしょう。
{
"devEngines": {
"runtime": [
{
"name": "bun",
"version": "1.1"
},
{
"name": "node",
"version": "20"
}
],
"packageManager": [
{
"name": "npm",
"version": "10"
},
{
"name": "yarn",
"version": "1.19"
}
]
}
}
$ node -v
v24.14.0
$ yarn -v
1.22.22
複数のランタイムやパッケージマネージャーを使いたい場合は.tool-versionsを使うのがよさそうです。
補完
シェルのタブ補完も対応しているようなのでやってみます。
まず補完スクリプトを生成&保存。 たとえばZ Shellならこんな感じ。 他のシェル用のコマンドは上記のリンク先を参照してください。
mise completion zsh > /usr/local/share/zsh/site-functions/_mise
“permission denied” された場合は、以下のいずれかで。
sudoをつけて実行- 保存先を環境変数
$fpathが指すディレクトリーのどこかに変更 $HOME/.zsh/completionsのようなディレクトリーを作成し、その中に変更→このディレクトリーを$fpathに追加
そのあとで別ターミナルを開いて補完の確認ですが、こんなエラーが出て補完できない時があります。
Error: usage CLI not found. This is required for completions to work in mise.
See https://usage.jdx.dev for more information.
その場合は、以下のコマンドでusageコマンドを使えるようにしてください。
mise use --global usage
これでタブ補完が効くようになると思います。
まとめ
- Voltaは開発停止したよ
- miseはいい感じだよ
.tool-versionsを読んでくれるよ- ちょっと設定すれば
package.jsonも読んでくれるよ devEngineを読んでくれるから、Voltaのように専用フィールドは必要ないよ- シェル補完もできるよ
- でもちょっと気をつけることあるよ
- NPMはピンポイントで自由に切り替えられないみたいだよ
devEnginesのruntimeやpackageManagerが配列の場合は、最初の1つしか認識しないよ
NPMだけ特別にバージョンを下げたいということも、runtimeやpackageManagerも複数指定することも個人的にはあまりないので、今のところ実用上の問題はなさそうです。
おかげでVoltaと決別する決心がつきました。 今までありがとう。 君のことは忘れないよ。