Local-first, for real
Every device keeps a full copy of your tasks. The app opens instantly, works on a plane, and syncs the moment it sees your server again.
Open source · AGPL-3.0 · v0.1
An open-source, local-first task manager you host yourself. Everything you expect from a polished task app, without the subscription, the tracking or the lock‑in.
Go ahead, it works. Press q to add a task, j/k to move, c to complete.
All clear. Enjoy your day. 🌿
Why OpenTodo
Every device keeps a full copy of your tasks. The app opens instantly, works on a plane, and syncs the moment it sees your server again.
Capture, triage and finish without touching the mouse. Try the keys below.
A single SQLite file in one volume. Back it up and you have backed up everything. JSON export any time.
One distroless container, no database server, no Redis. Happy on a Raspberry Pi or the cheapest VPS.
The app makes no requests except to your server. No telemetry, no crash reporters, no third-party fonts.
REST endpoints and API tokens write through the same op log as the app. Create a task with curl and watch it land on your phone on the next sync.
# add a task from a script curl -X POST $OPENTODO/api/v1/tasks \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"title":"Renew passport","priority":1}'
Every feature starts as an OpenSpec change. Behavior is written down before it is built, so you can read exactly how it works.
Sync that just converges
Every change is a tiny operation on one field, stamped with a hybrid logical clock. Devices queue them while offline and exchange them when they reconnect. The same rule runs everywhere, so every device lands on the same state. Play with it:
Toggle Wi-Fi on a device, change something, then reconnect.
Tip: click a task title to rename it, click the circle to complete it.
Looks like it costs money
Installable as an app on iPhone, Android and desktop. Light and dark mode follow your system.
The honest comparison
Self-host in 2 minutes
Point Coolify at the repository, or run one command. Open the URL, create the owner account, done. Updates are a redeploy; migrations run on start.
# In Coolify: + New Resource → Public Repository Repository https://github.com/pixari/opentodo Branch main Build pack Dockerfile Port 8080 Storage volume → /data # Add your domain, press Deploy. That's it.
$ git clone https://github.com/pixari/opentodo.git $ cd opentodo $ docker compose up -d # → open http://localhost:8080
# needs Go 1.26+ and Node 22+ $ make build $ ./bin/opentodo # serves on :8080, data in ./data
What's next
Deploy OpenTodo tonight. Your tasks will still be yours in ten years.