Skip to main content

Add ngrok to Next.js, FastAPI, Axum, and Gin

Your web framework already knows when your app starts and stops. Four packages in the ngrok-samples GitHub organization hook into that to give your app a public ngrok endpoint.

You don’t need a second terminal running ngrok http. Each package opens your app’s public URL when your server starts and closes it when the server stops, so you run one service: yours. The FastAPI, Axum, and Gin packages work the same way in production.

ngrok maintains all four as official packages. Each one is built on ngrok’s agent SDKs, so use a package as it is, or read the source and adapt the pattern to your own setup.

The four packages are:

  • @ngrok/nextjs for Next.js. It runs next dev and the endpoint as one process, so Ctrl+C stops both. By default, it also writes the endpoint URL to NEXTAUTH_URL and NEXT_PUBLIC_APP_URL in .env.local, so NextAuth callbacks go to your public URL.
  • ngrok-fastapi for FastAPI. It hooks into your app’s lifespan with one call to ngrok_fastapi.attach, so the rest of your app stays the same.
  • ngrok-axum for Axum. It serves your Router through an endpoint with one call to ngrok_axum::serve. The full API is on docs.rs.
  • ngrok-gin for Gin. It serves your router through an endpoint with one call to ngrokgin.Serve.

All four read your ngrok authtoken from NGROK_AUTHTOKEN and use your account’s dev domain by default. Set a reserved domain, a Traffic Policy document, pooling, or binding in the package’s config.

To expose more than one service, list them under endpoints in ngrok.config.ts for Next.js. The FastAPI, Axum, and Gin packages open several endpoints from one call (attach_many, serve_many, and ServeMany).

Get started

Sign up for ngrok or sign in, then copy an authtoken from the dashboard. Replace <YOUR_AUTHTOKEN> with it in the run commands below.

For Next.js, install the package:

npm install @ngrok/nextjs

Then run it from your project root in place of next dev:

NGROK_AUTHTOKEN="<YOUR_AUTHTOKEN>" npx @ngrok/nextjs dev

For FastAPI, install the package:

pip install ngrok-fastapi

Then attach it to your app in main.py:

import uvicornfrom fastapi import FastAPIimport ngrok_fastapi app = FastAPI()ngrok_fastapi.attach(app, ngrok_fastapi.Config(port=8000))  @app.get("/")def root():    return {"message": "hello"}  if __name__ == "__main__":    uvicorn.run(app, host="0.0.0.0", port=8000)

Run your app:

NGROK_AUTHTOKEN="<YOUR_AUTHTOKEN>" python main.py

For Axum, add the package with Axum and Tokio:

cargo add ngrok-axum axum tokio -F tokio/full

Then serve your router with ngrok_axum::serve in src/main.rs:

use axum::{routing::get, Router}; #[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {  let app = Router::new().route("/", get(|| async { "hello" }));  ngrok_axum::serve(app, ngrok_axum::Config::default()).await?;  Ok(())}

Run your app:

NGROK_AUTHTOKEN="<YOUR_AUTHTOKEN>" cargo run

For Gin, install the package:

go get github.com/ngrok-samples/ngrok-gin

Then serve your router with ngrokgin.Serve in main.go:

package main import (	"context" 	"github.com/gin-gonic/gin"	ngrokgin "github.com/ngrok-samples/ngrok-gin") func main() {	router := gin.Default()	router.GET("/", func(c *gin.Context) { c.String(200, "hello") })	ngrokgin.Serve(context.Background(), router, ngrokgin.Config{})}

Run your app:

NGROK_AUTHTOKEN="<YOUR_AUTHTOKEN>" go run main.go

Open your app’s public URL in a browser, then confirm the endpoint is online under Endpoints in the dashboard.

Each repository has an examples directory with working apps and a README that covers every config option. The same snippets are on the ngrok download pages for Next.js, FastAPI, Axum, and Gin.