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.
What you get today


The same app, the same offline copy of your data. The detail panel slides over the list; the sidebar tucks behind a menu. No app store, no account on anyone else's server.
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
Every planned feature exists as an OpenSpec change: a proposal, behaviour specs with testable scenarios, a design and a task list, all validated before a line of code is written. 35 changes are specified and waiting to be built. Click any item to read exactly how it will behave.
Deploy OpenTodo tonight. Your tasks will still be yours in ten years.