@dabble/local-dev-setup
v1.5.1
Published
Shared local dev setup for Dabble projects — installs and configures Caddy as an HTTPS reverse proxy for *.local.dabblewriter.com
Keywords
Readme
@dabble/local-dev-setup
Shared local development setup for Dabble projects. Installs and configures Caddy as an HTTPS reverse proxy so all Dabble services are reachable at https://*.local.dabblewriter.com on port 443.
What it does
When you run npm run dev in any Dabble repo, this package runs first and ensures the local environment is ready:
- Install Caddy — prompts to install via Homebrew (macOS), apt (Linux), or winget/choco (Windows) if not found.
- Configure Caddyfile — appends or updates the
# dabble-local-devblock with proxy entries for all Dabble services. - DNS setup — configures dnsmasq (macOS) or
/etc/hosts(Linux/Windows) so*.local.dabblewriter.comresolves to127.0.0.1. - Start Caddy — starts or reloads the Caddy service, and trusts its local CA certificate on first run.
Fast path
If everything is already configured, the script exits silently in under 500ms so it doesn't slow down npm run dev.
Caddy reload tracking
A hash of the Caddyfile is stored in $TMPDIR/.dabble-caddy-config-hash after each reload. If the Caddyfile is modified externally (e.g. by another project's setup), the next run detects the drift and reloads Caddy automatically.
Proxy configuration
| Hostname | Upstream | Notes |
|---|---|---|
| local.dabblewriter.com | localhost:5180 | Writer app (canonical Vite), retries for 10s |
| two.local.dabblewriter.com | localhost:8080 | Legacy alt slot, retains for backwards compat |
| *.local.dabblewriter.com | (dynamic) | Per-worktree subdomains, see below |
| accounts.local.dabblewriter.com | localhost:5181 | Accounts (SvelteKit) |
| admin.local.dabblewriter.com | localhost:5182 | Admin (Vite) |
| rest.local.dabblewriter.com | localhost:5184 | REST API (Wrangler) |
| pup.local.dabblewriter.com | localhost:5183 | Pup service |
The canonical writer proxy uses lb_try_duration 10s to retry connections to Vite and returns non-cacheable 503 errors instead of falling back to production. Backend service proxies fall back to their respective test servers on failure. Unregistered *.local.dabblewriter.com subdomains fall through to a 503 with a hint to run npm run dev in the matching worktree.
Per-worktree dev subdomains (1.3.0+)
When the dev script is invoked as dabble-local-dev-setup vite (rather than dabble-local-dev-setup && vite), the wrapper:
- Detects whether the current
cwdis a non-maingit worktree. - Picks a subdomain from the directory name (with the main worktree's basename +
-stripped) — e.g.dabble-writer-3.0-cover-image-fix->cover-image-fix.local.dabblewriter.com. - Allocates a port deterministically in
[8100, 8200)(persisted in$TMPDIR/dabble-worktree-ports.jsonso a worktree always gets the same port). - Registers
<host> -> localhost:<port>in Caddy via its admin API (localhost:2019); the route is inserted ahead of the wildcard catch-all. - Spawns the given command (e.g.
vite) withVITE_DEV_HOSTandVITE_DEV_PORTinjected. - Removes the route on exit (SIGINT / SIGTERM / process exit).
The main worktree (where the script is run from cwd === git worktree list --porcelain's first entry) keeps using the canonical local.dabblewriter.com static block on port 5180.
Override host / port
Resolution order: real shell env vars > <cwd>/.env.local > <cwd>/.env > auto-detect.
# dabble-writer-3.0-cover-image-fix/.env.local (optional)
DABBLE_DEV_HOST=feature-x.local.dabblewriter.com
DABBLE_DEV_PORT=8120Or one-off: DABBLE_DEV_HOST=foo.local.dabblewriter.com npm run dev.
Vite still loads the rest of .env.local itself; only DABBLE_DEV_HOST and DABBLE_DEV_PORT are read here.
Notes & caveats
- Duplicate-instance protection (1.3.1+): if you accidentally run
npm run devfor the same worktree in two terminals, the second invocation refuses early with a clear error instead of clobbering the first instance's Caddy route on cleanup. - Routes are stored in Caddy's running config and survive Caddyfile reloads, but a full Caddy restart drops them; just re-run
npm run devin the affected worktree to re-register. - All worktrees still share the same
accounts/rest/pupbackends — server-state changes are visible across instances. - Each subdomain is its own browser origin: separate IndexedDB, service worker, and login session.
- Wildcard DNS for
*.local.dabblewriter.comrequiresdnsmasq(auto-set up on macOS). On Linux/Windows the static/etc/hostsentries don't cover ad-hoc subdomains; install dnsmasq or add the specific worktree subdomain manually.
Usage
Add as a devDependency:
npm install --save-dev @dabble/local-dev-setupReference in your dev script. Two forms:
{
"scripts": {
// Backwards-compatible: just runs setup, then exits. Vite is invoked separately.
"dev:legacy": "dabble-local-dev-setup && vite --port 5180",
// Preferred (1.3.0+): wrapper handles per-worktree subdomains + ports automatically.
"dev": "dabble-local-dev-setup vite"
}
}The dabble-local-dev-setup bin is resolved automatically from node_modules/.bin when run inside an npm script. The wrapper form (any positional command after the script name) injects VITE_DEV_HOST / VITE_DEV_PORT into the child process; consume them in vite.config.ts:
server: {
port: Number(process.env.VITE_DEV_PORT) || 5180,
strictPort: true,
hmr: {
host: process.env.VITE_DEV_HOST || 'local.dabblewriter.com',
protocol: 'wss',
clientPort: 443,
},
},Requirements
- Node.js >= 18
- An
.npmrcwith//registry.npmjs.org/:_authToken=${NPM_TOKEN}to access the@dabblescope
