The Terminal Todo App: A Journey into Go and Command-Line Productivity
This article is about a terminal-based todo app built in Go that harnesses Cobra for intuitive command-line control and integrates with Apple Reminders to streamline task management.

Why Build a Terminal Todo App?
At the start of 2025, I undertook learning a new programming language. I chose Go—a language known for its simplicity, performance, and excellent tooling—because it offered low-level programming capabilities while providing some safety nets through its garbage collector.
Having learned how to build both simple programs and applications in Go, this choice led to an inevitable question: “What’s next?” Inspired by a brief YouTube video on building a basic todo terminal app, I decided to take the concept further.
Imagine a world where you manage your tasks without ever leaving the terminal. Whether you’re using NeoVim, Obsidian, or even Notion for notes, this terminal-based approach means your todo list is always a command away. Plus, by exposing each todo through piping, you can easily integrate and transform data using other command-line utilities. This flexibility is what makes the app both fun and powerful.
Technology and Design
The App in Go and Its Ecosystem
The app is built in Go—a language I quickly grew to love for its clarity and performance. By leveraging Go, I was able to efficiently implement concurrent operations (especially in the integration with external systems like Apple Reminders) and benefit from a robust standard library.
CLI with Cobra
One of the standout choices was using the Cobra library to handle command-line interactions. Cobra helps organize commands (like add, list, delete, and due) into a neat hierarchy, making it simple to extend the application further. This modular command pattern not only improves maintainability but also makes the tool feel intuitive for the end-user.
Modular Architecture, Connectors, and API’s
The app is designed with a clear separation of concerns:
Command Layer:
Each CLI command (found in the /cmd directory) encapsulates a specific functionality.
Connector Layer:
Interfaces and implementations for data storage (e.g., a JSON file connector) allow for easy swapping of storage mechanisms in the future.
API Integrations:
Interfaces and implementations for external APIs (e.g., Apple Reminders) allow for easy expansion without altering core functionality.
Utility Functions:
Helper functions manage tasks like reading from standard input, parsing dates, and even checking the operating system.
This modular structure reflects best practices in software design, ensuring the code is both scalable and testable.
Integration with External Platforms
A particularly interesting feature is the integration with Apple Reminders. Using Go’s ability to run shell commands (via the exec package), the app can invoke AppleScript commands to add tasks directly to the Apple Reminders app. This allows this program to bridge the gap between traditional terminal usage and modern GUI applications.
Core Features and Functionality
Task Management:
Users can add, list, complete, and delete tasks with simple commands. Each task is stored in a JSON file, ensuring that your todo list is persistent across sessions.
Due Dates:
Set due dates for tasks using a familiar date-time format. The app parses these dates and can display them in both the task list and when pushing tasks to external reminders.
Table View:
For those who prefer a structured overview, the app provides a table view. Using a table-rendering library, tasks are presented with headers like “ID,” “Completed,” “Due At,” and “Created At,” making it easy to scan through your list.
Piping and Flexibility:
One of the most exciting aspects is the ability to pipe input from other commands. This opens up a world of possibilities for chaining commands and integrating with other terminal utilities.
Concurrency:
When adding reminders to Apple Reminders, the app leverages Go’s goroutines to handle multiple tasks concurrently, ensuring a responsive experience even when dealing with several tasks at once.
Behind the Code: Architecture and Complexity
Diving into the code reveals a well-thought-out architecture:
Command Pattern:
The use of Cobra encapsulates each action (like add, delete, or list) as its own command. This approach not only simplifies user interactions but also aligns with the principles of the command design pattern.
Connector Interface:
By defining a Connector interface, the app abstracts the storage mechanism. Currently, it uses a JSON file for persistence, but this design means that future enhancements—like switching to a database—can be implemented with minimal changes to the rest of the code.
Error Handling and Testing:
Comprehensive error handling is evident throughout the code. There are also dedicated test files ensuring that each component—from file reading to task operations—works as expected. This test-driven approach helps maintain code quality and reliability.
Modular Package Organization:
With clear boundaries between command logic, API integrations, and utility functions, the project is organized in a way that makes it both easy to understand and extend.
The Path Ahead
The first iteration of the Terminal Todo App is almost complete, and this is just the beginning.
Future enhancements might include:
Extended Integration:
Building out integrations with other platforms like NeoVim or even web-based tools like Notion.
Enhanced Features:
Improving task categorization, priority settings, or even adding a natural language processing component to parse task descriptions.
User Experience Enhancements:
Further refining the terminal UI to make the tool even more user-friendly and visually appealing.