A quiet home for the things you need to do.
A self-hosted todo app you live in from the terminal — TUI by default, CLI for scripts. One Go binary, one SQLite file, optional multi-user via invite.
Self-hosted, so it's yours. On every device, so it's always there. Open to a few, when you'd like the company. Small enough to forget you're running it.
- TUI by default, CLI for scripts — same server, no separate daemon
- Projects + Inbox, markdown descriptions, done/undone
- Search across todos and projects
- Multi-user — first to register owns the server, others join by invite link
- Activity feed — see who changed what, when
- One container, one SQLite file — back it up with
cp
Run the server — one container, one persistent volume:
docker run -d --name dox \
-p 6278:6278 \
-v /opt/dox/data:/app/data \
sn0wl1n/dox:latestOr with Docker Compose — see docker/docker-compose.yml:
docker compose -f docker/docker-compose.yml up -dThen install the client and point it at the server:
npm install -g @l1nsn0w/dox # or: bun add -g @l1nsn0w/dox
doxThe TUI handles onboarding (register · login · accept invite) and everything after.
┌──────────┐ ┌──────────┐ ┌──────────┐
│ CLI │ │ TUI │ │ any │
│ │ │ │ │ client │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
│ HTTP/JSON │ HTTP/JSON │ HTTP/JSON
└──────────────┼──────────────┘
▼
┌─────────────────┐
│ dox-server │
│ (Go + SQLite) │
└─────────────────┘
just gen # proto → Go + TS, sqlc → Go DB bindings
just serve # run the server locally
just cli # run the CLI against the local serverA thank-you wall for the people who support my work, alongside a "buy me a coffee" link. It lives at sponsor.sn0w.fyi.
