Skip to content

Todo Workflow

A comprehensive guide to managing todos with zk directly from your editor. Todos are a special type of zettel designed for actionable tasks with status tracking, due dates, priorities, and links to other notes.


Todos in zk are not just checkboxes - they’re full zettels with:

  • Status tracking - Open, in progress, or closed
  • Due dates - Target completion dates
  • Priority levels - High, medium, or low
  • Links - Connections to other zettels, including daily notes
  • Full-text search - Todos are indexed and searchable
  • Rich content - Descriptions, acceptance criteria, notes

Key characteristics:

  • Type: todo - A distinct zettel type for actionable tasks
  • Linkable - Can link to any other zettel (notes, daily notes, other todos)
  • Queryable - Filter by status, priority, due date, project
  • Persistent - Never lost, always searchable, even when closed

FeatureTask Managerszk Todos
Rich descriptionsLimitedFull markdown
Links to knowledgeNoneNative linking
Searchable historyVariesAlways indexed
Context preservationLost on completionPermanent record
IntegrationSeparate appIn your editor
  1. Context lives with the task - Add notes, links, and details directly
  2. Tasks link to knowledge - Connect todos to related notes
  3. History is preserved - Closed todos remain searchable
  4. No context switching - Manage tasks in your editor

zk creates todos with this frontmatter:

---
id: "202602131045"
title: "Fix authentication bug"
type: "todo"
project: "my-project"
category: "untethered"
status: "open"
due: "2026-02-20"
priority: "high"
tags:
- "todo"
- "bug"
created: "2026-02-13T10:45:00Z"
---
# Fix authentication bug
## Description
Users are getting logged out randomly after 10 minutes.
## Acceptance Criteria
- [ ] Identify root cause
- [ ] Write failing test
- [ ] Implement fix
- [ ] Verify in staging
## Notes
Might be related to session timeout configuration.
## Related
- [[202602120930|Session Management Architecture]]
StatusMeaningIcon
openNot started[ ]
in_progressBeing worked on[~]
closedCompleted[x]
PriorityWhen to Use
highUrgent, blocking other work
mediumImportant but not urgent
lowNice to have, do when possible

" Basic todo
:ZkTodo Fix the login bug
" With due date
:ZkTodo Update documentation --due 2026-02-20
" With priority
:ZkTodo Critical security fix --priority high
" With project
:ZkTodo Refactor auth module --project my-project
" Multiple options
:ZkTodo Fix auth --due 2026-02-20 --priority high

Use the \s keymap (buffer-local on todo zettels) to open a status picker:

\s → Pick: open / in_progress / closed

This calls zk set-status under the hood.

" Generate markdown todo list
:ZkTodoList
" Project-specific list
:ZkTodoList my-project
" Due today
:ZkTodoList today
" Due this week
:ZkTodoList week

-- Basic todo
require("zk").todo({ title = "Fix the bug" })
-- With options
require("zk").todo({
title = "Update documentation",
due = "2026-02-20",
priority = "high",
project = "my-project",
})
-- Linked to specific zettels
require("zk").todo({
title = "Follow up",
links = { "202602131045", "202602131100" },
})
-- Set status on current buffer's todo
require("zk").set_status("closed")
require("zk").set_status("in_progress")
require("zk").set_status("open")
-- Set status on a specific file
require("zk").set_status("closed", "./path/to/todo.md")
-- Open todos (picker)
require("zk").todo_picker()
-- Closed todos
require("zk").todo_picker({ closed = true })
-- Filtered
require("zk").todo_picker({
project = "my-project",
priority = "high",
})
-- Due this week
require("zk").todo_picker({ this_week = true })
-- Overdue
require("zk").todo_picker({ overdue = true })
-- Get todos synchronously
local todos = require("zk").todos_sync({ this_week = true })
require("zk").todo_list()
require("zk").todo_list({ project = "my-project" })
require("zk").todo_list({ today = true })

  1. Open today’s daily note:

    :ZkDaily
  2. Review and plan from your daily note — create todos for tasks.

Capture task from idea:

:ZkTodo Investigate the memory leak

Start working on a task: Open the todo, review context, optionally mark as in_progress.

Complete a task: Press \s and select closed from the picker.

  1. Update due dates if needed (edit the frontmatter)

  2. Generate tomorrow’s list:

    :ZkTodoList today

require("zk").todo({
title = "Update auth",
links = { "202602101200", "202602111430" },
})

To see what notes link TO a todo, press \b to toggle the backlinks panel.


-- Todo management
vim.keymap.set("n", "<leader>zt", "<cmd>ZkTodo<cr>", { desc = "New todo" })
-- \s is automatically mapped on todo zettels (status picker)

Todos and daily notes work together naturally:

Daily Note (capture thoughts)
|
Identify actionable item
|
Create todo (:ZkTodo)
|
Todo tracks the task
Morning: Open daily note (:ZkDaily)
|
Check linked todos from yesterday
|
Plan the day
Created (open)
|
Working (in_progress) [optional]
|
Completed (closed)
|
Still searchable (permanent record)

The :ZkTodoList command generates a markdown file you can review or share:

# Todo List
Generated: 2026-02-13 15:30
## High Priority
- [ ] **Fix authentication bug** [[202602131045]]
- Due: 2026-02-15
- Project: my-project
## Medium Priority
- [ ] **Update documentation** [[202602131100]]
- Due: 2026-02-20
## Other
- [ ] **Refactor tests** [[202602131200]]
---
Total: 3 todos

ActionCommand / KeymapDescription
New todo:ZkTodo [title]Create a new todo
Set status\s (buffer-local)Pick open / in_progress / closed
Add tags\a (buffer-local)Prompt for tags and add to frontmatter
Validate frontmatter\v (buffer-local)Validate frontmatter against CUE schema
Generate list:ZkTodoListMarkdown summary of open todos

  1. Set due dates - Helps prioritize and enables filtering
  2. Use priorities sparingly - Reserve “high” for truly urgent items
  3. Don’t delete, close - Closed todos are a record of accomplishment
  4. Add descriptions - Your future self will thank you
  5. Link related notes - Build context around tasks
  6. Review regularly - Use :ZkTodoList to stay on track