C.W.K.
Stream
Lesson 01 of 07 · published

Installing MLX Without Hating Yourself

~10 min · installation, conda, rosetta

Level 0Curious
0 XP0/51 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

The two-line install (and why it sometimes goes sideways)

pip install mlx mlx-lm in a native ARM Python env. That is the entire intended workflow. Most failures aren't really MLX failures — they're Python-environment failures that show up at the moment you import MLX.

This lesson is short on purpose. The point is to get a clean, reproducible install in a dedicated env, run the verify check, and walk away knowing you can come back to a working setup any day of the week.

Use a dedicated conda env (recommended)

I keep MLX in its own conda env (named, creatively, mlx) and never let it share an env with other ML stacks. The reason isn't religious — MLX has light dependencies and rarely conflicts with anything — it's reproducibility. When you come back in three months and the breaking-change train has rolled through, having a single-purpose env means you upgrade one thing.

The Rosetta trap, in detail

If your python is running under Rosetta x86 emulation, MLX's pip install may quietly succeed and then SIGSEGV on first import mlx.core. The reason: pip resolves a dependency wheel for the wrong architecture and the linker only finds out at import time. The fix is to use a Python that itself reports arm64 from platform.machine().

The cleanest way to guarantee that on macOS is miniforge (or modern miniconda, which now ships native ARM by default). Both create environments where every Python interpreter is genuinely ARM. The one trap to avoid: do not install miniconda from the legacy x86_64 installer on Apple Silicon — the env will look fine and quietly use Rosetta.

Verify, then move on

Three checks; if all three pass you are done with this lesson:

  1. uname -m prints arm64
  2. python -c "import platform; print(platform.machine())" also prints arm64 (this is the one Rosetta lies about)
  3. import mlx.core as mx; print(mx.__version__) succeeds and prints a version

If you fail step 2 specifically, your Python is under Rosetta — fix that before anything else, no matter how tempting it is to "just try the import and see."

Code

Create the dedicated env (one-time)·bash
# If you already have miniforge or modern miniconda installed:
conda create -n mlx python=3.11 -y
conda activate mlx
pip install --upgrade pip
pip install mlx mlx-lm

# Always upgrade before serious work — MLX moves fast:
pip install -U mlx mlx-lm
Three-check verify (run inside the env)·bash
# 1. Shell-level architecture
uname -m
# Must print: arm64

# 2. Python-level architecture (this is the load-bearing one)
python -c "import platform; print('arch:', platform.machine())"
# Must print: arch: arm64
# If it prints x86_64, your Python is under Rosetta — DO NOT proceed.

# 3. MLX import + version
python -c "import mlx.core as mx; print('mlx:', mx.__version__)"
python -c "import mlx_lm;        print('mlx-lm:', mlx_lm.__version__)"

# Verified output (2026-05-03):
#   arm64
#   arch: arm64
#   mlx: 0.31.2
#   mlx-lm: 0.31.3

External links

Exercise

Create the dedicated mlx conda env from scratch (or, if you already have one, do conda env remove -n mlx and recreate it — this is your reproducibility test). Run the three-check verify. Then add mlx-check (or your equivalent) to your shell config and re-source your shell so the function is available. Time how long the whole thing takes — under 5 minutes is the bar. The point is to feel that this setup is cheap to redo, not precious to preserve.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.