Open source · npm · macOS + Linux
Localhost,
but everywhere.
dynamoip gives your local services a real domain and trusted HTTPS. So app.yourdomain.com opens on your phone, anywhere on your LAN, or out on the public internet.
Same URL every time — it doesn't reset like ngrok. One flag flips it from your private LAN to the whole internet.
dynamoip is an open-source npm tool for macOS and Linux. It gives your local services real domain names with trusted HTTPS — accessible on your LAN or exposed to the public internet via Cloudflare Tunnel. No port forwarding. No firewall rules. Configure once, one command every time. Three modes: Quick (mDNS .local), Pro (Cloudflare DNS + Let's Encrypt, LAN only), Max (Cloudflare Tunnel, public internet).
WebSockets and HMR just work — Vite and Next.js Fast Refresh keep running on your phone, not just your laptop.
Before / after
Drag to compare.
Same dev server. Two very different lives. Drag the handle.
Dev server address
app.yourdomain.com
Same URL, every network.
Share it
Just send the link.
They bookmark it. Done.
Tunnel URL
app.yourdomain.com
Permanent. Never resets.
On your phone
Everything works
Trusted HTTPS on the device.
/01
Who it's for.
Mostly one developer, one app, one real URL — but it scales up from there.
Your phone can't reach localhost.
Camera, geolocation, PWA installs, service workers — none of them work over plain HTTP, and none of them can see localhost from your phone anyway. dynamoip hands your dev server a real HTTPS URL that opens on any device. Set it up once, use the same URL every time.
Stop pasting IP addresses in Slack.
192.168.1.105:3000 isn’t a URL. dynamoip gives everyone on the network a real link — LAN-only, nothing leaves the office, no port forwarding, no VPN. Set it up once, share the same link every standup.
Your own server shouldn't feel sketchy.
Home Assistant, Grafana, Plex, Jellyfin — give each one a real subdomain with trusted HTTPS. Bookmark them, open them from your phone, and never click through another browser warning about your own hardware.
Share your local app with anyone.
A webhook you’re testing, a client demo from your laptop, a staging build you want feedback on — Max mode gives you a real, permanent URL. Not a random ngrok subdomain that expires and breaks every webhook you registered.
/02
How it works.
Configure once. It just works every time after that.
01 —
Install
One command adds dynamoip as a dev dependency. It never runs in production — this is a tool for you, not your users.
02 —
Configure
Drop in a config file, add your env vars, add one npm script. Five minutes, once — then you never touch it again. Add "tunnel": true when you want to go public.
03 —
Run
One command brings every domain live, on your LAN or the internet. If it crashes, it restarts itself with backoff and keeps your URLs up.
/03
Three modes.
From local dev to the public internet — one tool, one domain.
Cloudflare
Tunnel
Your services, live on the public internet. No port forwarding, no firewall rules, no inbound ports. cloudflared installs itself, and you don't need sudo.
"baseDomain": "acme.dev",
"tunnel": true,
"domains": { "app": 3000 }
}
Cloudflare
+ Let's Encrypt
Your own domain, with Cloudflare DNS and a Let's Encrypt wildcard cert. Every device on your LAN trusts it out of the box — no CA to install on phones or tablets. LAN only. No tunnel.
"baseDomain": "acme.dev",
"domains": { "app": 3000 }
}
Needs: a Cloudflare domain + an API token (Zone:DNS:Edit)
mDNS
.local
No domain, no accounts. Broadcasts .local hostnames over mDNS with a locally-trusted mkcert cert. The first time another device visits, it gets a one-tap trust page. LAN only. No tunnel.
"domains": { "app": 3000 }
}
Needs: mkcert, sudo
/04
Quick start.
Configure once. One command every time after that.
— one-time setup · ~5 min —
One command. It never runs in production.
Pick a mode. Expand to grab the config.
Max mode — public internetPublic internet
{
"baseDomain": "yourdomain.com",
"tunnel": true,
"domains": {
"app": 3000,
"api": 4000
}
}Needs a Cloudflare API token with Zone:DNS:Edit + Account:Cloudflare Tunnel:Edit.
Pro mode — LAN, your domain
{
"baseDomain": "yourdomain.com",
"domains": {
"app": 3000,
"api": 4000
}
}Needs a Cloudflare API token with Zone:DNS:Edit. No tunnel — traffic stays on your LAN.
Quick mode — LAN, .local, zero accounts
{
"domains": {
"app": 3000
}
}No Cloudflare, no domain — just mkcert and mDNS. Your domains become app.local. LAN only, no tunnel.
One line. This is the command you'll run from now on.
"scripts": {
"dev:proxy": "dynamoip --config dynamoip.config.json"
}Pro and Max need these. Quick doesn't.
CF_API_TOKEN=your_cloudflare_api_token CF_EMAIL=you@example.com # Pro mode only
— then, every time —
sudo npm run dev:proxy
Your domains are live in seconds. Same domain, every time, nothing to reconfigure.
Max runs without sudo — just npm run dev:proxy. Pro and Quick need it for ports 80/443, or pass --port 8443.
/05
Examples.
Runnable Docker projects. Clone one, run a command, done.