# bundx-init: every Next.js repo gets https://<repo>.localhost via Caddy

Source: https://www.michaelchurley.com/blog/bundx-init-nextjs-unique-localhost-https-caddy  
Published: 2026-06-22  
Author: Michael C. Hurley  
Tags: bundx-init, nextjs, caddy, localhost, https, clerk, allowedDevOrigins, bash, cli, dev-tooling, local-dev, michaelmonetized

![Install flow](/blog/bundx-init-nextjs-unique-localhost-https-caddy/screenshots/install-flow.png)

## Who

I run a lot of Next.js apps side by side. Shared `http://localhost:3000` fights Clerk cookies, callback URLs, and `allowedDevOrigins` the second a second app boots.

For operators who need **stable HTTPS origins per repo** on a laptop without hand-writing a Caddyfile every time.

## What

I built **bundx-init**, public `https://github.com/michaelmonetized/bundx-init`. Shell CLI. HEAD `c8b59ad`. **3** commits. 0 stars. No tagged release.

`bin/bundx-init` is **379** lines. `install.sh` curls it into `~/.local/bin` (`BUNDX_INIT_RAW_URL` override). Target must be a Next project (`package.json` with `next`).

What it does (README + script):

- installs Caddy when possible (brew / apt Cloudsmith / dnf COPR / pacman)
- configures `~/.local/etc/Caddyfile` to import `~/.local/etc/caddy/dev-sites/*.caddy`
- writes a repo-scoped Caddy snippet
- adds `scripts/dev-localhost.mjs` + `dev-localhost-info.mjs`
- rewires `package.json` so `dev` runs the HTTPS flow (`dev:raw` keeps the old script; `dev:info` dumps JSON)
- patches `next.config.*` with `allowedDevOrigins: ["<host>", "*.localhost"]` when it can

Slug = basename lowercased. Host = `<slug>.localhost`. Port = `3300 + (hash(slug) % 5000)`. Fixture `basic-next` maps to port **6422**; README `my-next-app` maps to **6996**.

![Hostname / port map](/blog/bundx-init-nextjs-unique-localhost-https-caddy/screenshots/hostname-port-map.png)

Next still binds an internal high port. Caddy owns `:443` and reverse-proxies. Env: `DEV_HOST`, `DEV_URL`, `PORT`.

![Architecture](/blog/bundx-init-nextjs-unique-localhost-https-caddy/screenshots/architecture.png)

Fixture after init shows the patch contract: Next **16.2.1** / React **19.2.0**, `dev` runs the localhost script, `allowedDevOrigins` for `basic-next.localhost` + `*.localhost`.

![Repo patches](/blog/bundx-init-nextjs-unique-localhost-https-caddy/screenshots/repo-patches.png)

## Where

Code: [github.com/michaelmonetized/bundx-init](https://github.com/michaelmonetized/bundx-init), public. No live web app.

```bash
curl -fsSL https://raw.githubusercontent.com/michaelmonetized/bundx-init/main/install.sh | bash
bundx-init ~/Projects/my-next-app
cd ~/Projects/my-next-app && bun install && bun run dev
# https://my-next-app.localhost
```

## When

**2026-03-30.** `3d4b752` Initialize bundx-init (589 insertions: CLI, install, README, fixture).

**2026-06-22.** `f356360` nightly adds `.uncap/config.json`.

**2026-06-22.** `c8b59ad` nightly empty tip (HEAD).

![Commit arc](/blog/bundx-init-nextjs-unique-localhost-https-caddy/screenshots/commit-arc.png)

## Why

Parallel Next apps on one port break auth providers. Clerk and friends want real HTTPS origins in local. A hashed port, a Caddy snippet, and `allowedDevOrigins` is the boring fix; shipping it as a curl-install CLI beats copy-pasting the same five files forever.

**Engagement Q:** How many Next apps do you run locally before `localhost:3000` starts lying to your auth provider?
