Skip to main content

Terminal-based task management on Linux: part 1

Setting up a lean, terminal-based task management system on Linux using a combination of powerful tools.

The quest for effective task management

Managing tasks effectively is one of those perpetual challenges we face as developers and technical professionals. While there's no shortage of graphical task management applications, those of us who spend most of our day in the terminal often prefer solutions that don't require reaching for the mouse or switching contexts.

In this series, I'll share my approach to creating a terminal-based task management system on Linux that's both powerful and flexible. This first article focuses on conceptual foundations and planning, while part 2 covers implementation and practical usage.

Core requirements for a terminal task management system

After experimenting with numerous approaches over the years, I've identified several essential requirements for an effective terminal-based task management system:

Content-task integration

The ability to mix content and tasks is tremendously valuable. When working on technical documentation or project planning, we often need to document concepts while simultaneously creating tasks related to that content. Ideally, we'd write content wiki-style, embedding tasks directly where they're conceptually relevant, and be able to mark them complete from either the wiki or a dedicated task manager.

This integration creates a natural flow between thinking, documenting, and task creation.

Context-aware task organisation

Not all tasks are created equal. Through experimentation, I've found it helpful to categorise tasks into distinct contexts:

Work tasks
Deadline-driven professional responsibilities like "prepare client presentation" or "submit quarterly report"
Code tasks
Development-related items like "refactor authentication module" or "fix pagination bug"
Personal tasks
Day-to-day items like "buy groceries" or "schedule dentist appointment"
Optional tasks
Non-urgent "someday" items like "learn Rust" or "explore mechanical keyboard options"

These different categories often benefit from different handling approaches. Time-sensitive work and code tasks typically belong in a primary task management tool, while optional "someday" items might be better suited to a separate list to avoid cluttering your main workflow.

One particularly important distinction is between tasks that should be actively tracked versus those that shouldn't. Some improvement activities—like learning keyboard shortcuts for your editor—don't benefit from formal tracking and can actually create noise that diminishes focus on actionable items.

Code-specific task handling

Development work introduces an additional layer of complexity. We often have code-specific TODO items that logically belong within the codebase itself. These might be embedded as comments in specific files or collected in DEVNOTES.md documents.

Tip

For code-related tasks, consider whether they belong in the code itself (as comments) or in your general task system. A good rule of thumb: if the task requires context from the code to understand, keep it near the code.

Maintaining a consistent workflow between these code-specific tasks and your general task system is crucial for preventing items from falling through the cracks.

Design principles for our system

Based on these requirements, I've established several guiding principles for our terminal-based task management system:

Speed and efficiency

The system must be fast and efficient, with minimal friction for creating, viewing, and completing tasks. Every extra keystroke or second of delay creates resistance that will eventually lead to abandonment.

Accuracy and reliability

Our system should maintain perfect synchronisation across tools, ensuring that tasks aren't duplicated or lost. When a task is marked complete in one interface, that change must propagate immediately to all other views.

Actionability

Task lists should remain focused and actionable, avoiding the accumulation of stale or aspirational items that never get addressed. This means being selective about what enters the system and having regular review processes.

Sustainability

A task system is only valuable if you actually use it consistently. I've built elaborate systems in the past, only to abandon them weeks later due to maintenance overhead. Our approach needs to be sustainable for daily use over the long term.

Simplicity and openness

The solutions should be simple, with data stored in accessible formats that allow for easy export and migration. Proprietary or closed systems create dependency risks that are best avoided.

Selecting our tools

After evaluating numerous options, I've settled on a combination of powerful tools that work well together while meeting our requirements:

Taskwarrior

Taskwarrior serves as the backbone of our system. This mature command-line task manager offers robust filtering, tagging, and prioritisation capabilities. Its data is stored in easily parsed text files, and it provides excellent reporting features.

VimWiki

VimWiki provides our content management component, allowing us to create interconnected markdown files with embedded tasks. As a Vim plugin, it integrates seamlessly with our development workflow.

Gollum

Gollum, a Git-powered wiki system, complements VimWiki by providing a browser-based interface to the same content. This allows for viewing and editing from devices where the terminal isn't ideal.

WikiTask

WikiTask bridges VimWiki and Taskwarrior, synchronising tasks between the two systems. This allows us to create tasks in our wiki content that automatically appear in Taskwarrior.

We'll also explore tools for extracting TODOs from code comments to complete our ecosystem.

Critical considerations

When implementing this system, several factors require careful attention:

Data synchronisation

Ensuring tasks stay in sync across multiple tools can be challenging. Changes made in one interface must reliably propagate to others without conflicts or data loss.

Learning curve

While terminal-based tools offer power and flexibility, they typically come with steeper learning curves than GUI alternatives. Investing time in mastering the core commands and workflows pays significant dividends.

Backup and portability

Task data represents valuable intellectual capital that needs protection. Git integration provides versioning, while regular backups ensure data isn't lost due to system failures.

Next steps

In part 2 of this series, we'll dive into practical implementation, configuring each component of our system and establishing workflows for different task types. We'll cover installation, configuration, and everyday usage patterns that maximise productivity while minimising maintenance overhead.

Note

This approach isn't for everyone. If you're more comfortable with graphical interfaces or don't spend much time in the terminal, excellent GUI alternatives exist. The best system is the one you'll actually use consistently.

For terminal enthusiasts, however, the combination of Taskwarrior, VimWiki, and supporting tools offers a powerful, flexible approach to task management that integrates nicely with development workflows.