Skip to main content
ngrok-axum serves an Axum Router through an ngrok endpoint with one call:
The crate is built on the Rust SDK. Axum 0.7 removed axum::Server, which took away the one-line way to serve an app on an ngrok listener. serve restores it: it opens the endpoint, accepts connections, and serves each one with Hyper so you don’t write the connection loop yourself.
ngrok-axum is published on crates.io at version 0.1.1 and maintained in the ngrok-samples/ngrok-axum repository.

What you’ll need

1. Install the crate

Add the crate alongside Axum 0.8 and Tokio:
Cargo.toml

2. Set your auth token

Export your auth token as an environment variable:
The crate reads NGROK_AUTHTOKEN from the environment when it opens the session.

3. Serve your router

Replace axum::serve with ngrok_axum::serve:
src/main.rs
serve runs until the listener closes or a connection error occurs.

4. Test your endpoint

Run your app:
The crate prints Ingress established at: followed by the public URL. With Config::default(), that URL is your account’s dev domain. Open it in your browser to see your Axum app.

Configuration

Pass a Config to set the URL, add a Traffic Policy, or change the binding:

Multiple endpoints

serve_many opens one endpoint per Endpoint, each with its own Router and Config, on a single session:
serve is the one-endpoint case of serve_many. To put one router behind several listeners, clone the Router into more than one Endpoint. Every endpoint needs its own url, or pooling: true on each endpoint that shares one. If two endpoints would share a URL without pooling, including two endpoints that both leave url as None and land on your dev domain, serve_many returns an error before opening a session. Without that check, ngrok lets the most recently opened listener win and the other goes unreachable with no error.

Limits and availability

  • The crate opens HTTP endpoints only. For TCP or TLS endpoints, use the Rust SDK directly.
  • The crate requires Axum 0.8.
  • An Internal binding requires a url that ends in .internal. ngrok rejects any other URL with ERR_NGROK_9029.
  • A URL that another agent or a Cloud Endpoint already claims fails with ERR_NGROK_334.
  • Endpoint counts and domains follow your plan’s limits. See free plan limits.

What’s next?