A minimal, fast todo list app with real-time sync across devices.
- Multiple lists with custom emoji icons
- Real-time sync across devices via Server-Sent Events (SSE)
- Offline-first with RxDB (IndexedDB) and bidirectional sync
- Undo actions with history tracking
- PWA installable on mobile and desktop
- Drag-and-drop list reordering
- Sorting options for items and lists (alphabetical, date, custom)
- Backend: FastAPI, Uvicorn, SQLite
- Frontend: Vanilla JavaScript, RxDB, Vite
- Infrastructure: Docker (multi-arch: amd64, arm64, armv7)
Use the docker-compose.yml from this repository:
docker compose pull
docker compose up -dThe SQLite database is persisted in ./data/.
Requires Python 3.13+ and Node.js 22+.
# Backend
pip install .
# Frontend
cd frontend && npm install && npm run build && cd ..
# Run
python main.pyAll settings can be overridden via TICKR_* environment variables. Copy the example file to get started:
cp .env.example .envSee .env.example for the full list with defaults.
| Variable | Default | Description |
|---|---|---|
TICKR_DATABASE |
data/tickr.db |
SQLite database path |
TICKR_RATE_LIMIT_REQUESTS |
100 |
Max requests per window per IP |
TICKR_RATE_LIMIT_WINDOW |
60 |
Rate limit window in seconds |
TICKR_RATE_LIMIT_MAX_IPS |
10000 |
Max tracked IPs in rate limiter |
TICKR_MAX_SSE_CLIENTS |
10 |
Max concurrent SSE connections |
TICKR_SSE_HEARTBEAT_INTERVAL |
15 |
SSE heartbeat interval in seconds |
TICKR_BACKUP_DIR |
data/backups |
Backup output directory |
TICKR_BACKUP_RETAIN |
7 |
Number of backups to keep |
See docker-compose.yml for a ready-to-use Docker Compose setup with commented-out environment overrides.
Interactive docs available at /docs (Swagger UI) and /redoc.
# Install dev tools
pip install ruff mypy
# Lint and format
ruff check --fix .
ruff format .
# Type check
mypy main.py
# Frontend dev server (with API proxy to FastAPI)
cd frontend && npm run dev