49 releases

0.15.0 Apr 3, 2025
0.14.0 Mar 26, 2025
0.14.0-pre.15 Dec 19, 2024
0.14.0-pre.14 Jul 22, 2024
0.5.0 Nov 23, 2020

#101 in HTTP server

Download history 539/week @ 2024-12-25 1080/week @ 2025-01-01 1514/week @ 2025-01-08 1721/week @ 2025-01-15 1083/week @ 2025-01-22 1246/week @ 2025-01-29 1493/week @ 2025-02-05 1085/week @ 2025-02-12 1700/week @ 2025-02-19 1247/week @ 2025-02-26 1281/week @ 2025-03-05 1639/week @ 2025-03-12 978/week @ 2025-03-19 1175/week @ 2025-03-26 1512/week @ 2025-04-02 1455/week @ 2025-04-09

5,451 downloads per month
Used in cargo-doc-ngrok

MIT/Apache

340KB
8K SLoC

ngrok-rust

Crates.io docs.rs MIT licensed Apache-2.0 licensed Continuous integration

API Docs (main)

ngrok is a simplified API-first ingress-as-a-service that adds connectivity, security, and observability to your apps.

ngrok-rust, our native and idiomatic crate for adding a public internet address with secure ingress traffic directly into your Rust apps 🦀. If you’ve used ngrok in the past, you can think of ngrok-rust as the ngrok agent packaged as a Rust crate.

ngrok-rust lets developers serve Rust services on the internet in a single statement without setting up low-level network primitives like IPs, NAT, certificates, load balancers, and even ports! Applications using ngrok-rust listen on ngrok’s global ingress network for TCP and HTTP traffic. ngrok-rust listeners are usable with hyper Servers, and connections implement tokio’s AsyncRead and AsyncWrite traits. This makes it easy to add ngrok-rust into any application that’s built on hyper, such as the popular axum HTTP framework.

See /ngrok/examples/ for example usage, or the tests in /ngrok/src/online_tests.rs.

For working with the ngrok API, check out the ngrok Rust API Client Library.

Installation

Add ngrok to the [dependencies] section of your Cargo.toml with cargo add:

$ cargo add ngrok

Quickstart

Create a simple HTTP server using ngrok and axum:

Cargo.toml:

[package]
name = "ngrok-rust-demo"
version = "0.1.0"
edition = "2021"

[dependencies]
ngrok = {version = "0.14.0"}
tokio = { version = "1", features = [
    "full"
] }
axum = { version = "0.7.4", features = ["tokio"] }
async-trait = "0.1.59"
hyper = {version = "1", features = ["full"]}
hyper-util = { version = "0.1", features = [
	"full"
] }
url = "2.5.4"

src/main.rs:

#![deny(warnings)]
use axum::{routing::get, Router};
use ngrok::config::ForwarderBuilder;
use std::net::SocketAddr;
use url::Url;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    // Create Axum app
    let app = Router::new().route("/", get(|| async { "Hello from Axum!" }));

    // Spawn Axum server
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    tokio::spawn(async move {
        axum::serve(tokio::net::TcpListener::bind(addr).await.unwrap(), app)
            .await
            .unwrap();
    });

    // Set up ngrok tunnel
    let sess1 = ngrok::Session::builder()
        .authtoken_from_env()
        .connect()
        .await?;
    let sess2 = ngrok::Session::builder()
        .authtoken_from_env()
        .connect()
        .await?;

    let _listener = sess1
        .http_endpoint()
        .domain("/* your domain*/")
        .pooling_enabled(true)
        .listen_and_forward(Url::parse("http://localhost:3000").unwrap())
        .await?;
    let _listener2 = sess2
        .http_endpoint()
        .domain("/* your domain */")
        .pooling_enabled(true)
        .listen_and_forward(Url::parse("http://localhost:8000").unwrap())
        .await?;

    // Wait indefinitely
    tokio::signal::ctrl_c().await?;
    Ok(())
}

Changelog

Changes to ngrok-rust are tracked under CHANGELOG.md.

Join the ngrok Community

License

This project is licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in ngrok by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~20–34MB
~603K SLoC