Project profiles
A project is rarely one port. Laravel wants an app server and Mailpit
and a database; WordPress sits on a whole LAMP stack. Project
profiles describe the stack once (committed to the repo) so bare
xport exposes everything in one command:
cd my-laravel-appxport ____ _ __ _| _ \ ___ _ __| |_ \ \/ / |_) / _ \| '__| __| > <| __/ (_) | | | |_ /_/\_\_| \___/|_| \__|
Project: my-laravel-app (laravel)
LABEL URL LOCALWeb https://k7fz2.xport.sh localhost:8000Mailpit https://q2mw9.xport.sh localhost:8025
private: db — reachable (local only), never exposed
Group: my-laravel-app — stop all with: xport stop --group my-laravel-appExpires: 2026-11-03 18:30:00 CETPress Ctrl-C to stop all.How projects are detected
Section titled “How projects are detected”xport.yamlin the project root — explicit profile, always wins.- Markers — a known file selects a built-in template:
artisan→ laravel,wp-config.php→ wordpress,package.json→ node. - Neither →
xportbehaves as always (stdin becomes a paste, a terminal shows help).
Writing a profile
Section titled “Writing a profile”xport profile init laravel # built-in templatexport profile init # generic scaffoldprofile: laravel # informational: which template it came fromname: my-laravel-app # groups the shares in the registryservices: app: port: 8000 label: Web check: php artisan migrate:status # preflight command (optional) hint: php artisan key:generate # shown when the check fails mail: port: 8025 label: Mailpit optional: true # skipped with a warning instead of abortingprivate: db: 3306 # verified locally, NEVER exposedCommit the file: teammates clone, run xport, and get the identical
setup — no README section to follow.
Preflight
Section titled “Preflight”Before any tunnel starts, every service is verified:
- Port check — something must listen on the port. A closed required
port aborts with the service’s
hint(a dead URL helps nobody); an optional service is skipped with a warning. checkcommands — run after the port check; failure aborts (or skips, when optional) with the captured error and the hint.
Check commands and trust
Section titled “Check commands and trust”A profile’s check commands are arbitrary shell — a cloned repository
could smuggle anything into them. So an xport.yaml file carrying
check commands asks before running them, once per file (its hash is
remembered); --trust opts out. Built-in templates and marker
detection ship with the CLI and are trusted by construction. In --json
or detached runs, where no one can answer, an untrusted profile aborts
with a clear error instead of guessing.
Managing
Section titled “Managing”xport listshows every service with its group;xport stop --group <name>stops the whole project at once.--jsonemits one envelope with all services, URLs, and ports — nice for scripts and CI.- All persistent flags apply (
--expires,--detach, …).
Built-in templates
Section titled “Built-in templates”| Template | Services | Private |
|---|---|---|
laravel |
Web (8000, checks php artisan --version), Mailpit (8025, optional) |
db (3306) |
wordpress |
Web (8080) | db (3306) |
node |
Web (3000) | — |
Ports are starting points — edit xport.yaml to match your stack
(Valet, LocalWP, Sail, custom ports). More templates ship as the
ecosystem grows.

