All Blog

Ngrok Tunnel Guide: Expose Localhost to the Internet

10 min read
Spt 9, 2026

TL;DR

TL;DR illustration

An ngrok tunnel gives a service running on localhost a public URL without requiring port forwarding, a public IP address, or an immediate deployment. After installing and authenticating the ngrok CLI, run your application locally and enter a command such as ngrok http 3000. Requests to the generated HTTPS URL are then forwarded through ngrok to your local port.

This makes ngrok especially useful for testing webhooks, sharing development builds, connecting mobile applications to local APIs, and temporarily testing real-time applications. Treat the URL as public, protect sensitive endpoints, and avoid using a temporary development tunnel as an unplanned production deployment.

Understanding ngrok

ngrok is a cross-platform ingress platform that can create a public endpoint for an application running behind a firewall or NAT. For a developer, its most recognizable function is turning a localhost service into a URL that another person or internet service can reach.

Suppose your Node.js application is available only at:

http://localhost:3000

That address works on your computer, but a webhook provider, mobile device, remote colleague, or customer cannot reach it. An ngrok tunnel can assign the service an HTTPS address similar to:

https://example-name.ngrok-free.app

Requests sent to that public endpoint travel through an outbound tunnel established by the ngrok agent and are forwarded to port 3000 on your machine.

You do not have to configure router port forwarding, purchase a domain, obtain a public IP address, or deploy every work-in-progress change. That convenience is the main reason developers reach for ngrok during testing.

It is important, however, to understand what ngrok is not. It is not a replacement for your application server, database, authentication system, or production hosting architecture. It provides controlled ingress to an existing service.

How an ngrok connection works

The ngrok CLI runs an agent on your computer. The agent opens an outbound connection to ngrok's edge network, which is normally easier to establish through NAT and firewalls than an unsolicited inbound connection.

When an external client uses the assigned public URL, the traffic follows this path:

Browser, mobile app, or webhook provider
                  |
                  | HTTPS request
                  v
          Public ngrok endpoint
                  |
                  | Authenticated tunnel
                  v
          ngrok agent on your PC
                  |
                  | Local forwarding
                  v
          localhost:3000 application

The response travels back through the same route. Your local application therefore receives an ordinary HTTP request while ngrok handles the public endpoint and tunnel connection.

A typical request has five stages:

  1. The local ngrok agent connects to ngrok's service.
  2. ngrok assigns or activates a public endpoint.
  3. An internet client sends a request to that endpoint.
  4. ngrok carries the request through the established tunnel to your local service.
  5. Your application returns a response through the tunnel.

This arrangement is valuable when the external system must initiate the request. A payment processor cannot send a webhook to localhost, for example, because localhost refers to the processor's own machine. An ngrok URL provides the reachable endpoint it needs.

The tunnel does introduce another network hop and dependency. It is excellent for development and controlled previews, but latency, availability, endpoint stability, and plan limits should be considered before treating it as production infrastructure.

What an ngrok tunnel actually is

An ngrok tunnel is the logical connection between a public ngrok endpoint and a service available to the local ngrok agent. For HTTP applications, the service is commonly a port such as localhost:3000, localhost:8080, or localhost:5173.

The public endpoint and the local service are different things:

  • Public endpoint: The URL used by remote clients.
  • Tunnel: The connection that carries traffic to and from the agent.
  • Local upstream: The application receiving the forwarded request.
  • Agent: The local ngrok process that maintains the connection.

By default, an HTTP tunnel gives developers an HTTPS endpoint. This protects traffic between the external client and the public endpoint, while the agent maintains its secure connection to ngrok. If your local application also serves HTTPS, specify the correct local protocol rather than assuming every segment uses the same configuration.

Temporary URLs are suitable for quick tests, but they may change when a session restarts. If a webhook provider stores your callback URL or a remote team relies on a stable preview address, use a reserved domain or another persistent endpoint option available under the appropriate plan.

The practical distinction is simple: use an ephemeral tunnel for disposable tests, and use a stable, access-controlled endpoint when another system depends on the address.

Expose a local Node.js server with ngrok

The following ngrok tunnel example creates a small Node.js server and makes it reachable from the internet.

1. Check the prerequisites

You need:

  • A current Node.js installation
  • npm or another Node.js package manager
  • An ngrok account and authentication token
  • The ngrok CLI
  • A terminal, editor, and browser

Confirm that Node.js is available:

node --version
npm --version

Install ngrok using the method recommended for your operating system, then verify the CLI:

ngrok version

2. Create the Node.js application

Create a new project and install Express:

mkdir ngrok-node-demo
cd ngrok-node-demo
npm init -y
npm install express

Create a file named server.js:

const express = require("express");

const app = express();
const port = 3000;

app.use(express.json());

app.get("/", (req, res) => {
  res.json({
    message: "This local Node.js server is reachable through ngrok."
  });
});

app.post("/webhook", (req, res) => {
  console.log("Webhook received:", req.body);
  res.sendStatus(204);
});

app.listen(port, () => {
  console.log(`Local server running at http://localhost:${port}`);
});

Start the application:

node server.js

Visit http://localhost:3000 first. If the page does not work locally, adding a tunnel will not fix the application.

3. Authenticate the ngrok CLI

Copy the authentication token from your ngrok account and add it to the local configuration:

ngrok config add-authtoken YOUR_TOKEN

Do not commit the token to source control, place it in client-side JavaScript, or paste it into public logs. Treat it like any other account credential.

4. Start the ngrok tunnel

Keep the Node.js process running. In a second terminal, use this ngrok tunnel command:

ngrok http 3000

You can also write the upstream explicitly:

ngrok http http://localhost:3000

The CLI displays session information and a forwarding address. Open the HTTPS address in a browser and append /webhook when configuring a webhook provider.

For example:

https://example-name.ngrok-free.app/webhook

You have now created an ngrok tunnel to localhost. Requests to the public address reach the Express route on your development machine.

5. Test the public endpoint

Use curl to test the root route:

curl https://example-name.ngrok-free.app/

Then send a sample webhook:

curl -X POST https://example-name.ngrok-free.app/webhook \
  -H "Content-Type: application/json" \
  -d '{"event":"test.completed","id":"evt_123"}'

The second request should appear in your Node.js terminal.

If it fails, check the following:

  • Is the local Node.js process still running?
  • Does its port match the ngrok command?
  • Is the public URL current?
  • Is the requested route correct?
  • Is a local firewall or proxy interfering with the agent?
  • Does the webhook provider require a particular status code or signature?

Stop the tunnel with Ctrl+C. Once stopped, its temporary public endpoint may no longer work.

Using ngrok safely

ngrok provides secure transport and access-control capabilities, but opening a tunnel still changes your risk profile: software previously reachable only from your computer now has an internet-facing URL.

Follow these practices:

  1. Assume the URL can be discovered or shared. A hard-to-guess address is not authentication.
  2. Require application authentication. Protect dashboards, admin routes, APIs, and development tools just as you would after deployment.
  3. Validate webhook signatures. HTTPS protects transport, but it does not prove that a request came from the expected provider.
  4. Expose only the required port. Do not tunnel databases, internal control panels, or unrelated services for convenience.
  5. Remove debug data. Stack traces, environment variables, test credentials, and customer data should not appear in public responses.
  6. Use ngrok access policies where appropriate. OAuth, identity-aware controls, traffic rules, or other available protections can reduce exposure.
  7. Inspect requests carefully. Request inspection is useful, but captured headers and payloads may contain personal data or secrets.
  8. Stop unused tunnels and rotate compromised credentials. A forgotten tunnel can remain an unnecessary entry point.

Also review your organization's security policy before tunneling corporate services. Some environments prohibit third-party ingress agents or require explicit approval.

Four practical uses for ngrok

Four practical uses for ngrok illustration

1. Receive webhooks during development

Webhook providers need a public callback address. An ngrok tunnel lets payment, email, source-control, or automation platforms call your local handler while you develop it.

Use a route dedicated to the integration, log only necessary fields, and verify the provider's signature. Remember to update the provider if your temporary URL changes.

2. Share a local preview

You can give a remote stakeholder a working URL without deploying the branch. This is faster than sharing screenshots when feedback depends on navigation, responsive behavior, or API responses.

A preview tunnel is still connected to your development computer. Keep it open only for the review window, avoid using production credentials, and warn reviewers that the URL may be temporary.

3. Connect devices to a local backend

A phone cannot normally reach localhost on your laptop because its own localhost is the phone itself. Pointing a mobile build at an ngrok URL lets the device call the backend running on your computer.

This can simplify testing across mobile networks, although tunnel latency may differ from direct LAN access or the eventual production environment.

4. Test APIs and real-time callbacks

ngrok can expose REST endpoints, signaling services, event callbacks, and compatible TCP services. For a real-time audio/video application, it is useful for exposing the local web UI, token service, webhook receiver, or signaling-related backend during development.

It should not be assumed to replace a purpose-built global media network. Interactive media has stricter latency, packet-loss, routing, and scalability requirements than an ordinary development callback.

Eight ngrok capabilities worth knowing

1. Public tunneling

The core feature maps an internet-facing endpoint to a local service. HTTP is the common choice, while other endpoint types may be available depending on the configuration and plan.

2. HTTPS endpoints

ngrok can provide an HTTPS public address without requiring you to obtain and install a certificate for every temporary development session. This matters because many browser APIs and webhook providers require HTTPS.

3. CLI-based operation

The ngrok tunnel CLI makes basic workflows fast:

ngrok http 3000

For repeatable environments, define endpoints in configuration rather than relying on team members to remember a growing list of flags.

4. Request inspection

The local inspection interface commonly runs at:

http://127.0.0.1:4040

It lets you inspect request and response details and, where supported, replay requests. This is particularly helpful when a webhook appears to have arrived but your application processed it incorrectly.

The local inspector is different from the ngrok account dashboard. The local interface focuses on traffic reaching the current agent, while the ngrok tunnel dashboard provides account-level visibility and configuration appropriate to your plan.

5. Stable domains

A stable domain prevents integrations from breaking whenever the tunnel restarts. This is useful for longer-running QA environments, repeated demos, and callback configurations that are inconvenient to update.

6. Traffic controls

Depending on the plan and endpoint configuration, ngrok can apply controls such as authentication, request filtering, header manipulation, or rate-related policies at the edge. These controls complement rather than replace authorization inside the application.

7. Multiple endpoints and configuration files

Projects often need more than one service, such as a frontend on port 5173 and an API on port 3000. Named configurations make those mappings easier to reproduce and review.

8. Observability and logs

Connection status, request metadata, errors, and traffic inspection can shorten debugging time. Before enabling extensive logging, decide whether payloads could contain passwords, tokens, health information, or other sensitive content.

How ngrok pricing works

ngrok offers a free entry point for development as well as paid options for higher limits, stable domains, team workflows, security controls, and production-oriented requirements. Pricing and included quotas can change, so verify the current details on the official ngrok pricing page rather than designing around an old request or bandwidth allowance.

Evaluate a plan against the behavior of your project:

  • How many endpoints and domains are required?
  • Must the public URL remain stable?
  • How much traffic will pass through the service?
  • Do you need team access or centralized administration?
  • Are edge authentication and traffic policies required?
  • Is the tunnel limited to development, or will users depend on it?

The free option is usually enough to learn the CLI and test a temporary endpoint. A paid plan may be justified when changing URLs disrupt integrations or when security and operational controls become mandatory. If the tunnel is becoming permanent production ingress, compare its total cost and failure model with a conventional deployment or another managed ingress service.

Five useful ngrok alternatives

The best ngrok tunnel alternative depends on whether you prioritize zero setup, self-hosting, private-network access, stable domains, or production controls.

1. LocalTunnel

LocalTunnel is simple for Node.js users and can expose an HTTP service with an npm-based command. It works well for quick demos but generally offers fewer enterprise controls and operational features than a full ingress platform.

Best for: Disposable frontend and API previews.

2. Cloudflare Tunnel

Cloudflare Tunnel establishes an outbound connection from your environment to Cloudflare and can publish services without opening inbound ports. It is compelling when you already use Cloudflare DNS, identity controls, or edge services.

Best for: Persistent endpoints and Cloudflare-centered infrastructure.

3. Tailscale Funnel

Tailscale Funnel can publish selected services from a device in a Tailscale environment. For private access limited to known users or devices, ordinary Tailscale sharing may be preferable to making the service public.

Best for: Teams already using a mesh VPN and identity-based networking.

4. localhost.run

localhost.run uses SSH remote forwarding and can be convenient when SSH is already installed. Its command-line workflow is lightweight, although it may provide less configuration and traffic management than dedicated tunnel platforms.

Best for: Fast tests without installing a specialized agent.

5. zrok

zrok is an open-source sharing platform that supports public and private resource sharing. It is worth considering when self-hosting, open-source deployment, or alternative access models are important.

Best for: Developers who want greater deployment control.

Do not compare tunnel tools only by whether they generate a URL. Consider endpoint persistence, authentication, regional routing, protocol support, logs, data handling, self-hosting effort, usage limits, and the consequences of an outage.

Turn localhost into a useful public test environment

ngrok removes one of the most frustrating barriers in local development: an external system cannot call a service that exists only on your machine. With the ngrok CLI and a single command, you can create a public HTTPS endpoint, forward requests to localhost, and inspect what happened.

The shortest reliable workflow is:

  1. Confirm the application works locally.
  2. Authenticate the ngrok agent.
  3. Run ngrok http <port>.
  4. Test the generated HTTPS URL.
  5. Add authentication and webhook verification as needed.
  6. Stop the tunnel when the test is complete.

That workflow is ideal for webhooks, device testing, short demos, and remote review. If the endpoint must be stable or continuously available, move from an improvised temporary tunnel to an intentionally designed environment with appropriate security, monitoring, and cost controls.

Further ngrok resources

For command syntax, endpoint configuration, traffic policies, and agent installation, consult the official ngrok documentation. The Node.js documentation is also useful when the issue is in your local HTTP server rather than the tunnel.

When troubleshooting, separate the layers: test the application on localhost first, inspect the ngrok agent second, and test the public URL last. This prevents a server bug from being mistaken for a tunnel problem.

How to Build an App Like This with Tencent RTC

An ngrok tunnel can expose the development frontend, token endpoint, or event receiver for a local real-time application. The audio and video path itself should use infrastructure designed for interactive media.

Tencent RTC Engine provides the cross-platform real-time audio/video core for calls, conferences, live streaming, and custom interactive experiences. It handles room-based media transport, weak-network resilience, global low-latency routing, monitoring, and media processing. The ngrok endpoint remains a development ingress tool; Tencent RTC carries the actual media sessions.

A practical development architecture is:

Remote browser
  |-- HTTPS --> ngrok --> local web app and token service
  |
  |-- Audio/video --> Tencent RTC global real-time network
                            |
                            +--> Other room participants

Implement it in this order:

  1. Create a Tencent RTC application and obtain its SDKAppID.
  2. Build a server-side endpoint that returns a short-lived userSig. Never generate production signatures with the secret key in browser code.
  3. Run that token service and your frontend locally.
  4. Expose the local HTTP service with ngrok http 3000 when a remote browser or device must reach it.
  5. Install trtc-sdk-v5 in the web application.
  6. Create a Tencent RTC client and enter a room using roomId, userId, userSig, and sdkAppId.
  7. Start microphone and camera capture. Tencent RTC publishes those local tracks into the room.
  8. Listen for remote media events and subscribe by rendering the remote user's stream.
  9. Stop capture and exit the room during cleanup.

Install the SDK by running npm install trtc-sdk-v5.

The following focused browser example enters a room, captures and publishes local media, and renders remote video:

import TRTC from "trtc-sdk-v5";

const trtc = TRTC.create();

trtc.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, ({ userId, streamType }) => {
  trtc.startRemoteVideo({
    userId,
    streamType,
    view: `remote-${userId}`
  });
});

export async function joinCall({ sdkAppId, roomId, userId, userSig }) {
  await trtc.enterRoom({
    sdkAppId,
    roomId,
    userId,
    userSig
  });

  await trtc.startLocalVideo({ view: "local-video" });
  await trtc.startLocalAudio();
}

export async function leaveCall() {
  await trtc.stopLocalVideo();
  await trtc.stopLocalAudio();
  await trtc.exitRoom();
}

Create the local and remote video containers in your UI before starting playback. In a production implementation, also handle permission denial, device changes, room-entry errors, remote-user departure, and network quality events.

See the official Tencent RTC Engine overview and integration guidance for supported platforms and the broader SDK architecture. This separation gives you a fast local workflow through ngrok without forcing real-time audio and video through a general-purpose localhost tunnel.

FAQ

What command creates an ngrok tunnel to localhost?

Run ngrok http 3000, replacing 3000 with the port used by your local application. Keep both your application and the ngrok process running.

Is an ngrok tunnel safe for sensitive applications?

It offers secure transport, but the public endpoint still needs authentication, authorization, webhook signature validation, and careful logging. Do not expose sensitive development tools without access controls.

Should ngrok carry real-time audio and video traffic?

It can expose development pages and supporting APIs, but production media should use purpose-built infrastructure such as Tencent RTC Engine for low-latency routing, weak-network resilience, media processing, and monitoring.

Talk to us

We'd love to answer your questions and discuss how our RTC solutions can help meet your needs!
You can request demos, learn about pricing, or get personalized onboarding support. Complete the form below and one of our solution experts will be in touch shortly.
Submit
Submit that agree with the above information for contact purposes. Please read our Privacy Policy.