~/nouns
a REST API that builds REST APIs. and the UI for them.
you make API calls. nouns builds the backend, the JWT-protected end-user accounts, the OpenAPI spec, and a hosted, themable customer-facing site — all from JSON definitions you POST.
no migrations, no models, no deploys, no frontend build. define a noun, define a page, ship.
try it now see an example self-host
# one customer = one developer account.
POST /customers/signup
{ "email": "you@example.com", "password": "..." }
# → token + your customer uuid (lives in your app's URLs).
POST /apps
{ "slug": "todo" }
POST /apps/todo/nouns
{
"name": "task",
"fields": { "title": "string", "done": "bool", "priority": "int" },
"enabled_actions": ["list", "create", "partial_update", "destroy"],
"filterable_fields": ["done"]
}
# end-users sign up here:
POST /<your_uuid>/todo/auth/signup
# they CRUD their tasks at:
POST /<your_uuid>/todo/task # create
GET /<your_uuid>/todo/task # list (?done=false works)
PATCH /<your_uuid>/todo/task/<id> # update
DELETE /<your_uuid>/todo/task/<id> # delete
# live OpenAPI 3 spec + Scalar docs at:
GET /<your_uuid>/todo/openapi.json
GET /<your_uuid>/todo/docs
# declare a few pages — table, cards, form, or detail layouts:
POST /apps/todo/pages
{
"slug": "tasks",
"title": "All Tasks",
"layout": "table",
"noun": "task",
"columns": ["title", "done", "priority"],
"actions": ["create", "edit", "delete"]
}
# wire them into a navigation block:
PUT /apps/todo/navigation
{ "items": [{"label": "Tasks", "page": "tasks"}] }
# (optional) brand it with three CSS knobs:
PUT /apps/todo/theme
{ "bg": "#1a0033", "fg": "#ff66cc", "accent": "#ffcc00" }
# your end-users land here, no frontend code required:
GET https://nouns-app.pages.dev/site/<your_uuid>/todo/tasks
that's the whole loop. tables are inline-editable, references auto-expand, m2m fields render as multi-selects, and your end-users sign in with the auth you got for free in step 4.
a runnable, fully-commented worked example — workout tracker — shows the entire flow in ~150 lines of bash.
public_read toggle when you want everyone to see itreference:<noun> for 1:N,
reference:<noun>[] for many-to-many. inline
expansion via ?expand=field; protected deletes (no
dangling references); contains-style filters for m2m.nouns-app.pages.dev/site/<uuid>/<app>/<page>.
tables are inline-editable; forms support
on_submit: redirect:<page>.PUT /apps/<slug>/theme./admin/import; nouns parses it, previews the API
calls, and instantiates the whole app on confirm.__gt, __contains) — exact-match only today?expand=post.author)they show up when someone actually needs them.
the easiest way: just sign up at the hosted admin, paste a mermaid ER diagram into /admin/import, and you have a live app in seconds. or follow the workout-tracker walkthrough end-to-end.
prefer to self-host?
git clone <repo> nouns
cd nouns/api
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python manage.py migrate
.venv/bin/python manage.py runserver 127.0.0.1:8766
then visit the CRUD client at
localhost. full deploy walkthrough in DEPLOY.md.