skip to content

For local Laravel development, how do Herd and Valet serve an app differently from `php artisan serve`, and what does parking a directory do?

level: middleimportance: should knowfreq 32%

answer

  1. always-on web server vs per-terminal process
  2. Nginx plus dnsmasq in the background
  3. folder name becomes name.test
  4. ~/Herd, valet park, valet link
  5. artisan serve: 127.0.0.1:8000, one process

basics

~20 s

Herd and Valet keep Nginx running in the background and resolve *.test names, so every app inside a parked directory is served at foldername.test with no command. php artisan serve starts PHP's single-process built-in server on 127.0.0.1:8000 only while it runs.

solid answer

~40 s

`php artisan serve` launches PHP's built-in web server from `public/`, by default on `127.0.0.1:8000`, and it lives only as long as that terminal process. **Valet** (macOS, installed with Homebrew and `composer global require laravel/valet`, then `valet install`) and **Herd** (a native app for macOS and Windows that bundles PHP, Nginx, Composer and the `laravel` CLI) instead keep Nginx running permanently and route every `*.test` hostname to your machine. **Parking** a directory registers it as a parent: each sub-folder becomes a site named after the folder, so `~/Herd/vet-clinic` is served at `http://vet-clinic.test`. Valet parks with `valet park`, serves a single folder with `valet link`, adds HTTPS with `valet secure` and pins PHP per site with `valet isolate`; Herd creates `~/Herd` as its parked directory at install time.

code

bash · 8 lines
bash
# Built-in server, only while this terminal runs
php artisan serve --port=8080

# Valet (macOS): park a parent folder once
cd ~/Sites && valet park
# ~/Sites/vet-clinic is now http://vet-clinic.test
valet secure vet-clinic
valet isolate [email protected] --site=vet-clinic

go deeper

for a junior

Know that artisan serve gives you 127.0.0.1:8000 while it runs, and that Herd or Valet serve parked folders at foldername.test without a command.

for a middle

Explain the always-on Nginx plus DNS model, what park and link do, and the serve command's port retry and .env reload behaviour.

for a senior

Pick a local setup for the team, per-site PHP versions included, and keep queue, logs and Vite running beside Herd or Valet.

for a principal

Weigh a native toolchain such as Herd against a container-based setup for consistency with production, and document the choice for onboarding.

## Two ways to get a local URL A Laravel app answers HTTP through `public/index.php`, so locally you need something that sends requests there. There are two models: - **A process you start**: `php artisan serve` runs PHP's built-in web server for one app, while the command runs. - **A server that is always on**: Herd and Valet run Nginx in the background and map hostnames to folders, so apps are reachable without starting anything. ## `php artisan serve` The `serve` command runs `php -S host:port` with `public/` as the working directory and a small router script that returns static files directly and sends everything else to `index.php`. Its defaults and behaviour: - Host `127.0.0.1` (or `SERVER_HOST`) and port **8000** (or `SERVER_PORT`); `--host` and `--port` override them. - If the port is busy and you did not pass `--port`, it tries the next port, up to `--tries=10` times. - It restarts itself when `.env` changes, unless `--no-reload` is passed. - PHP documents its built-in server as a single-threaded development tool that should not be used on a public network, so one slow request blocks the next. `PHP_CLI_SERVER_WORKERS` can fork more workers, but Laravel honours it only together with `--no-reload`. ## Valet **Laravel Valet** is a macOS-only tool that needs Homebrew: 1. `composer global require laravel/valet`, then `valet install` sets up Nginx and DnsMasq to start with the machine; port 80 must be free. 2. `valet park` inside, say, `~/Sites` makes every sub-folder a site: `~/Sites/vet-clinic` answers at `vet-clinic.test`. 3. `valet link` serves just the current folder, optionally under another name; `valet links` lists them. 4. `valet secure vet-clinic` issues a local TLS certificate so the site works over HTTPS. 5. `valet use [email protected]` switches the global PHP; `valet isolate [email protected]` pins one site to a different version. The default top-level domain is `test`, changeable with `valet tld`. ## Herd **Laravel Herd** is a native desktop application for macOS and Windows. It bundles PHP and Nginx and provides the `php`, `composer`, `laravel`, `expose`, `node`, `npm` and `nvm` command-line tools. At install time it creates a parked directory, `~/Herd` (or `%USERPROFILE%\Herd` on Windows), and on macOS it uses dnsmasq for the `.test` names. The documented flow is `cd ~/Herd`, `laravel new vet-clinic`, `cd vet-clinic`, `herd open`. Herd Pro adds local MySQL, PostgreSQL and Redis services, mail viewing and log monitoring. ## Comparing them | | `php artisan serve` | Valet | Herd | |---|---|---|---| | Platforms | Anywhere PHP runs | macOS | macOS, Windows | | Web server | PHP built-in, one process | Nginx, always on | Nginx, always on | | URL | `http://127.0.0.1:8000` | `http://<folder>.test` | `http://<folder>.test` | | Needs a command per app | Yes | No, once parked | No, once parked | ## Choosing for a team Onboarding a new hire onto the clinic app, the choice usually comes down to these points: - **Mixed operating systems**: Herd covers macOS and Windows, Valet only macOS, and `php artisan serve` runs wherever PHP runs, including Linux. - **Several apps at once**: parked `.test` sites avoid juggling ports 8000, 8001 and 8002 across projects. - **Different PHP versions per project**: Valet pins one with `valet isolate`, while `php artisan serve` simply uses whichever `php` binary starts it. - **HTTPS locally**: needed for secure cookies or some browser APIs; `valet secure` covers it on Valet, while the built-in server speaks plain HTTP. - **Parity with a container-based production**: a Docker-based environment is a different option with its own topic. ## Practical consequences - The Laravel installer checks whether the new folder sits in a Herd or Valet parked path; if so it prints the `.test` URL instead of suggesting `composer run dev`. - Parking gives you HTTP serving; queue listeners, log tailing and Vite still need their own processes, so teams often keep `php artisan dev` and drop its `server` process. - Keep `APP_URL` in `.env` in line with the URL you actually browse, or generated links and redirects point at the wrong host.

  • What does php artisan serve do when port 8000 is already taken?
    If you did not pass `--port`, it increments the port and retries, up to the `--tries` limit, which defaults to 10, so you may land on 8001 or 8002. If you did pass `--port`, it does not retry and exits with the server's error. Remember to update `APP_URL` if links must match the port.
  • When would you use valet link instead of valet park?
    `valet park` serves every sub-folder of a parent directory, which suits a projects folder. `valet link` serves one folder that lives outside any parked path, and lets you choose the hostname, for example `valet link clinic-api` to get `clinic-api.test`. `valet links` lists linked sites and `valet unlink` removes one.

php artisan serve is a food truck you drive out and park for one event, then take home. Herd and Valet are a permanent food court: every stall placed in the parked hall automatically gets a sign with its own name, and the court is open whether or not you are standing there.

saying these in an interview costs you the question

  • php artisan serve runs a multi-worker Nginx behind the scenes
  • Herd only works if you also install Valet separately
  • Parking a directory serves only the folder you run it in
  • Valet runs natively on Windows and Linux
  • A parked site answers only while php artisan serve is running