Sites

A site is a directory BitL serves at name.test. Link projects one at a time, or park a folder and let every subdirectory become a site.

Link

One directory → one domain

Park

Every subfolder becomes a site

HTTPS

Locally-trusted certificates

Isolate

Per-site PHP version

Linking a site

cd ~/Sites/my-appbitl link                          # → http://my-app.test

The domain defaults to the directory name. The first argument can be a path or a domain — BitL checks whether it exists on disk:

bitl link shop                     # link the current dir as shop.testbitl link ~/Code/api               # link ~/Code/api as api.testbitl link ~/Code/api --domain=backend   # link ~/Code/api as backend.testbitl link --tld=localhost          # use a different TLD for this site

List what is linked, and remove sites:

bitl list                          # domain, path, PHP version, SSL, linked or parkedbitl unlink shopbitl unlink --group ~/Sites        # every site from one parked directorybitl unlink --all --yes            # everything, no prompt

Parking a directory

Park a folder and every subdirectory is served automatically — no linking needed. While the app is running it watches parked folders, so a new project folder becomes a site within a second.

bitl park ~/Sites                  # ~/Sites/blog → blog.test, ~/Sites/shop → shop.test …bitl parked                        # parked directories and the sites they producebitl unpark ~/Sites
Tip. If a subfolder's name is already taken by a linked site, the linked site is kept. Park your projects folder for convenience, then bitl link --domain the odd one that needs a different name.

HTTPS

bitl secure my-app                 # → https://my-app.testbitl unsecure my-app

During setup (the first-launch screen, or bitl init) BitL creates a local certificate authority, valid 10 years, in ~/Library/Application Support/BitL/ssl/ca/, then signs a certificate for each secured site (valid 825 days, the maximum Apple platforms accept). BitL trusts the CA for your user account automatically — no password needed.

If macOS still reports the CA as untrusted, bitl secure says so and prints the one command that trusts it system-wide. Run it once:

sudo security add-trusted-cert -d -r trustRoot \  -k /Library/Keychains/System.keychain \  ~/Library/Application\ Support/BitL/ssl/ca/BitLCA.pem
Note. Firefox keeps its own certificate store. Set security.enterprise_roots.enabled to true in about:config so it honours the macOS keychain, or import BitLCA.pem under Settings → Certificates.

Framework detection

BitL inspects each site and picks a driver that knows its document root and front controller. First match wins:

DriverDetected whenDocument root
Statamicartisan and a content/ directorypublic/
Laravelartisan existspublic/
Symfonybin/console and public/index.phppublic/
WordPresswp-config.php or wp-config-sample.phpproject root
Staticnothing above matchedproject root

Need something the drivers don't cover — an SPA, a reverse proxy to a Node server? Apply an nginx template to the site.

Per-site PHP version

Pin a site to a PHP version; it gets its own PHP-FPM pool, while everything else keeps the global default.

bitl isolate 8.2                   # the site in the current directorybitl isolate 8.2 legacy-shop       # a named sitebitl php pools                     # which pools run, and which sites use them
Warning. The version comes first: bitl isolate <php-version> [domain]. The version must be installed — see PHP.

Site groups

Group related sites and change them together.

bitl group create acmebitl group add acme acme-appbitl group add acme acme-apibitl group list bitl group apply acme --php 8.4 --secure   # every site in the groupbitl group apply acme --unsecurebitl group remove acme-api                 # take a site out of its groupbitl group delete acme

Docker containers

Give a container a .test domain (with HTTPS if you like) via an nginx reverse proxy.

bitl docker link api 8080          # api.test → 127.0.0.1:8080bitl docker proxy my-container     # auto-detect domain and port from a running containerbitl docker list                   # proxies, plus running containersbitl docker unproxy my-containerbitl docker unlink api

docker proxy uses the container's first published port and its name as the domain. Override either with labels:

compose.yaml
services:  api:    labels:      bitl.domain: backend      # → backend.test      bitl.port: "8080"

Sharing over a tunnel

Show a local site to a client or test a webhook. BitL drives whichever tunnel tool you have installed.

bitl share my-app.test                    # cloudflared, then ngrok, then exposebitl share my-app.test --provider ngrokbitl share my-app.test --port 443bitl share --listbitl share my-app.test --stop
Note. BitL does not bundle a tunnel client. Install one first, e.g. brew install cloudflared.

Opening sites

bitl open                  # the site for the current directory, in your browserbitl open my-app           # a named sitebitl open my-app --editor  # its folder in your editorbitl open my-app --terminalbitl edit my-app           # its folder in $EDITOR (falls back to VS Code / Sublime)

Choose the browser, editor and terminal with bitl config, e.g. bitl config set browser arc.

Detecting a project

Not sure what BitL will make of a directory? Ask it:

bitl detect                # current directorybitl detect ~/Code/app --verbose

detect recognises far more than the web drivers — Laravel, PHP, Node.js, React Native, Flutter, Python, Go, Ruby, Swift, Java, Kotlin, Rust, CLI tools and static sites — so the app can offer the right actions.