Offline-first, self-hosted task manager with multi-device sync.
Perists work locally for offline use and syncs w/ server for automatic conflict resolution.
OPFS storage in browser, websocket sync and SQLite persistence on the server.
Intended for multi-device use with no authorization logic.
- Areas — ongoing spheres of responsibility, with recursive sub-areas as deep as you need.
- Projects — bounded goals inside areas, grouped Active/Backlog/Done; Done is derived from task completion, never stored.
- Sections — group tasks within a project.
- Tasks — arbitrarily nested sub-tasks.
- Drag and Drop Trees: reorder, nest, and unnest in one flattened drag surface.
- Inbox / Today / Week views with recursive open-task rollups across area subtrees.
- Themes (light/dark/system), five fonts, three densities; per-device view state stays out of sync.
- Sync log — full per-event viewer (pulls / pushes / connections) per session.
- Offline-first. The entire app runs against an in-browser store persisted to OPFS — no account, no login, works without a network.
- Self-hosted. The entire backend is a single Bun process — static files, WebSocket sync, and one SQLite DB file. Nothing else to deploy, and your data never leaves machines you control.
- Multi-device sync. Clients converge over WebSocket via CRDT-style merge (per-cell HLC timestamps, last-writer-wins) — no conflict dialogs. A sidebar badge shows sync state (Local only → Syncing… → Synced).
The client keeps all state in a TinyBaseMergeableStore persisted to OPFS in the browser. A WsSynchronizer merges it with the server's authoritative SQLite copy, so edits on multiple devices converge automatically. The same sync handler serves dev and prod.
Browser Server Browser
┌────────────────────┐ ┌───────────────────────────┐ ┌────────────────────┐
│ React SPA │ │ static file server │ │ React SPA │
│ MergeableStore ◄───┼── /ws ──┤► sync (createWsServer) ◄┼─ /ws ─┼──► MergeableStore │
│ OPFS persister │ │ persist (SQLite) │ │ OPFS persister │
└────────────────────┘ └───────────────────────────┘ └────────────────────┘
Requires Bun (package manager and runtime — the server uses bun:sqlite).
bun install
bun run dev # Vite dev server + sync WS (http://localhost:5173)Production:
bun run build
bun run prod # port 7373, SQLite in the platform user-data dir
bun run preview # port 7474, preview store (data-preview.db)bun run prod/bun run preview accept --port <n> and --db <path>; --help prints defaults.
Multi-device sync: run bun run prod on a reachable host and point every client at that host. No auth at the moment.
- Vite 8 · React 19 (Compiler) · TypeScript · TinyBase 9 · SQLite (
bun:sqlite) ·ws· dnd-kit · markdown-it bun test— unit + integration suites;bun run smoke— WS/SQLite round-trip; Playwright e2e (bun run test:e2e)
docs/architecture.md— client/server/sync/data model, runtime modes, testing strategydocs/ux.md— shell, navigation, views, appearance, interaction patternsdocs/glossary.md— domain vocabulary (areas, projects, sections, tasks, notes…)PRODUCT.md/DESIGN.md— positioning and the visual system
AGPL-3.0-or-later
