Jottit makes getting a website as easy as filling out a textbox. Each site lives at its own subdomain (myblog.jottit.org) or its own secret URL (jottit.org/abc12/).
This is a modern port of the 2007 Jottit codebase originally written by Simon Carstensen and Aaron Swartz. The Python 2 + web.py + Jinja 1 + psycopg2 stack has been rewritten on Flask 3 + SQLAlchemy Core 2 + Jinja2 + psycopg3, with the original look-and-feel preserved.
You'll need uv and Postgres.
# Install Postgres and start it
brew install postgresql@16
brew services start postgresql@16
# Create the dev database
createdb jottit_dev
# Install Python dependencies
uv sync
# Configure your environment
cp .env.example .env
# Create the schema
uv run --env-file .env alembic upgrade head
# Run the dev server
uv run flask --app jottit run --port 5000Open http://localtest.me:5000. The default JOTTIT_DOMAIN=localtest.me:5000 uses localtest.me — *.localtest.me resolves to 127.0.0.1 — so subdomain routing works without any /etc/hosts edits.
The schema is managed with Alembic. jottit.db.metadata is the source of truth; migration files live under migrations/versions/.
# Apply all pending migrations
uv run --env-file .env alembic upgrade head
# Autogenerate a new migration after editing jottit/db.py
uv run --env-file .env alembic revision --autogenerate -m "describe the change"
# Inspect history
uv run --env-file .env alembic current
uv run --env-file .env alembic historyIf your dev database already has tables but no alembic_version row (e.g., it was created by an older metadata.create_all bootstrap), stamp it at the initial revision before running upgrade:
uv run --env-file .env alembic stamp 704f4e95f8bfAlways review autogenerated migrations before committing — Alembic can miss column renames, server-side defaults, and check constraints.
uv run pytestTests spin up a fresh jottit_test database against your local Postgres, run, and drop it at the end. They use metadata.create_all directly rather than the migration chain, so adding a column to jottit/db.py is enough to keep them green — but you still need to write a migration for it to reach prod.
AGPLv3 — see LICENSE.md and NOTICE for the relicensing path from the 2007 LGPLv3 original.