language-runtimes
Skill0 starsChanged 3 months agoMITView on GitHub
Sets up language runtimes on macOS the modern way - mise for Node LTS, Java Temurin LTS, Go and Ruby, uv for Python, rustup for Rust; one manager per runtime, preserving existing nvm/pyenv/jenv first. Use for "install node/python/java versions", "set up mise/uv", "runtime version managers", "manager conflicts". Not for project dependencies, pnpm/databases, Android JDK wiring, or OS packages.
- Installs packages
In this repository21 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-skillSkill
- publish-repoSkill
- ai-dev-toolsSkill
- cloud-dev-setupSkill
- dev-cli-toolsSkill
- docker-on-macSkill
- dotfiles-setupSkill
- editor-setupSkill
- git-ssh-identitySkill
- homebrew-setupSkill
- mac-dev-appsSkill
- mac-maintenanceSkill
- macos-defaultsSkill
- macos-dev-setupSkill
- macos-security-baselineSkill
- macos-system-prepSkill
- mobile-dev-setupSkill
- web-dev-setupSkill
- zsh-setupSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 45
Never sudo pip/npm/gem and never modify system Python/Ruby — macOS's runtimes are part of the OS.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Language Runtimes
Installs the full runtime lineup — Node, Python, Java, Go, Rust, Ruby on request — under the modern manager set: mise for everything except Python (uv) and Rust (rustup). One manager per runtime; competing managers racing to put shims first in PATH is the top cause of "node is weird" machines.
When NOT to use
- Project-level deps (
npm install, venvs, requirements.txt) → native - pnpm/corepack, databases →
web-dev-setup - JDK specifically for Android Studio/Gradle →
mobile-dev-setup - Upgrading installed runtimes →
mac-maintenance
Prerequisites
brew present (→ homebrew-setup).
The rules
- Detect before installing.
[ -d ~/.nvm ],command -v pyenv jenv mise asdf uv fnm volta conda sdk,grep -E 'nvm|pyenv|jenv|mise|asdf|fnm|volta|conda|sdkman' ~/.zshrc ~/.zprofile ~/.zshenv 2>/dev/null, andtype -a node python3 javato see what actually wins PATH today. - Preserve existing. A working manager stays (an nvm/pyenv/jenv setup is not broken — don't stack mise on top of it for the same runtime). Multiple already present → show the conflict, ask which to keep, disable the loser's init line (with consent), don't delete its data. An explicit user tool choice wins ("install nvm" means nvm — classic-manager details: references/runtime-versions.md).
- Boundaries: uv owns Python entirely (don't enable mise's python); rustup owns Rust; mise owns node/java/go/ruby.
Safety rails
.zshrcadditions are grep-guarded appends; back up before edits.- Never
sudo pip/npm/gemand never modify system Python/Ruby — macOS's runtimes are part of the OS. - Disabling a manager = comment/remove its init lines; deleting
~/.nvm,~/.pyenvetc. only on explicit request (it deletes installed runtimes).
Workflow (fresh machine — the default)
brew install mise uv rustup
grep -q 'mise activate' ~/.zshrc || echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
eval "$(mise activate zsh)" # current shell too
# Node - LTS
mise use -g node@lts
# .nvmrc/.node-version support is off by default:
mise settings add idiomatic_version_file_enable_tools node
# Java - Temurin LTS (plain temurin tracks the latest NON-LTS - pin the LTS)
mise use -g java@temurin-25
# Go
mise use -g go@latest
# Ruby (on request; never system Ruby - it's EOL 2.6, immutable)
# mise use -g ruby@3
# Python - uv owns it
uv python install 3.13 # 3.14 is current; 3.13 has the broadest wheel coverage - ask
# Plain `python3` on PATH from uv too? add --default (shims into ~/.local/bin -
# make sure that dir is on PATH):
# uv python install 3.13 --default
uv tool install ruff # CLI tools (pipx replacement; installs to ~/.local/bin)
# projects: uv init / uv add / uv run / uv sync
# Rust - rustup (brew formula; NOT brew's `rust`)
export PATH="$(brew --prefix rustup)/bin:$PATH" # + grep-guarded .zshrc line
rustup default stableExisting classic setups (nvm / pyenv / jenv)
Preserve-existing wins — keep them running, don't migrate unasked:
- nvm: already sourced from
.zshrc;nvm install --lts && nvm alias default 'lts/*'for a new version. Slow-startup mitigation:--no-useon the source line (defers activation; doesn't zero the cost — full lazy-load needs zsh-nvm or switching to mise/fnm). - pyenv: builds from source — needs
brew install openssl readline sqlite3 xz zlib tcl-tk; init lines per its README. uv coexists fine (it can use pyenv's interpreters). - jenv:
jenv add <jdk-home>,jenv versions,jenv global <name>; JDKs from versioned Temurin casks (brew install --cask temurin@25).
Migration to mise/uv only on explicit request: install the modern manager, move the global default over, comment out the old init lines, leave the old data dirs untouched.
Verify
sh "${CLAUDE_SKILL_DIR}/scripts/check.sh"Fresh shell: node -v (LTS major), python3 --version or uv run python
--version, java --version (Temurin LTS), go version, rustc
--version — each resolving from its one manager (type -a node shows
exactly one manager's path).
Output spec
Done means: every requested runtime installed with exactly one manager active per runtime, global defaults set, init lines present once, fresh-shell verification passes, and any pre-existing setup was preserved or consciously replaced.
Gotchas
- Two managers, one runtime = flaky versions + slow shells.
type -a node/which -a python3expose the race. - Plain
temurincask /java@latest= newest non-LTS JDK; the LTS is the versioned pin (temurin-25). Multiple JDKs:/usr/libexec/java_home -V. uv self updateerrors on brew installs (standalone-installer feature) — update viabrew upgrade uv.- mise's
.nvmrcparsing is opt-in (theidiomatic_version_filesetting above); without it, per-project Node pins silently don't apply. - Node's corepack no longer ships with Node 25+ — pnpm/yarn install
changed; that's
web-dev-setupterritory. - Homebrew's
openjdkformulae are keg-only and need asudo ln -sfnstep beforejava_homesees them — Temurin casks and mise's java avoid this. - Facts that age (current LTS lines, versions, classic-manager commands): references/runtime-versions.md.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

