Skip to content

Repository files navigation

🍃 Mongui

A lightweight, self-hosted web UI for browsing, querying, and editing MongoDB.

Point it at one MONGODB_URI, log in, and work with your data from the browser — databases, collections, documents, queries, aggregations, and indexes.

CI Docker image License: MIT Next.js 16 MongoDB driver 7

Quick start · Features · Configuration · API · Security


✨ Features

🗂️ Navigate Sidebar tree of databases and collections with document counts; create a database or collection inline.
📋 Browse Paginated, capped document table — a large collection is never loaded in full.
🔎 Query Filter, sort, and projection as Extended JSON, validated server-side before it reaches the driver.
✍️ Edit Full document CRUD in a CodeMirror 6 JSON editor with syntax highlighting and parse errors surfaced inline.
🧮 Aggregate Run pipelines against a collection; write stages ($out, $merge) are blocked in read-only mode.
Indexes List, create, and drop indexes per collection.
🔐 Auth Cookie session via iron-session + bcrypt. Every API route is guarded; unauthenticated calls get 401.
🛡️ Read-only mode READ_ONLY=true makes every write path return 403 before it touches the database.
🧬 EJSON end to end ObjectId, Date, Decimal128 round-trip safely — no silent JSON.stringify corruption.
♻️ One pooled connection A single cached MongoClient singleton, reused across requests and hot reloads.
🐳 Ships as a container Multi-stage Dockerfile, OCI labels, and a Compose file with a sample MongoDB.

🚀 Quick start

Docker Compose (Mongui + a sample MongoDB)

docker compose up --build
# open http://localhost:3000   (login: admin / change-me)

Change ADMIN_PASSWORD and SESSION_SECRET in docker-compose.yml before any real use.

Production image

Published as a multi-arch manifest (linux/amd64 + linux/arm64) on every v* tag, to ghcr.io/soumya7681/mongui and docker.io/soumyaranajan/mongui.

docker run -p 3000:3000 \
  -e MONGODB_URI="mongodb://user:pass@host:27017/?authSource=admin" \
  -e ADMIN_USER=admin \
  -e ADMIN_PASSWORD="a-strong-password" \
  -e SESSION_SECRET="$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")" \
  ghcr.io/soumya7681/mongui:latest

Build it yourself instead with docker build -t mongui ..

Local development

Requires Node.js 20.9+ and a reachable MongoDB.

npm install
cp .env.example .env.local   # then edit the values
npm run dev                  # http://localhost:3000

⚙️ Configuration

Everything is environment variables — see .env.example.

Variable Required Default Description
MONGODB_URI Connection string for the single MongoDB instance. Include credentials + authSource when the server has auth enabled.
ADMIN_USER Login username.
ADMIN_PASSWORD Login password in plaintext — Mongui bcrypt-hashes it at runtime, so you never generate or escape a hash yourself.
SESSION_SECRET 32+ character secret encrypting the session cookie. Generate with node -e "console.log(require('crypto').randomBytes(32).toString('hex'))".
READ_ONLY false When true, every write (insert / update / delete / drop / $out / $merge) returns 403.

Secrets live in .env.local (gitignored); .env.example documents every variable.

🔐 Security

Warning

Mongui grants full read/write access to the configured database. Do not expose it on the public internet. Keep it behind a network boundary (VPN or private network), always set a strong ADMIN_PASSWORD and a random SESSION_SECRET, and use READ_ONLY=true for a browse-only deployment.

Built-in guardrails:

  • Session check on every route under /api except auth/login.
  • Login rate limiting to blunt brute-force attempts.
  • Query limits capped server-side (max 200 documents per page) plus a maxTimeMS on every operation.
  • Filters, sorts, and projections validated with zod; unparseable input is rejected with 400, never passed through.
  • Destructive UI actions require confirmation — drops require typing the name.

📡 API

All routes return JSON. Errors use { "status": "error", "message": string }.

Method Route Purpose
GET /api/health Ping + MongoDB server version.
POST /api/auth/login Create a session.
POST /api/auth/logout Destroy the session.
GET /api/databases List databases.
GET POST DELETE /api/databases/[db]/collections List, create, or drop collections in a database.
GET POST /api/databases/[db]/[collection]/docs Query (filter/sort/projection/pagination) or insert.
GET PUT DELETE /api/databases/[db]/[collection]/docs/[id] Read, replace, or delete one document.
POST /api/databases/[db]/[collection]/aggregate Run an aggregation pipeline (capped, read-only aware).
GET POST DELETE /api/databases/[db]/[collection]/indexes List, create, or drop indexes.
Example: query with a filter
curl -s 'http://localhost:3000/api/databases/mydb/users/docs?filter={"age":{"$gt":21}}&sort={"age":-1}&limit=20' \
  -H 'Cookie: <session cookie>'

Filter, sort, and projection are Extended JSON, so {"_id":{"$oid":"..."}} works as expected.

🧰 Scripts

npm run dev      # dev server (Turbopack) on :3000
npm run build    # production build
npm run start    # serve the production build
npm run lint     # eslint
npm test         # vitest unit tests

🏗️ Tech stack

Next.js 16 (App Router, Turbopack) · React 19 · TypeScript (strict) · official mongodb driver 7 · Tailwind CSS 4 · TanStack Query & Table · CodeMirror 6 · iron-session · bcryptjs · zod · Vitest.

🤝 Contributing

Issues and pull requests are welcome. Run npm run lint, npm test, and npm run build before opening a PR — CI runs the same on Node 22. Project context for contributors (and coding agents) lives in AGENTS.md, scope in PLAN.md, and detailed requirements in REQUIREMENTS.md.

📄 License

MIT © Soumyaranjan

About

A lightweight, self-hosted web UI for browsing and editing MongoDB like adminer

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages