>_ DevTrendsen

Language

Home

Languages

Sections

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embedded Security
CSS

How to expose a local port to the internet without the hassle

A familiar situation: you spin up a backend on your local machine, configure integration with an external service like Stripe or Telegram, and then you need to test a webhook. There's no external access to your localhost:8000, ordering a static IP feels like too much effort, and deploying a staging environment just for a couple of requests takes too long.

Usually in moments like these, your hand instinctively reaches for ngrok or similar services. But commercial alternatives always come with annoying limitations: traffic caps, URLs that change with every restart, or paid subscriptions for basic features. Recently I came across tunnelto — an open-source Rust utility that does exactly what it says on the tin, without the extra hassle.

What is this tool

The tunnelto project lets you expose a local web server to the public internet via a tunnel. You run a single command in the terminal, get a valid public URL, and hand it off to external services or clients for demo purposes.

The main highlight is that both the client and server are written in Rust using the async tokio engine. This results in modest memory usage and fast handling of incoming connections. No heavy runtimes or background processes eating up gigabytes of RAM.

The project repository is available at https://github.com/tunneltodev/tunnelto.

How it works in practice

Installation takes a couple of minutes. If you're on macOS, the utility installs via Homebrew:

brew install agrinman/tap/tunnelto

If you already have a Rust toolchain set up, you can build the package via Cargo:

cargo install tunnelto

For other systems, the author has prepared compiled binaries in the Releases section on GitHub.

Quick start

Let's say you have a web application running locally on port 8000. You can expose it to the outside world with this command:

tunnelto --port 8000

After execution, the utility opens a tunnel and immediately provides a working address. Any requests coming to that address from the internet are instantly forwarded to your local port.

Useful parameters

In everyday work, you often need additional configuration. Here are the flags that save time:

  • --subdomain sets a fixed subdomain name so you don't have to change the URL in webhook settings after every restart
  • --scheme switches the protocol between http and https if your local service requires a secure connection
  • --dashboard-address spins up a local interface for inspecting and viewing incoming requests
  • --key accepts an API key for tunnel authorization

Example command with explicit subdomain specification:

tunnelto --port 3000 --subdomain my-test-app

What this is useful for

In development, there are several scenarios where tunneling saves hours of work:

  1. Debugging incoming webhooks from payment systems, messengers, or OAuth providers directly in your local debugger with breakpoints.
  2. Testing a mobile application on a real smartphone connected to a mobile network, without configuring Wi-Fi router.
  3. Quickly showing layouts or prototypes to colleagues while the code hasn't been pushed to the repository yet or deployed to a test server.
  4. Verifying HTTPS certificates and security headers before release.

Personal impressions

The README mentions the ability to self-host the server component, although the documentation lacks detailed instructions. If full traffic privacy is important to you, you'll need to dig into the codebase and deploy a relay on your own VPS.

The project doesn't have many stars (around 400), and commits don't come every day, but for basic tasks the utility works reliably. It starts up quickly, doesn't require registration for basic tunneling, and does exactly one clear thing. If you're looking for a simple open-source replacement for ngrok, it's worth checking out the repository and giving it a try.

Related projects