Axum
Set up debugger in a Rust project using the Axum framework.
Last updated March 19, 2026
Rust + Axum
This guide covers adding debugger to a Rust API using Axum. The setup takes three lines.
| Feature | Support |
|---|---|
| Server console | Yes |
| Server errors | Via tracing |
| HTTP requests | Yes |
| Browser script injection | Manual |
Prerequisites
- Rust 1.75 or later
Install
Add the crate to your Cargo.toml:
[dependencies]
ephem-debugger = { version = "0.1", features = ["axum"] }
Set up
Use the layers convenience function to get both the HTTP middleware
and tracing capture layer:
use axum::{routing::get, Json, Router};
use ephem_debugger::axum_middleware;
use serde_json::{json, Value};
use tracing_subscriber::prelude::*;
async fn index() -> Json<Value> {
tracing::info!("home page hit");
Json(json!({"status": "ok"}))
}
#[tokio::main]
async fn main() {
let (middleware_layer, capture_layer) = axum_middleware::layers(3000);
tracing_subscriber::registry()
.with(capture_layer)
.with(tracing_subscriber::fmt::layer())
.init();
let app = Router::new()
.route("/", get(index))
.layer(middleware_layer);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await.unwrap();
axum::serve(listener, app).await.unwrap();
}
Three lines handle debugger setup:
axum_middleware::layers(3000)— creates the session, store, IPC bridge, and returns both layers.with(capture_layer)— captures alltracingevents into the debugger store.layer(middleware_layer)— captures HTTP request metadata
What gets captured
- HTTP requests — method, path, status code, and duration for every request via the Tower middleware layer
- tracing events — all
tracing::info!(),tracing::error!(), etc. calls via the capture layer, including structured fields - Axum internals — connection events at DEBUG/TRACE level
Verify
Build and run:
cargo run
The terminal shows the session ID:
> @ephem-sh/debugger: session ba2f3c
> @ephem-sh/debugger: bridge listening on 127.0.0.1:60693
Open another terminal and query:
npx dbg statuspnpm dlx dbg statusbun x dbg statusyarn dlx dbg statusnpx dbg server consolepnpm dlx dbg server consolebun x dbg server consoleyarn dlx dbg server consoleAPI reference
axum_middleware::layers(port) -> (DebuggerLayer, CaptureLayer)
Returns a tuple of two layers:
DebuggerLayer— TowerLayerfor HTTP request captureCaptureLayer—tracing_subscriber::Layerfor log capture
Add the DebuggerLayer to your Axum Router with .layer() and
the CaptureLayer to your tracing_subscriber::registry() with
.with().
DebuggerLayer::new(port) -> DebuggerLayer
Creates just the HTTP middleware layer (without tracing capture). Use this if you want to set up tracing separately.
Production safety
The middleware runs unconditionally. Guard it with a feature flag or environment variable:
let app = if std::env::var("DEBUG").is_ok() {
let (mw, cap) = axum_middleware::layers(3000);
// set up tracing with cap...
router.layer(mw)
} else {
router
};
Browser support
The middleware automatically handles /_/d.js and /_/d POST
routes. To enable browser capture, add these script tags before
</body> in your HTML templates:
<script>window.__DEBUGGER_INGEST_URL__="/_/d";</script>
<script src="/_/d.js" defer></script>
Query browser data with:
npx dbg browser consolepnpm dlx dbg browser consolebun x dbg browser consoleyarn dlx dbg browser consolenpx dbg browser errorspnpm dlx dbg browser errorsbun x dbg browser errorsyarn dlx dbg browser errorsnpx dbg browser networkpnpm dlx dbg browser networkbun x dbg browser networkyarn dlx dbg browser networknpx dbg browser storagepnpm dlx dbg browser storagebun x dbg browser storageyarn dlx dbg browser storageFull example
See the complete working example at examples/rust/axum.



