Your terminal now uses the PHP version you set with herd isolate. When you cd into an isolated site, php,
composer and artisan switch to that version, in subfolders too. When you leave, they switch back to Herd's default.
Works in zsh, bash, fish, PowerShell and Nushell, on macOS and Windows.
Herd's own herd php and herd composer only do this from the site's root folder, and only with the herd prefix.
You need Laravel Herd on macOS or Windows, and a site isolated with
herd isolate <version>. Open a new terminal when you're done.
Pick your plugin manager:
-
antidote: add
HelgeSverre/herd-php-autoswitchto~/.zsh_plugins.txt -
zinit:
zinit light HelgeSverre/herd-php-autoswitch -
zap:
plug "HelgeSverre/herd-php-autoswitch" -
sheldon:
sheldon add herd-php-autoswitch --github HelgeSverre/herd-php-autoswitch -
oh-my-zsh: clone the repo into your custom plugins, then add
herd-php-autoswitchtoplugins=(...)in~/.zshrc:git clone https://github.com/HelgeSverre/herd-php-autoswitch ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/herd-php-autoswitch
No plugin manager? Clone the repo and source the plugin:
git clone https://github.com/HelgeSverre/herd-php-autoswitch ~/.herd-php-autoswitch
echo 'source ~/.herd-php-autoswitch/herd-php-autoswitch.plugin.zsh' >> ~/.zshrcIt can go anywhere in ~/.zshrc.
Works with bash 3.2 (the one macOS ships) and newer.
git clone https://github.com/HelgeSverre/herd-php-autoswitch ~/.herd-php-autoswitch
echo 'source ~/.herd-php-autoswitch/herd-php-autoswitch.bash' >> ~/.bashrc- Terminal.app reads
~/.bash_profile, not~/.bashrc. Make sure your~/.bash_profilesources~/.bashrc. - bash switches when the next prompt appears, not during
cd. So incd other-project && php -v,phpis still the old version. Run the two commands on separate lines.
Works with fish 3.5 and newer. With Fisher:
fisher install HelgeSverre/herd-php-autoswitchWithout Fisher, copy conf.d/herd-php-autoswitch.fish into ~/.config/fish/conf.d/.
Works with PowerShell 7 and Windows PowerShell 5.1. Clone the repo and load the module from your profile:
git clone https://github.com/HelgeSverre/herd-php-autoswitch "$HOME\herd-php-autoswitch"
if (-not (Test-Path $PROFILE.CurrentUserAllHosts)) { New-Item -ItemType File -Path $PROFILE.CurrentUserAllHosts -Force }
Add-Content $PROFILE.CurrentUserAllHosts 'Import-Module "$HOME\herd-php-autoswitch\HerdPhpAutoswitch"'- PowerShell 7 and 5.1 use separate profiles. Run the last two lines in each one you use.
- 5.1 blocks profile scripts by default. Allow them once with
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned. - 5.1 switches when the next prompt appears, like bash. PowerShell 7 switches right away.
Clone the repo:
git clone https://github.com/HelgeSverre/herd-php-autoswitch ~/.herd-php-autoswitchThen add this line to your config (run config nu to open it):
source ~/.herd-php-autoswitch/herd-php-autoswitch.nuNushell switches when the next prompt appears, like bash.
cd ~/Herd/my-project
php -v # your isolated version
composer --version 2>&1 | grep 'PHP version' # the same version
which php # ~/.cache/herd-php-autoswitch/83/phpOn Windows, (Get-Command php).Source should end in \.config\herd\bin\php83\php.exe.
When you run herd isolate 8.3, Herd writes this line at the top of the site's nginx config, for example
~/Library/Application Support/Herd/config/valet/Nginx/my-project.test:
# ISOLATED_PHP_VERSION=8.3
Herd reads the same line for herd php. Each time you change folders, the hook:
- finds the Herd site you're in, the same way Herd does: a folder linked with
herd link(named after the link), or a folder directly inside a parked path (herd park). It checks the current folder first, then each parent folder. - reads the PHP version from that site's config line,
- puts that version's folder first on your
PATH:- on macOS,
~/.cache/herd-php-autoswitch/83, which holds aphplink to Herd'sphp83 - on Windows, Herd's own
bin\php83folder
- on macOS,
composer, php artisan and tools in vendor/bin all use the first php on your PATH, so they follow along. Each
switch takes 1 to 2 ms.
If a site is isolated to a PHP version that isn't installed in Herd, you get a one-line warning when you enter it, and the default PHP stays in place.
- Tested with Laravel Herd 1.30 on macOS, with zsh 5.9, bash 3.2 and 5.3, fish 4.9, PowerShell 7.6 and Nushell 0.115.
- Works alongside direnv and mise in zsh, bash and fish (tested with direnv 2.37 and mise 2026.9).
- CI tests every shell on macOS, Ubuntu and Windows, including Windows PowerShell 5.1. It uses a fake Herd install, copied from Herd's documented folder layout.
- It changes the shell you're typing in. Scripts, child shells and IDE tasks keep the PHP version that was active when
they started, even if they
cdinto another project. - Aliases win over
PATH. If you havealias php='herd php'oralias composer='herd composer', remove them. - Git worktrees: a worktree inside the project folder uses the project's PHP version. A worktree elsewhere, such as
git worktree add ../my-project-feature, is a separate site to Herd (or no site at all), so it uses the default PHP until you runherd isolatein it. Outside your parked folders, runherd linkthere first. - Only
herd isolateis read. PHP versions in.valetrcor.valetphprcfiles are ignored. - It only changes your own terminal. To make Composer pick packages for your production PHP version on every machine,
also run
composer config platform.php 8.3.30in the project.
If you run herd isolate or herd unisolate inside a site, refresh with:
- zsh, fish, Nushell:
cd . - bash:
unset _herd_autoswitch_pwd - PowerShell:
Update-HerdPhpAutoswitch
- zsh, bash, Nushell: remove the
sourceline (or the plugin entry) and delete the cloned folder. - fish:
fisher remove HelgeSverre/herd-php-autoswitch - PowerShell: remove the
Import-Moduleline from your profile and delete the cloned folder. - On macOS, also run
rm -rf ~/.cache/herd-php-autoswitch.
The tests use a fake Herd install in a temporary folder, so you don't need Herd to run them:
sh tests/run.sh # zsh, bash, fish (whichever are installed)
pwsh -NoProfile -File tests/run.ps1 # PowerShell module
nu -n tests/run.nu # Nushell
sh tests/nu-repl.sh # Nushell REPL (needs expect)To re-record the demo GIF (needs VHS and Herd with PHP 8.3 and 8.4). It creates a temporary Herd site; the second command removes it:
vhs docs/demo/demo.tape
sh docs/demo/cleanup.shMIT. See LICENSE.

