SmallStack v0.16.2 → Changelog & source
One small backend. Many roles.

Django,
fully assembled

Declare a model once and SmallStack serves it every way at once—an admin app, a REST backend for your React frontend, an MCP server for Claude, and a fast search engine—with OpenAPI docs, webhooks, and feeds on the same SQLite file, behind one zero-downtime deploy.

Django 6.1 Python 3.12 SQLite + WAL Docker Kamal 2
01 One model

The same class declaration produces an HTML interface, a REST endpoint, an MCP tool, full-text search, and a terminal CLI. Add a field, get a column, a JSON key, a tool argument, and a search index—everywhere at once.

Five surfaces from one declaration.

A CRUDView bound to a model derives its own list, detail, create, update, and delete tools—then exposes them on the surfaces you opt into.

# apps/tickets/views.py
class TicketCRUDView(CRUDView):
    model         = Ticket
    list_columns  = ["id", "title", "status"]
    enable_api    = True     # REST + OpenAPI
    enable_mcp    = True     # tools for Claude
    enable_search = True     # full-text + RAG tool
/tickets/ HTML list, detail, edit, delete—with htmx tabs & filters.
/api/tickets/ REST endpoints with paginated JSON and an OpenAPI 3.0 spec.
/mcp JSON-RPC tools tickets_list, tickets_get, etc.—ready for Claude.
/search/ Full-text search page + a search_tickets MCP tool for retrieval (RAG).
sc tickets Terminal CRUD—sc ls, get, search, staff-gated new/set/rm—same ops, --json everywhere.
02 Many roles

SmallStack isn't one kind of app. It's a small backend that drops into your architecture and plays whatever role you need—usually several at once.

Not an app type. A role you fill.

a / admin app

A polished admin

Auth, profiles, five-palette light/dark, table views, modal editors, filters, breadcrumbs—the internal tool you'd build anyway.

/tickets/
b / headless api

A backend for your frontend

REST with token auth and OpenAPI 3.0, plus bundled typed clients for React, Svelte, Solid & Streamlit. Point your SPA at it.

/api/
c / mcp server

An MCP server for AI

OAuth + JSON-RPC tools derived from your models—Claude Desktop and the Connectors UI work with no setup.

/mcp
d / search engine

A search engine

Real full-text search—FTS5 on SQLite, tsvector on Postgres—ranked, with a Ctrl-K omnibar and an MCP tool.

/search/
e / integration layer

An integration hub

Signed webhooks in and out, RSS/Atom publish + consume, and Swagger + ReDoc for every endpoint. The seam between your systems.

/webhooks/
f / task runner

A scheduled task runner

One-shot jobs plus recurring @scheduled work—cron, interval, or once—with a themed UI. No Redis, Celery, or beat.

/scheduler/
03 Search

Real full-text search, built in—not a LIKE query. Ranked, fast, and the same code path on SQLite or Postgres.

A search engine, included.

Add enable_search = True and a model gets a real index—FTS5 with BM25 ranking on SQLite, a tsvector + GIN index on Postgres—self-provisioned at migrate, no migration to write.

  • Ranked & weighted—per-field search_weight tunes what wins, with snippets and prefix matching.
  • Four ways in—a Ctrl-K omnibar, a /smallstack/search/ page, a REST endpoint, and a search_X MCP tool.
  • SearchBuilder—define tailored variants (admin, public, api), each with its own MCP tool and JSON serialization. No DRF.
  • Retrieval for AI—that search_X tool is RAG: Claude answers from your own records.
# One flag turns a model into a search source.
class TicketCRUDView(CRUDView):
    model         = Ticket
    enable_search = True
    search_fields = ["title", "description"]

# You now have, with no extra code:
#   • FTS5 / tsvector index, self-provisioned
#   • omnibar + /search/ page + REST
#   • search_tickets(query, limit) MCP tool
04 Integrations

The backend everything else talks to—your React app, your automations, and the systems next door.

The backend everything else talks to.

Every enable_api model is a documented REST resource. OpenAPI 3.0 feeds Swagger UI and ReDoc out of the box—hand the schema to any client or codegen.

  • A backend for React—bundled typed TypeScript/JS and single-file Python clients ship in clients/: token auth, CRUD helpers, field-error maps, always API-version-matched.
  • Webhooks, both ways—signed outbound on change, verified inbound; Zapier, n8n, Stripe, and Slack are plug-ins on four seams.
  • Feeds, both ways—publish any model as RSS/Atom, or consume an external feed on a schedule.
  • Live docs/api/docs/ (Swagger), /api/redoc/ (ReDoc), /api/schema/openapi.json.

See the React, Svelte, Solid & Streamlit guides →

// Your SPA, talking to SmallStack — no SDK to publish.
import { SmallStackClient } from 'smallstack-sdk-js'

const api = new SmallStackClient({ baseUrl: API_URL })
await api.auth.login('admin', 'admin')

const items = api.resource('/api/inventory/items')
const page  = await items.list({ q: 'drill', status: 'active' })
// typed rows, token handled, errors → field map
05 Two editions

Same engine, two starters. smallstack-tabler is a downstream fork that tracks this repo and swaps the chrome.

Two starters for two shapes of work.

a / smallstack

For CRUD & headless work

Django admin's base CSS, customized per palette—no extra framework. Light/dark with 5 palettes; HTMX in every CRUDView. The sweet spot for internal admins, REST APIs, and MCP servers.

$git clone django-smallstack
b / smallstack-tabler

When the UI is the product

Forks & tracks smallstack; swaps the chrome for Tabler. Dashboards, charts, kanban, calendar—anywhere a public-grade UI matters as much as the data.

$git clone smallstack-tabler
06 Day one

Boring infrastructure, already done. Thirteen admin surfaces wired into the sidebar before you write a line.

The admin you'd build anyway, already built.

/explorer Explorer Every model, browsable.
/search Search new Full-text, per-model opt-in.
/mcp MCP admin Health, tools, traffic.
/api API admin v0.10 Threat panel.
/activity Activity Request log, paths, latency.
/tokens Tokens Mint, search, revoke.
/backups Backups SQLite snapshots + restore.
/status Status Public uptime page.
/users Users Roles, password resets.
/help Docs Markdown + slide decks.
/runbook Runbook Versioned markdown docs.
/scheduler Scheduler new Recurring @scheduled jobs.
/webhooks Webhooks new Inbound + outbound events.
07 Boring on purpose

Most apps don't need the cluster they were architected for. SmallStack is built around that admission—lightweight, boring, and useful for years without a rebuild.

Unapologetically SQLite.
One file. Five years of customers. Zero rebuilds.

postgres + pgbouncer
redis + sentinel
celery + beat + rabbit
nginx + certbot
1 .sqlite3 database
WAL + IMMEDIATE tuned defaults
$4 / mo vps headroom
08 Knowledge base

New in v0.13.0. Operational docs that live in the app—versioned, searchable, and reachable from every surface.

A runbook your app remembers.

Runbook ships in core. Write Markdown in the browser, keep an immutable version on every save, and find anything with full-text search. Set retention policies, export a runbook to a portable ZIP, restore any past version—nothing is ever destructive.

web REST MCP CLI one document, four ways in
# the same doc, straight from your shell — the rb CLI
rb find "postgres upgrade"
#  → ops/postgres-major-upgrade   v7
rb cat ops/postgres-major-upgrade
# …or let Claude call search_runbook_documents
# versioned · searchable · OAuth + bearer
09 AI-native

Every app ships with the skill files Claude Code needs to understand it. Open the repo, start vibing.

Vibe-code with Claude—and serve it, too.

Two sides of the same idea. SmallStack is readable by AI (skill files for the theme, CRUD, MCP, deployment) and serves AI—through a first-class MCP server that exposes your existing models as tools.

  • CLAUDE.md at the root: your project's onboarding doc.
  • 20+ skill files teaching the stack one pattern at a time.
  • Ten-minute MCP walkthrough from enable_mcp = True to Claude calling your tools.
  • Retrieval built in—the search_X tool is the lowest-friction RAG; Claude answers from your own records.
# Two flags: act on data, and find it.
class TicketCRUDView(CRUDView):
    model         = Ticket
    enable_mcp    = True
    enable_search = True

# That's it. Claude Desktop sees:
#   • tickets_list   (search + filter)
#   • tickets_get    (by id)
#   • tickets_create / update / delete
#   • search_tickets (full-text → RAG)
# All authenticated by OAuth + bearer.
10 Run it

Three commands to a running app.

Free, MIT-licensed, self-hosted in minutes. Managed hosting from $15 / month when you'd rather not.

$git clone github.com/emichaud/django-smallstack my-app
$cd my-app && make setup # creates venv, migrates, seeds admin/admin
$make run # serving on :8005
This site runs on SmallStack v0.16.2. github  ·  tabler  ·  docs  ·  pricing