Skip to content

Frameworks & non-PHP apps

When you link a project, Butler picks a driver — the bit of logic that knows where a framework’s front controller and public directory live. Most of the time this is automatic; when it isn’t, you can name the driver yourself.

Butler inspects the project directory and recognizes these frameworks from their tell-tale files:

FrameworkDetected by
Laravelan artisan file
WordPresswp-config.php (or wp-config-sample.php)
Symfonybin/console + public/
DrupalDrupal’s index.php / directory layout
StatamicStatamic’s markers on top of Laravel
Crafta craft executable + Craft layout

Anything it doesn’t recognize is served as a static site (files served directly) or, if the project ships a Valet-style LocalValetDriver.php, as a custom site using that driver.

Check what Butler chose with butler sites or the Sites section of the app.

To override detection, set the driver in the project’s butler.yml:

driver: laravel
publicPath: public # override the docroot if it isn't the driver default

Valid values: laravel, wordpress, symfony, drupal, statamic, craft, static, proxy, and custom.

Serving a JS dev server (Vite, Next, Nuxt, …)

Section titled “Serving a JS dev server (Vite, Next, Nuxt, …)”

For a project you run with your own dev server — a Vite, Next.js, Nuxt or similar process — use the proxy driver. Butler stops trying to run it as PHP and instead reverse-proxies your .test address to the dev server you’re running:

butler.yml
driver: proxy
proxy:
target: "127.0.0.1:3000" # where your dev server listens
websocket: true # tunnel WebSocket/HMR upgrades (default true)

Now https://my-app.test fronts your dev server on 127.0.0.1:3000 — you get a clean hostname and trusted HTTPS (great for features that require a secure context) while your framework’s own tooling handles hot reload. Start your dev server as you normally would; Butler handles the routing.

A folder of HTML/CSS/JS is served as-is — no configuration needed. To be explicit, or to serve a subdirectory, set:

driver: static
publicPath: dist

If you’re bringing a project from Valet that has a LocalValetDriver.php, Butler honors it — the site is treated as custom and routed through that driver, matching Valet’s behavior. See Valet & Herd compatibility.