Custom Domains
stack defaults new projects to .localhost because it resolves to loopback for free — no setup, no hosts file, no admin rights, since it's RFC 6761-special-cased. Coming from Herd or Laragon, you might prefer the shorter, more familiar .test instead. That works too — it just needs one one-time step first.
Why this needs a step at all
[project].domain is fully free-form in stack.toml — domain = "myapp.test" works today with zero code change, since Caddy (the actual router stack drives) doesn't care what string it's given. The gap is DNS resolution: unlike .localhost, .test is reserved by RFC 2606 but your OS doesn't automatically route it to loopback. Herd and Laragon don't get this for free either — they quietly automate it for you (writing per-project entries into the hosts file, or running their own resolver). This page is that same one-time automation, done manually, once, for every .test subdomain at once.
Windows: Acrylic DNS Proxy
Acrylic is a small local DNS proxy that supports wildcard entries in a custom hosts-like file. Needs admin rights, one-time.
Install Acrylic
Download and run the installer from the official Acrylic DNS Proxy page.
Add a wildcard entry
Open AcrylicHosts.txt (from the Acrylic UI's menu, or directly under its install folder) and add:
127.0.0.1 *.test
Restart the Acrylic service afterward (from its tray icon or Windows Services) so the change takes effect.
Point your network adapter at Acrylic
Network and Sharing Center → Change adapter settings → your active adapter's Properties → Internet Protocol Version 4 (TCP/IPv4) → Properties → set Preferred DNS server to 127.0.0.1. Do this for every adapter you actually use (Ethernet and Wi-Fi both, if you switch between them).
From here, any *.test domain resolves to loopback the same way *.localhost already did — including domains from projects you haven't created yet, since it's a wildcard, not a per-project entry.
macOS/Linux: dnsmasq
stack only ships Windows builds today — this section is here for when that changes, and for anyone running stack's source build on these platforms in the meantime.
Install and configure dnsmasq
$ brew install dnsmasq $ echo 'address=/.test/127.0.0.1' >> $(brew --prefix)/etc/dnsmasq.conf $ sudo brew services start dnsmasq
Register .test as a resolver domain
$ sudo mkdir -p /etc/resolver $ echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/test
macOS routes any *.test lookup through /etc/resolver/test to dnsmasq from here on, system-wide — no per-app configuration.
Avoid .dev (a real, ICANN-delegated TLD Google owns) and .local (claimed by Bonjour/mDNS on macOS) for this — .test is the one actually reserved for exactly this purpose.
Next
Once your TLD resolves, set it per-project the normal way: domain = "myapp.test" in stack.toml's [project] section, or answer the domain prompt with it when running stack new/stack init. See the Manifest Reference for the full [project] section.