A development tool for viewing and querying SQL databases in web browsers, easily integrable as an Axum layer. Drop in a single line of code to get a full-featured database browser for your application.
Note: Currently supports SQLite and PostgreSQL databases via SQLx.
Warning
Development Use Only - This tool is intended for local development and debugging purposes. It is not suitable for production environments because:
- No authentication - The viewer is publicly accessible to anyone who can reach the endpoint
- Full database access - Exposes complete schema, data, and allows raw SQL execution (including INSERT/UPDATE/DELETE)
- Potential data exposure - All database contents are viewable through the web interface
If you need production database management, use proper database administration tools with appropriate security controls.
- Table Browser - Browse all tables with infinite scrolling and virtual rendering
- Column Sorting - Click column headers to sort ascending/descending
- Column Resizing - Drag column borders to resize
- Row Selection - Select rows for batch operations
- Schema Viewer - View table structure, primary keys, foreign keys, and indexes
- Raw SQL Execution - Execute arbitrary SQL queries with results display
- Query History - Automatically saves executed queries for quick re-use
- Saved Queries - Save frequently used queries with custom names
- Import/Export - Export saved queries to JSON, import from files
- Dark/Light Theme - Toggle between themes based on preference
- Embedded Frontend - No separate frontend deployment needed; assets are embedded in the binary
Add to your Cargo.toml:
[dependencies]
axum-sql-viewer = "0.1"sqlite- Enable SQLite support (enabled by default)postgres- Enable PostgreSQL support (enabled by default)
To use only one database:
[dependencies]
axum-sql-viewer = { version = "0.1", default-features = false, features = ["sqlite"] }use axum::{Router, routing::get};
use axum_sql_viewer::SqlViewerLayer;
use sqlx::SqlitePool;
#[tokio::main]
async fn main() {
let pool = SqlitePool::connect("sqlite:./my_database.db")
.await
.unwrap();
let app = Router::new()
.route("/", get(|| async { "Hello World" }))
// Add the SQL viewer at /sql-viewer
.merge(SqlViewerLayer::sqlite("/sql-viewer", pool).into_router());
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
println!("SQL Viewer available at http://localhost:3000/sql-viewer");
axum::serve(listener, app).await.unwrap();
}use axum::{Router, routing::get};
use axum_sql_viewer::SqlViewerLayer;
use sqlx::PgPool;
#[tokio::main]
async fn main() {
let pool = PgPool::connect("postgres://user:password@localhost/mydb")
.await
.unwrap();
let app = Router::new()
.route("/", get(|| async { "Hello World" }))
.merge(SqlViewerLayer::postgres("/sql-viewer", pool).into_router());
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}That's it! Navigate to http://localhost:3000/sql-viewer to browse your database.
Mount the viewer at any path:
SqlViewerLayer::sqlite("/admin/database", pool) // Viewer at /admin/database
SqlViewerLayer::sqlite("/debug/sql", pool) // Viewer at /debug/sqlThe following HTTP endpoints are available under your configured base path:
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Serves the web dashboard |
/api/health |
GET | Health check endpoint |
/api/tables |
GET | List all tables in the database |
/api/tables/:name |
GET | Get table schema information |
/api/tables/:name/rows |
GET | Fetch rows with pagination and sorting |
/api/query |
POST | Execute a raw SQL query |
limit- Number of rows to fetch (default: 100)offset- Number of rows to skip (default: 0)sort_column- Column name to sort bysort_order- Sort direction:ascendingordescending
curl -X POST http://localhost:3000/sql-viewer/api/query \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT * FROM users WHERE active = true"}'- Rust 1.70+
- Node.js 18+ and pnpm (for frontend development)
# Build the entire project (includes frontend)
cargo build
# Run the example server
cargo run -p example-servercd axum-sql-viewer/frontend
pnpm install
pnpm dev # Start dev server with hot reload- SqlViewerLayer wraps your SQLx connection pool and provides HTTP endpoints
- The web dashboard is served as embedded static assets (no external files needed)
- Database schema is discovered dynamically at runtime
- Virtual scrolling enables browsing large tables efficiently
- All state (query history, saved queries, theme) is stored in browser localStorage
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.

