DEV Community

Cover image for I built a FastAPI admin panel that doesn't suck (and here's why it's different)
Muhammed Rasin O M
Muhammed Rasin O M

Posted on

I built a FastAPI admin panel that doesn't suck (and here's why it's different)

TL;DR: FastAPI Matrix Admin combines one-line auto-discovery, async-first architecture, and production-grade security in a package that requires zero Node.js.

🟢 Live Demo (Read-only)
💻 Github Repo

The admin panel problem nobody talks about

Every FastAPI project follows the same arc:

  1. You build a great API.
  2. Product wants to "just update a few records manually."
  3. You reluctantly install Django admin (now you have two frameworks).
  4. Or you build a custom React dashboard (6 weeks later...).
  5. Or you use a generic admin and spend days configuring it.

I've done all three. They all sucked for different reasons.

What's wrong with existing FastAPI admin solutions?

I evaluated every major option before building this. Here's what I found:

Library Issue
FastAPI-Admin Requires Tortoise ORM (can't use SQLAlchemy).
SQLAdmin Good, but sync-only. No async support in 2024?
Starlette-Admin Heavy Starlette dependency, limited FastAPI integration.
Admin-One Requires Vue.js build step, defeats FastAPI's simplicity.

The pattern: They either force you into specific ORMs, ignore async, or add frontend build complexity.


What I Built Instead

FastAPI Matrix Admin focuses on three non-negotiables:

1. One-Line Auto-Discovery (Because Your Time Matters)

from fastapi_matrix_admin import MatrixAdmin

admin = MatrixAdmin(app, engine=engine, secret_key="...")
admin.auto_discover(Base)  # Done. All models registered.
Enter fullscreen mode Exit fullscreen mode

Under the hood:

  • Introspects SQLAlchemy models using inspect().
  • Analyzes column types to generate appropriate form fields.
  • Detects text columns for search.
  • Finds timestamp columns for default ordering.
  • Creates a sensible list display based on column types.

Customization when you need it:

admin.register(
    User,
    list_display=["id", "email", "created_at"],
    searchable_fields=["email", "name"],
    ordering=["-created_at"],
    exclude=["password_hash"]  # Obviously
)
Enter fullscreen mode Exit fullscreen mode

2. Zero Node.js (Seriously)

No npm. No webpack. No package.json.

  • Stack: Tailwind CSS via CDN, HTMX for dynamic updates, Alpine.js (3KB), and Jinja2 templates.
  • Why this matters:
    • pip install fastapi-matrix-admin → you're done.
    • No build step in CI/CD.
    • No frontend/backend version mismatches.
    • Deploys anywhere Python runs.

3. Production-Grade Security (Not an Afterthought)

Most admin libraries treat security as optional. Here is what is built-in:

  • Content Security Policy (CSP): Prevents XSS by strictly controlling script sources.
  • CSRF Protection: Every form gets a signed token automatically.
  • URL Signing: All admin URLs are cryptographically signed to prevent ID enumeration/tampering.
  • Type Safety with Pydantic v2: Input validation happens automatically.

Security Comparison:

Feature FastAPI Matrix Admin SQLAdmin FastAPI-Admin
CSP Headers ✅ Built-in ❌ Manual ❌ Manual
CSRF Protection ✅ Automatic ⚠️ Optional ❌ None
URL Signing ✅ Yes ❌ No ❌ No
Pydantic v2 ✅ Yes ⚠️ v1 ❌ No validation

Performance: Async All The Way Down

Full async support isn't optional in 2024.

# Async SQLAlchemy 2.0
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession

engine = create_async_engine("postgresql+asyncpg://...")
admin = MatrixAdmin(app, engine=engine)
Enter fullscreen mode Exit fullscreen mode

Simple benchmark (100 concurrent list view requests):

  • FastAPI Matrix Admin (async): ~50ms avg
  • SQLAdmin (sync): ~180ms avg (blocks other requests)

The Matrix UI (Yeah, It's Different)

I'm not going to pretend the cyberpunk aesthetic is for everyone. But here's why it exists:

Problem: Every admin panel looks the same. Generic Bootstrap tables. Boring gray sidebars. No personality.
Solution: Terminal-style green/black theme with neon accents.

It makes internal tools feel less corporate, and stakeholders actually remember seeing "that Matrix admin thing." (If you hate it, the CSS variables are customizable).


Quick Start

pip install fastapi-matrix-admin
Enter fullscreen mode Exit fullscreen mode
from fastapi import FastAPI
from sqlalchemy import Column, Integer, String, Boolean
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.orm import declarative_base
from fastapi_matrix_admin import MatrixAdmin

Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    email = Column(String, unique=True)
    is_active = Column(Boolean, default=True)

app = FastAPI()
engine = create_async_engine("sqlite+aiosqlite:///./database.db")

# That's it
admin = MatrixAdmin(app, engine=engine, secret_key="your-secret-key-min-32-chars")
admin.auto_discover(Base)
Enter fullscreen mode Exit fullscreen mode

Run it:

uvicorn app:app
# Visit http://localhost:8000/admin
Enter fullscreen mode Exit fullscreen mode

What's Next

Current roadmap:

  • [ ] File/image upload support
  • [ ] Advanced filters (date ranges, multi-select)
  • [ ] Export to CSV/Excel
  • [ ] Custom dashboard widgets
  • light theme for the Matrix-haters

Final Thoughts

I built this because I kept rebuilding the same admin panel over and over. Auto-discovery saves me hours per project. Zero Node.js means simple deploys. The security features mean I can actually use this in production.

If you try it, let me know what breaks. Or what you wish it did differently.

Questions I'd love feedback on:

  1. Is auto-discovery too magical, or genuinely useful?
  2. What security features am I missing?
  3. Would you actually use this in production?

Drop a comment or open an issue. First-time contributors welcome!

Github: fastapi-matrix-admin

Top comments (1)

Collapse
 
shahrouzlogs profile image
Shahrouz Nikseresht

Nice breakdown. It’s good to see a FastAPI admin panel that actually focuses on real pain points.