To expose localhost to the internet, install the Ngris agent and run one command against the port your app already listens on — ngris http 3000 — and use the public HTTPS URL it prints. That's the whole answer: no router port to open, no DNS to set up, and no TLS certificate to request. The rest of this guide shows the exact commands, how to open the URL on your phone or another computer, why it needs no port forwarding, and how to keep a stable address.
# Install the agent (macOS & Linux)
curl -fsSL https://ngris.com/install.sh | sh
# Turn localhost:3000 into a public HTTPS URL
ngris http 3000
Why not just forward a router port? The naive way to expose localhost means opening an inbound hole in your network, pointing dynamic DNS at your home IP, and somehow getting a TLS certificate for a hostname you don't own — brittle, insecure, and gone the moment your ISP rotates your address. A tunnel does the opposite: your machine makes an outbound connection to the Ngris edge, the edge gets a public hostname with TLS already terminated, and incoming requests are forwarded back down that connection to your local port. This is the same reverse-tunnel approach tools like ngrok use, so nothing is opened on your network and the public URL is HTTPS from the first byte. If you're switching from ngrok, the Ngris vs ngrok comparison maps the workflow you already know onto the policy-first edge.
How to get a public URL for localhost
The two lines above are the whole flow: the install one-liner drops the agent on your machine (macOS and Linux), and ngris http 3000 points it at the port your app already listens on. There's no reverse proxy to stand up, no certificate to request, and nothing to configure on your router.
One command to make localhost public
When the agent connects, it prints a Forwarding line with a public https://… address, and every request to that URL is served by your local process — your localhost is now public. The edge terminates TLS and serves your traffic over HTTP/1.1, HTTP/2, and HTTP/3 (QUIC); clients negotiate whichever they support. If you'd rather point the agent at a different port, just change the number:
# Expose the app running on port 3000 → public HTTPS URL
ngris http 3000
Access localhost from your phone or another computer
To access localhost from your phone (or a tablet, or another computer), open the public HTTPS URL that ngris http 3000 prints — not localhost. The reason localhost can't be reached from elsewhere is that localhost only ever means "this machine." On your phone it resolves to the phone; on a colleague's laptop it resolves to their laptop. To reach the thing running on your machine from a different device — over the internet, on cellular data, or on a completely different network — you need a real hostname that lives outside your machine.
The public URL from Ngris is exactly that. It's a normal internet address, so you can open it in mobile Safari or Chrome to test your website on your phone from localhost, load it on a tablet, or paste it into a browser on a different machine on a different network entirely. Because the edge serves it over HTTPS, mobile browsers that refuse plaintext will load it without complaint. And to share your localhost with someone, you don't screenshare or ask them onto your Wi-Fi — you hand them the URL and they open it like any other site.
Make localhost public — from any network, with a domain if you want one
"Make localhost public" and "get a public URL for localhost" describe the same thing from two angles, and one command covers both: ngris http 3000 makes your local port reachable from any network — your phone on cellular data, a colleague in another city, a partner's office behind their own firewall. The URL doesn't care what network the visitor is on, because it resolves to the Ngris edge, not to your machine. That's why it works to access localhost from a different network when nothing on your LAN ever will.
If you want a real domain for localhost instead of a generated hostname — a stable, memorable address like app.yourcompany.com that points at whatever you're running locally right now — reserve a hostname with --url or attach a custom domain you own; Ngris issues and renews the HTTPS certificate automatically. The step-by-step is in putting a custom domain on localhost.
Expose localhost without port forwarding
Router port forwarding is the traditional way to make a local server reachable, and it's the wrong tool here. Forwarding a port opens an inbound hole in your network, exposes your machine's real IP, and leaves you to provision and terminate TLS yourself. On a laptop that moves between networks — or behind carrier-grade NAT where you don't control the router at all — it may not work no matter how you configure it. You'd also need dynamic DNS to track your changing address.
A tunnel avoids all of that by reversing the direction of the connection. The Ngris agent dials out to the edge; the edge answers the public hostname and forwards requests back down that same outbound connection to your local port. Nothing listens on your network, so there's no router port to forward, no inbound firewall rule to punch, and no dynamic DNS to maintain. Your machine's address stays private, and the public URL keeps working when you switch from office Wi-Fi to a coffee shop to a hotspot.
Reserved hostname vs ephemeral endpoint
Run ngris http 3000 with no --url and the server provisions an ephemeral endpoint: a randomly generated hostname that lives only for the duration of the agent process. That's ideal for a quick demo or a one-off share — the free way to expose localhost to the internet when you just need a link for the next ten minutes.
When you want a URL that stays the same across restarts — so a teammate's bookmark or a webhook registration keeps working — pass a reserved hostname with --url:
# Reserved hostname — stable across runs
ngris http 8080 --url blog.ngris.com
The same flag attaches a custom domain you own; Ngris provisions and renews the certificate automatically via Let's Encrypt. The full walkthrough is in the Endpoints & Tunnels docs, and if a stable address on your own domain is the goal, see putting a custom domain on localhost.
Any port, any framework
The command takes a port number, and a port is just a number. ngris http <port> works for any local HTTP dev server — whatever framework happens to be listening on it. There's nothing to auto-detect and nothing framework-specific to configure; you tell it the port and it forwards that port.
# React / Next.js / Node — expose localhost 3000
ngris http 3000
# Vite dev server
ngris http 5173
# Angular
ngris http 4200
# Django
ngris http 8000
# Flask
ngris http 5000
# Spring / Tomcat
ngris http 8080
So exposing a Vite dev server, a Next.js dev server, or a Django development server to the internet is the same one command with a different number — 5173, 3000, or 8000. If your API isn't just a demo and you want auth and inspection in front of it, the companion post on exposing a local API to the internet goes deeper.
Expose a server to the internet, not just a dev server
The same command that exposes a dev server exposes any local server to the internet — an app server, an API, a database admin UI, a game server's web console. You're not limited to Vite or Next.js: ngris http <port> takes localhost from private to public regardless of what's listening, so "how to expose a server to the internet" and "how to make a localhost website public" are the same one command with a different number.
# Expose an app server on 8080
ngris http 8080
# Expose a local API on 8000
ngris http 8000
Turning localhost into a real, public address is exactly what people mean by "make localhost public" or "public localhost": the URL resolves to the Ngris edge, not to your machine, so it works from any network and stays private on your side. Once your server is more than a demo — and you want auth, rate limits, and a WAF in front of it — the companion guide on exposing a local API to the internet walks through locking the endpoint down, and pricing shows what each plan includes.
HTTP/2 and HTTP/3, automatically
You don't configure protocol negotiation. Every HTTPS endpoint advertises HTTP/3 via the alt-svc header, and clients negotiate whichever protocol (HTTP/1.1, HTTP/2, or HTTP/3/QUIC) they support. Real client IPs survive the hop, so your logs and the traffic inspector see the original address regardless of the negotiated version.
Is it safe to expose localhost?
A public URL means your local process is reachable from the internet, so treat it like any public endpoint: only expose what you mean to, and shut the agent down when you're done. An ephemeral endpoint disappears the moment you stop the agent, which keeps the exposure window small by default.
When you need more than a raw tunnel, the edge is a full gateway: you can layer authentication, rate limits, and a Coraza-powered WAF as traffic policies, and put internal apps behind identity-aware SSO/OIDC so only your people reach them. That's a whole topic of its own — the expose a local API guide walks through locking an endpoint down.
A free way to expose localhost to the internet
The Developer plan is $0 and includes 5 endpoints at no cost, with no credit card to start — enough to keep a few stable URLs around for the apps you tunnel most often. An ephemeral endpoint (ngris http 3000 with no --url) is the free way to get a public URL for a quick share. When you outgrow it, the Team plan ($10/mo) adds custom domains, the full policy engine, and edge auth, and Enterprise ($25/mo) adds dedicated ports/IPs and SSO; see pricing for the full comparison. If you're coming from ngrok, the Ngris vs ngrok comparison maps the workflow you already know onto the policy-first edge.
Frequently asked questions
How do I get a public URL for localhost?
Install the Ngris agent with curl -fsSL https://ngris.com/install.sh | sh (macOS and Linux) and run ngris http 3000, pointing it at the port your app already listens on. The agent prints a Forwarding line with a public HTTPS URL that any browser can open — no reverse proxy, DNS, or certificate setup required.
How do I expose a server to the internet?
Point the agent at whatever port your server listens on — ngris http 8080 for an app server, ngris http 8000 for an API — and Ngris returns a public HTTPS URL for it. Because a port is just a number, the same command exposes a dev server, a production-style app server, or an API to the internet without opening any inbound port on your network.
How do I make a localhost website public?
Run ngris http against the port your site serves on (for example ngris http 3000) and use the public HTTPS URL the agent prints. That URL makes your localhost website public — reachable from any network — while localhost itself only ever means your own machine and cannot be opened from anywhere else.
How do I expose a local dev server without ngrok?
Ngris is a drop-in alternative — run ngris http 3000 to turn any local dev server into a public HTTPS URL. Like ngrok it opens an outbound tunnel, so there is no port forwarding, and the Free plan includes 5 endpoints with no credit card.
Is it safe to expose localhost to the internet?
A public URL makes your local process reachable, so only expose what you intend to and stop the agent when you're done; an ephemeral endpoint disappears the moment the agent stops. For more control you can layer authentication, rate limits, a Coraza WAF, and identity-aware SSO/OIDC at the edge as traffic policies.
How do I expose localhost without port forwarding?
The Ngris agent dials out to the edge, and the edge forwards requests back down that outbound connection to your local port. Because nothing listens on your network, there is no router port to forward, no inbound firewall hole, and no dynamic DNS to maintain.
How do I access localhost from my phone or another computer?
The public HTTPS URL from ngris http 3000 is a real internet address, so you can open it in a mobile browser, on a tablet, or on another computer on a different network. Since the edge serves it over HTTPS, mobile browsers that block plaintext will load it without issue.
How do I share my localhost with someone?
Run ngris http against your local port and hand the person the public HTTPS URL the agent prints. They open it like any other website — no screenshare and no need to be on your Wi-Fi. For a link that survives restarts, reserve a stable hostname with the --url flag.
Can I expose a Vite, Next.js, or Django dev server?
Yes. ngris http <port> works for any local HTTP dev server, since a port is just a number and there is nothing framework-specific to configure. Use ngris http 5173 for Vite, ngris http 3000 for Next.js, or ngris http 8000 for Django.
Is there a free way to expose localhost to the internet?
Yes. The Developer plan is $0 and includes 5 endpoints with no credit card required, and an ephemeral endpoint (ngris http 3000 with no --url) gives you a public URL for a quick share. The Team plan at $10/mo adds custom domains, the policy engine, and edge auth; Enterprise at $25/mo adds dedicated ports/IPs and SSO.
Get a public URL for localhost
Create a free account, install the agent, and run ngris http 3000 — no credit card.
curl -fsSL https://ngris.com/install.sh | sh
ngris http 3000
New to the CLI? The Getting Started guide walks through install, authentication, and your first endpoint step by step. When your app grows past a demo, the same edge can expose and lock down a local API, put a custom domain on localhost, or — when you've built something and want it hosted rather than tunneled — expose or deploy behind one edge. Coming from another tool? See Ngris vs ngrok.