express-sqlite-admin
v1.0.2
Published
Zero-dependency Express middleware for a SQLite admin panel
Maintainers
Readme
🗄️ express-sqlite-admin
A zero-dependency Express middleware that gives you a web admin panel for any SQLite database.
Install. Mount. Done. ✅
✨ Features
- 🔌 Drop-in middleware — one line to add to your Express app
- 📦 Zero dependencies — nothing installed beyond what you already have
- 🔒 Password protected — cookie-based auth with rate-limited login
- 👀 Read-only by default — opt in to writes explicitly
- 📱 Mobile friendly — responsive UI that works on any screen size
- ✏️ Browse, search, edit, delete — full CRUD for your tables
- 🛡️ SQL injection safe — parameterized queries, validated table/column names
📦 Installation
npm install express-sqlite-adminPrerequisites: You need express and better-sqlite3 in your project.
🚀 Quick Start
const express = require('express');
const Database = require('better-sqlite3');
const sqliteAdmin = require('express-sqlite-admin');
const app = express();
const db = new Database('my-app.db');
app.use('/admin', sqliteAdmin({
db: db,
password: process.env.ADMIN_PASSWORD,
readonly: false
}));
app.listen(3000);That's it! Visit http://localhost:3000/admin and log in with your password. 🎉
⚙️ Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| db | Database | required | A better-sqlite3 database instance |
| password | string | required | Password for the admin panel (min 8 characters) |
| readonly | boolean | true | Set to false to enable editing and deleting rows |
🔐 Security
- Password — required, minimum 8 characters, compared using timing-safe equality
- Cookies — signed with HMAC-SHA256,
HttpOnly,SameSite=Strict, autoSecureover HTTPS - Rate limiting — 5 login attempts per IP per 60 seconds
- SQL safety — table and column names validated against
sqlite_master, all values parameterized - Error handling — database errors are logged server-side, never exposed to the browser
- Read-only default — no writes unless you explicitly opt in
⚠️ Always use a strong password and HTTPS in production.
📖 What You Can Do
| Feature | Read-only mode | Write mode | |---------|:--------------:|:----------:| | 📋 View all tables with row counts | ✅ | ✅ | | 🔍 Browse table data (paginated) | ✅ | ✅ | | 🔎 Search across text columns | ✅ | ✅ | | ✏️ Edit rows | ❌ | ✅ | | 🗑️ Delete rows (with confirmation) | ❌ | ✅ |
🛣️ Routes
Once mounted, the middleware provides these routes:
| Route | Description |
|-------|-------------|
| GET /login | Login page |
| POST /login | Authenticate |
| GET /logout | Log out |
| GET / | List all tables |
| GET /:table | Browse table rows |
| GET /:table/:rowid | Edit row form (write mode) |
| POST /:table/:rowid | Save row (write mode) |
| POST /:table/:rowid/delete | Delete row (write mode) |
All routes are relative to your mount path (e.g. /admin/login).
💡 Tips
Use an environment variable for the password
// Don't hardcode passwords!
sqliteAdmin({ db, password: process.env.ADMIN_PASSWORD })Enable WAL mode for better performance
const db = new Database('my-app.db');
db.pragma('journal_mode = WAL');Mount at any path
app.use('/secret-panel', sqliteAdmin({ db, password: '...' }));
// Now available at /secret-panel🚫 What This Doesn't Do
This is intentionally simple. It does not include:
- Schema editing (CREATE / DROP / ALTER)
- Raw SQL console
- CSV import/export
- Multi-user auth or roles
- Real-time updates
📄 License
MIT — use it however you want.
