はじめに
Claude Code は Anthropic 公式の CLI で、ターミナル上で対話しながらコード編集・コマンド実行までこなしてくれる AI 開発アシスタントです。
筆者の体感では、Python と Node.js が動く環境を与えた瞬間から Claude Code でできることが一気に広がります。具体的には:
- 書いたコードをその場で動かして、エラーが出たら原因を追って直すまで一気通貫
- CSV / Excel / JSON の加工(「この売上データ、重複消して月別に集計して別シートに出して」)
- Web からの情報収集(「この商品ページの価格を毎日取って CSV に追記していって」)
- 画像の一括リサイズ、PDF の結合、ファイル名の連番リネームみたいな日常の雑務
逆に環境が無いと「コードは書けても検証できない」状態になりがちで、Claude Code の強みが半減します。
この記事では、WSL に uv と nvm を入れ、プロジェクト毎に仮想環境を作る最小構成と、それを Claude Code に守らせるための CLAUDE.md テンプレを紹介します。
なぜ uv と nvm なのか
- プロジェクト毎に隔離したい: グローバル環境を汚すと他プロジェクトに影響が出る。Claude Code は複数プロジェクトを行き来するので、汚染を防ぐ意味が特に大きい
- バージョン切替が要る: プロジェクトごとに Python / Node のバージョンが違うのは当たり前
-
速い: どちらも Rust / シェルで書かれており、
pipやnpmより体感が軽い - 標準的: どちらも現代の Python / Node 界隈で広く採用されている
インストール
WSL(Windows Subsystem for Linux)
PowerShell を 管理者権限で 開いて:
wsl --install
再起動後、Ubuntu が自動起動するのでユーザー名とパスワードを設定します。以降の作業はすべて WSL のシェル内で行います。
既に WSL が入っている場合は
wsl --updateで最新に。
Claude Code 本体
まずは主役の Claude Code を入れます。公式推奨のネイティブインストーラを使います(バックグラウンドで自動更新されるのがラク):
curl -fsSL https://claude.ai/install.sh | bash
シェルを再読み込みして確認:
claude --version
初回起動時はブラウザ経由で認証が走ります:
claude
利用には Pro / Max / Team / Enterprise など Claude Code 対応のプランが必要です(無料の Claude.ai プランでは使えません)。
Node 派の方はnpm install -g @anthropic-ai/claude-codeでも OK(Node 18+ が必要。後述の nvm セットアップ後に実行してください)。
uv(Python パッケージ/プロジェクトマネージャ)
curl -LsSf https://astral.sh/uv/install.sh | sh
シェルを開き直すか source ~/.bashrc で PATH を反映。確認:
uv --version
nvm(Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
URL 中のバージョン(
v0.40.4)は古くなることがあるので、公式 README の最新に合わせてください。
同じくシェルを再読み込み。LTS を導入しておきます:
nvm install --lts
nvm use --lts
node --version
Node に同梱される npm は古いことが多いので、更新しておきます:
npm install -g npm@latest
npm --version
これで土台は完成です。
CLAUDE.md を書く
CLAUDE.md はプロジェクト直下に置くだけで Claude Code が自動的に読んでくれる プロジェクトの流儀メモ です。ここに環境の方針を書いておけば、Claude Code に毎回指示しなくても同じ手順で進めてくれます。
筆者が使っているテンプレはこちらです:
# CLAUDE.md
## 開発環境
- OS: WSL (Linux)
- `uv` と `nvm` はインストール済み
## 仮想環境の方針
Python / Node.js を利用する際は、**プロジェクト直下**に仮想環境を作成すること。グローバル環境は使わない。
### Python (uv)
```bash
# 新規プロジェクト
uv init # pyproject.toml 等を生成
uv init --python 3.12 # Python バージョンを指定する場合
# ↑ 生成される main.py / 空 README.md は不要なら削除
# 既存プロジェクト
uv sync # pyproject.toml から .venv を復元
# パッケージ追加
uv add <package>
# 実行(venv を activate しない)
uv run <script.py>
uv run python -m <module>
```
### Node.js (nvm)
LTS は導入済み。プロジェクト直下で:
```bash
# 新規 ─ 共通: Node バージョンを固定
echo "lts/*" > .nvmrc # 最新 LTS で固定
echo "22.17.0" > .nvmrc # バージョンを指定する場合
nvm install && nvm use
# 新規 ─ A) プレーン(ライブラリ、CLI 等)
npm init -y # package.json のみ作成
# 新規 ─ B) フレームワーク scaffold(プロジェクト直下に展開)
npm create vite@latest . # Vite (React / Vue / Svelte 等)
# 他に Next.js / Nuxt / Astro / Remix / Qwik など
npm install # scaffold した package.json から依存を導入
# 既存プロジェクト
nvm install # .nvmrc のバージョンが未導入なら入れる
nvm use # .nvmrc のバージョンに切替
npm ci # package-lock.json どおりに node_modules/ を復元
# パッケージ追加
npm install <package>
```
## 注意
- 初期化コマンドが生成した不要なファイル(`main.py` / 空 `README.md` 等)は削除する
- `.gitignore` は `.venv/` と `node_modules/` を最低限含める(`uv init` は Python 向けのみ生成)
- グローバルに `pip install` / `npm install -g` はしない(例外: `npm install -g npm@latest` で npm 自体の更新は可)
- Python は `.venv` を activate せず、必ず `uv run` 経由で実行する
ポイント解説
個々のルールには「Claude Code を安定して動かすための理由」があります。ひとつずつ見ていきます。
新規と引継ぎの分岐を宣言しておく
Claude Code は git clone 直後のリポジトリにも、空ディレクトリにも投入されます。どちらの状態かで打つコマンドは違うので、CLAUDE.md に分岐を明示しておくと「init すべきでないのに init してしまう」「sync で済むのに手動で入れ直す」といった事故が減ります。
| 新規(ゼロから) | 引継ぎ(既存を復元) | |
|---|---|---|
| Python (uv) | uv init |
uv sync |
| Node.js (npm) |
npm init -y / npm create …
|
npm ci |
ロックファイルから決定的に再現する
uv sync / npm ci はロックファイル(uv.lock / package-lock.json)を唯一の真実として環境を復元します。一方 npm install は場合により lock を書き換えるので、引継ぎでは必ず npm ci。Claude Code が別日・別マシンで触っても同じ結果になるのは、この一貫性のおかげです。
| ロックファイル | 挙動 | |
|---|---|---|
npm install |
なくても動く | 足りないものを入れる、場合により lock を更新 |
npm ci |
package-lock.json 必須 |
node_modules/ を消してから lock どおりに再現 |
言語バージョンもファイルで共有する
パッケージだけでなく 言語ランタイム自体のバージョンもリポジトリに残します。
-
Python (uv):
uv init --python 3.12で.python-versionとpyproject.tomlのrequires-pythonが生成され、以降uv runが自動でそのバージョンを選びます -
Node.js (nvm):
.nvmrcにlts/*や22.17.0を書き、nvm useが引数なしで読み取ります
uv run でシェル状態から切り離す
Claude Code はコマンドごとに新しいシェルを立てることが多く、source .venv/bin/activate した状態は次のコマンドまで保持されません。uv は uv run <script> が毎回 .venv を参照するので、そもそも activate を使わない設計に寄せられます。「さっき activate したはずなのに import できない」という罠を根本から潰せます。
フレームワークは npm create で雛形を引き込む
React / Vue / Svelte / Next.js などを使うなら、npm init -y ではなく公式 scaffolder を使います:
npm create vite@latest . # Vite (React / Vue / Svelte 等)
# 他に Next.js / Nuxt / Astro / Remix / Qwik など
. を渡すとカレントディレクトリに展開されます。scaffolder は依存を自動インストールしないので、直後に npm install が必要な点だけ覚えておけば OK です。
初期化の"お節介"は掃除する
uv init は main.py と空の README.md を勝手に作ります。使わないものはすぐ削除。.gitignore は uv init 側が Python 向けのみ出すので、Node を併用するなら node_modules/ を追記して統合しておくと後々ラクです。
効果
この環境を整えてから、Claude Code に「ちょっとこの URL の内容を取ってきて CSV にして」みたいなタスクを投げても、勝手に uv init → uv add requests → uv run script.py まで一気通貫で走らせてくれるようになりました。CLAUDE.md があるとコマンドのブレがほぼ無くなり、結果として毎回の指示が短くて済みます。
まとめ
- WSL + uv + nvm が現時点での最小構成
-
CLAUDE.mdにルールを書いて Claude Code に読ませる - プロジェクト毎に仮想環境、activate しない、ロックファイルで再現