Most “set up your Mac for development” guides stop at a runtime. You install PHP or Node, you get a version number back from the terminal, and the guide declares victory. Then the first real project needs a database, a hostname that is not localhost:3000, a certificate the browser will not warn about, somewhere for outgoing mail to land, and a way to keep all of that from colliding with the next project. A local development environment is those six layers, not the first one.
What a local development environment on a Mac has to include
Every route below is judged on the same six layers, because a route that covers three of them is not cheaper than one that covers six — it just moves the other three onto you.
- Runtimes, per project. Project A on PHP 8.2 while project B is on 8.4, Node 20 next to Node 22. Version switching that is global is version switching that breaks something every Tuesday.
- A web server in front.Something that maps a hostname to a process, so two projects can both be “the site” without arguing over port 3000.
- Databases, per project. A MySQL or PostgreSQL instance with its own data directory, and its credentials reaching the app without being typed into a
.envby hand. - DNS and a real hostname.
https://acme.testrather than a port number — which matters the moment you touch OAuth callbacks, cookies scoped to a domain, or anything that reads the Host header. - Trusted HTTPS. Not a self-signed certificate you click through. A certificate signed by a CA your Mac already trusts, so Service Workers, secure cookies and the clipboard API behave locally the way they behave in production.
- Mail capture.A local SMTP sink, so a password-reset email in development lands in an inbox you own rather than in a real customer's.
Route 1: Homebrew, by hand
Install the runtimes and services directly and wire them together yourself. It is the most honest route — nothing is hidden, and you will understand every part of it — and it is the one with the highest ongoing cost. A working PHP setup on macOS 26 Tahoe, which ships no PHP at all, runs to roughly thirty command sequences and six hand-edited config files before the first page loads. Multiple versions mean the Homebrew link/unlink dance or the shivammathur tap; multiple Node versions mean nvm or fnm and a shell hook. Add nginx or Caddy, dnsmasq for .test, and mkcert for certificates, and you have built an environment that only you can operate.
Choose it when you have one or two long-lived projects on stable versions and you would rather own the configuration than learn a tool.
Route 2: Docker
Containers solve version isolation and service provisioning in one move, and on a team they solve something nothing else does: parity with the image that runs in production. The cost on a Mac is structural rather than fixable — macOS cannot run Linux containers natively, so every container lives in a Linux VM that holds memory whether it is busy or not, and file syncing between macOS and that VM is slower than the filesystem for the I/O-heavy directories web projects are made of. We go through the trade in detail in the Docker alternative guide and rank the runtimes in the Docker Desktop alternatives roundup, and the honest summary is: keep Docker when you need image parity or a Linux-only dependency, and question it when you are running a PHP app and a MySQL container on a laptop.
Choose it when production is containers, or a dependency genuinely will not run on macOS.
Route 3: a PHP-first managed environment
Tools in this family install native runtimes for you and handle the server, the .test domain and the certificate. Laravel Valet is the lean CLI original; Laravel Herd is the polished GUI successor; MAMP is the long-running classic. They are genuinely good at the layer they cover, and the wall is always the same one: they are built around PHP, so Node apps, additional database engines, mail capture and tunnels are either a Pro upgrade or a separate tool. Herd Pro is $99/yr; ServBay is the polyglot member of this family and caps its free tier at five sites.
Choose one when your work is PHP and the extra layers are things you genuinely do not need.
Route 4: one managed environment for every stack
The fourth route is the same managed idea without the language boundary: native runtimes for PHP and Node side by side, per-project databases, DNS, certificates and mail capture from one app, with no VM underneath. PortBay is the version of this we build, and it is free and open source for six projects, so the disclosure is worth making plainly before the list.
- Runtimes detected from the folder. Point it at a project and it reads the stack, fills in the start command and port, and runs PHP-FPM and Node versions side by side as native processes.
- A real domain with trusted HTTPS, in one click. mkcert issues the certificate, a managed resolver answers for
.test, and a bundled Caddy routes it. No hosts file, no nginx config. - Databases provisioned per project. MySQL, MariaDB, PostgreSQL, Redis, MongoDB or Memcached with isolated data directories, injected into the project's process as
DATABASE_URLandDB_*on every start. - Mail captured locally and public tunnels. A bundled Mailpit inbox catches outgoing mail; one click gives a project a public HTTPS URL for a webhook or a client demo.
- Your existing setup imported. On first launch it reads the sites you already run in Herd, ServBay, MAMP and Valet — paths, versions, domains and databases — so this is not a migration you schedule.
Which route fits
- One project, stable versions, you like configs: Homebrew by hand.
- Production is containers, or a Linux-only dependency: Docker, on a slimmer runtime.
- PHP only, and you want it to be someone else's problem: Valet or Herd.
- Several projects across several stacks: a polyglot managed environment, which is the case PortBay is built for.
The layer most guides still skip
One thing has changed about this list since 2024. If you hand work to an AI coding agent, the environment stops being a convenience and becomes the thing that decides whether the agent's output is worth reading. An agent that cannot load the page it just changed, query the database it just migrated or read the log it just filled is writing code it cannot check — and you end up verifying every line by hand. That argument, and what it implies for how you set your machine up, is its own guide.
If the fourth route is the one that fits, PortBay is a free download — signed and notarized for Apple Silicon and Intel, open source under AGPL-3.0, and it imports what you already run.
