Skip to content

Requirements

macOS 13 (Ventura) or later to run — macOS 15 (Sequoia) for everything

Section titled “macOS 13 (Ventura) or later to run — macOS 15 (Sequoia) for everything”

Two numbers, on purpose. Through 0.8.6 the floor was macOS 15; now the app runs on macOS 13 and 14, and it says so itself: at first launch on such a Mac the wizard reads “This Mac runs macOS 13.6 — rexenv works here with older versions of some components and without PostgreSQL and PHP 8.0. Everything is available on macOS 15 or later.” Below 13 nothing is offered a download.

What “older versions” means is a different pin per component — the last build of each that still loads on that macOS, measured on both chips before it was pinned. The exact numbers are on every row of Pinned versions; in short, on macOS 13:

Component macOS 15+ macOS 13
MySQL 8.4.6 / 8.0.44 8.4.3 / 8.0.40
MariaDB 12.3.2 / 11.4.12 12.0.2 / 11.4.8
Redis 8.8.0 8.2.1
Apache 2.4.68 2.4.65
Xdebug 3.5.3 for 8.1–8.5 3.4.5 for 8.1–8.4 — none for 8.5
cloudflared 2026.6.1 2025.4.0 (also on macOS 14)
PostgreSQL 18.6 / 17.11 / 16.15 not available (macOS 14: 16.4.0 only)
PHP 8.0 8.0.30 not available

macOS 14 differs from 15 in only two rows: cloudflared 2025.4.0 and PostgreSQL 16.4.0 alone. Everything else on 14 is the standard pin.

What is not available is refused by name, with the macOS it needs, wherever you could choose it — the Databases page, the New Site dialog’s Database field, rex db versions and the agent tools all answer with the same sentence, for example “Needs macOS 14 or later — this Mac runs macOS 13.6.” The row stays visible with that reason; nothing is silently hidden. PHP 8.0 sits in Settings with the sentence as a badge and its Install button off.

One universal build runs natively on both. There is no separate download to choose and no Rosetta involved.

rexenv does not bundle its stack. It downloads each component — PHP, nginx, Caddy, MySQL, Mailpit and the rest — the first time you actually use it, verifies it against a pinned checksum, and prepares it for macOS.

Budget up to ~600MB across a full cold start, spread over your first few actions rather than taken all at once. After that rexenv works offline; nothing re-downloads unless you add a component you have not used before.

The reason it works this way rather than shipping a 600MB app: you get seven PHP versions, four database engines and three web servers available on demand, and you only pay for the ones you touch.

Plan on 2–4GB for a working setup: the app itself is small, the downloaded components are most of it, and your databases sit alongside them under ~/Library/Application Support/dev.rexenv.rexenv/. Your sites are in ~/rexenv/Sites.

rexenv binds 80 and 443 for the edge proxy, and a set of high ports for everything else — deliberately offset from the usual defaults so it never collides with a MySQL, Mailpit or nginx you already run.

If something else already holds 80 or 443, rexenv tells you what is holding it rather than failing quietly. rex doctor reports the same from a terminal.

  • No Docker, no VM, no Homebrew installation of the stack itself.
  • No /etc/hosts editing. A DNS resolver handles *.rex for you.
  • No Xcode, and no Command Line Tools, for the stack — Caddy, nginx, PHP, MySQL, Mailpit, Adminer and WP-CLI all install on a Mac that has never seen a compiler, and so do Redis, MariaDB, Apache and Xdebug.

On all three systems the web server on :443, the .rex DNS route and the resolver’s port are machine-wide, so a second account on the same machine cannot run its own rexenv beside the first — its services would find those ports taken. Use rexenv from one account. On Windows there is one more machine-wide piece, the \rexenv\dns-agent scheduled task. A second account’s launch finds it registered for the first and leaves it alone — its log says the task is “registered for another account on this computer”, naming that account’s SID — and .rex is answered by that second copy only while it runs. Through 0.8.10 the second launch silently took the task over, so the resolver then started at the wrong account’s sign-in.