███████╗██████╗ ██████╗ ██████╗ ██╗████████╗
██╔════╝██╔══██╗██╔═══██╗██╔═══██╗██║╚══██╔══╝
█████╗ ██║ ██║██║ ██║██║ ██║██║ ██║
██╔══╝ ██║ ██║██║ ██║██║ ██║██║ ██║
██║ ██████╔╝╚██████╔╝╚██████╔╝██║ ██║
╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝
faster-dooit
Your todo app takes two seconds to open. This one doesn't.
vim-style terminal todo manager · Go + Bubble Tea · 10k todos in ~34 ms
> Not affiliated with the official dooit project — this is an independent, from-scratch port. AI-assisted hobby project.
Why
Your todo tool shouldn't make you wait. The original dooit pays 1.9 s cold-start and rebuilds its whole tree on every frame. faster-dooit loads 10,000 todos in ~34 ms, renders only what's visible, and never polls the database. It's vim, for your todos.
Features
- ⚡ Fast enough to feel instant — 10k todos cold-load in ~34 ms; the original takes ~1.9 s on the same machine
- 🎯 vim muscle memory —
j/k move, a adds, d 3d sets a due date, c completes
- 🗂️ Two-pane tree with folding — nested workspaces + todos,
z/Z to collapse, collapse_depth to auto-fold deep nodes
- 🎨 Themes that actually fit — 7 built-in presets (
nord, dracula, catppuccin_mocha…) plus per-color overrides and transparent backgrounds
- 🔌 Clean Lua config — no
api. prefix: theme.name, keys.set, vars.urgency_colors
- 📦 Single static binary — pure Go, no CGO, no runtime, no dependency tree to audit
Quick Start
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/XiaTian-AC/faster-dooit/main/install.sh | bash
# Windows
iwr -useb https://raw.githubusercontent.com/XiaTian-AC/faster-dooit/main/install.ps1 | iex
Or pick your package manager:
brew tap XiaTian-AC/XiaTian-AC-bucket && brew install faster-dooit # macOS/Linux
scoop bucket add faster-dooit https://github.com/XiaTian-AC/XiaTian-AC-bucket && scoop install faster-dooit # Windows
The command is fdooit. Build from source needs only Go ≥ 1.22.
Usage
fdooit
┌─ Workspaces ────────────────┐ ┌─ Todos ───────────────────────────────┐
│ ⌄ Work │ │ ⌄ o finish release notes @today │
│ > Personal │ │ o write the spec │
└─────────────────────────────┘ └───────────────────────────────────────┘
a add a todo · A add a child · c toggle complete · d set due (tomorrow, 3d, next monday)
z/Z fold a node / its parent · o expand a long description
S search · ctrl+s sort · y/Y copy · p/P paste · ? help
- Empty columns (no due/recurrence) hide automatically; a scrollbar appears on short terminals
Architecture
graph LR
A[Terminalfdooit] --> B[AppBubble Tea model]
B --> C[StoreSQLite, load-once]
B --> D[Luaconfig.lua runtime]
B --> E[Themepresets + overrides]
C --> F[(todo.db)]
style A fill:#E6A23C,color:#fff
style B fill:#409EFF,color:#fff
style C fill:#67C23A,color:#fff
style D fill:#F56C6C,color:#fff
style E fill:#9B59B6,color:#fff
style F fill:#909399,color:#fff
The performance model is three deliberate choices: load-once (DB read into memory at startup, edits write through), viewport-only rendering (row cache keyed by pane,id,version), and direct SQLite (pure Go, no CGO, single connection).
Configuration
config.lua lives at ~/.config/faster-dooit/config.lua (all platforms). An invalid file prints a file:line error and exits.
| Setting | Example |
|---|
| Theme | theme.name = "dracula" |
| Color override | theme.text_color = "#FF79C6" |
| Transparent bg | theme.background_color = "transparent" |
| Fold depth | vars.collapse_depth = 0 |
| Long-description lines | vars.max_description_lines = 3 |
| Remap key | keys.set("i", add_sibling) |
| Status bar | bar.set({ fn, fn, ... }) |
Built-in themes: nord, catppuccin_mocha, catppuccin_latte, dracula, gruvbox_dark, solarized_light, tokyo_night. Seventeen named UI colors plus urgency_colors (see config.lua for the full list).
API
faster-dooit exposes a Lua API (a deliberate subset of the original Python surface) for customization:
| API | Purpose |
|---|
keys.set(key|{keys}, action) | Remap keybindings |
formatter.todos..add(fn) | Style todo columns |
bar.set({fn, ...}) | Custom status bar |
dashboard.set({line, ...}) | Welcome dashboard |
theme / vars | Colors, presets, fold depth, max lines |
notify(msg, level) / now(fmt) | Feedback & time |
subscribe(event, fn) / timer(sec, fn) | Events & periodic callbacks |
Directory Structure
faster-dooit/
├── main.go # entry: flags, paths, TUI bootstrap
├── internal/
│ ├── app/ # Bubble Tea model: modes, keys, rendering, scrollbar
│ ├── model/ # in-memory tree: Workspace/Todo, cascade rules
│ ├── store/ # SQLite persistence: load-once, write-through
│ ├── lua/ # sandboxed config.lua evaluation
│ ├── theme/ # resolved theme + 7 built-in presets
│ └── dateparse/ # natural-language dates ("tomorrow", "3d")
├── install.sh / install.ps1 # one-line installers
└── config.lua # default user config
Tech Stack
| Layer | Tech |
|---|
| Language | Go |
| TUI | Bubble Tea, lipgloss |
| Database | SQLite (modernc.org/sqlite, pure Go) |
| Config | gopher-lua (sandboxed) |
| Release | GoReleaser + GitHub Actions |
Contributing
- Fork the repo
- Create a branch (
git checkout -b feat/amazing)
- Commit your changes
- Push and open a Pull Request
go test ./... # unit + parity + e2e
go vet ./...
go test ./internal/app/ -bench . -benchmem # perf gates
License
MIT