Use Case: Building an Advanced Todo App From Scratch
A Superpowers beginner can build a complete Todo application -- from brainstorm to working prototype -- in a single work session. This is the ideal introductory use case to experience the entire workflow.
Context
You want to build a Todo application as a prototype/demo -- impressive enough to present, but built using the full Superpowers workflow from start to finish.
Requirements:
- CRUD: Add, edit, delete, mark as complete
- Filter/search by status, priority, category
- Categories (Work / Personal / Study) and priority levels (High / Medium / Low)
- Drag & drop reordering
- Due date for each todo
- Dark mode (toggle + system preference detection)
- Data stored in localStorage (no backend needed)
Tech stack:
- Vite + React 18 + TypeScript
- shadcn/ui + Tailwind CSS
- @dnd-kit (drag & drop)
- date-fns (date handling)
- Vitest + React Testing Library
What You'll Learn
In this tutorial, you'll apply four core Superpowers skills:
- Brainstorming & Design -- Explore requirements through Q&A, compare approaches, choose layout with visual companion
- Writing Plans -- Break down into 11 tasks with clear verification steps
- TDD -- Write tests first for hooks and components
- Debugging & Verification -- Handle real-world compatibility issues and verify everything works
End goal: a fully functional Todo application with 12 passing test cases, a successful production build, built following a disciplined workflow.
Step-by-Step Walkthrough
Step 1: Brainstorm the Todo App Design
You open a chat with AI and say:
"I want to build a simple Todo app using React + TypeScript. Let's brainstorm before writing any code."
AI enters brainstorm mode, activates the visual companion (displaying mockups in the browser), and starts asking questions one at a time:
Question 1: "What's the main purpose of this Todo app?"
- A) Learning project/portfolio
- B) Personal daily-use application
- C) Prototype/demo for presentations
You choose: C) Prototype/demo -- needs to be impressive when presenting.
Question 2: "What features does the app need?"
- A) Basic -- Add, edit, delete, mark as complete
- B) Intermediate -- Like A + filter/search, categories, priority
- C) Advanced -- Like B + drag & drop, due date, dark mode, localStorage persist
You choose: C) Advanced -- full-featured for the demo.
Question 3: "Where should data be stored?"
- A) LocalStorage only
- B) Mock API (json-server or MSW)
- C) Real backend (Firebase/Supabase)
You choose: A) LocalStorage -- simple, no backend needed.
Question 4: "Which UI/styling approach?"
- A) Tailwind CSS
- B) shadcn/ui + Tailwind
- C) CSS Modules / Styled Components
- D) Ant Design / MUI
You choose: B) shadcn/ui + Tailwind -- beautiful components, professional, easy to customize.
Question 5: "Which tooling/build system?"
- A) Vite
- B) Next.js
- C) Create React App
You choose: A) Vite -- fast, lightweight, most popular.
After gathering enough information, AI presents 3 approaches:
## Approach A: Single Page -- All-in-One (Recommended)
The entire app lives on 1 page. Sidebar contains filters/categories, main area contains the todo list.
- Pros: Simple, no routing needed, smooth UX
- Cons: Everything packed into 1 view
## Approach B: Multi-Page with React Router
Split into multiple pages: Dashboard, Todo List, Settings.
- Pros: Clear structure, easy to extend
- Cons: Overkill for a todo app, adds dependency
## Approach C: Kanban Board Style
Todos displayed as columns (To Do / In Progress / Done), drag & drop between columns.
- Pros: Visually impressive for demos
- Cons: Much more complex, harder to filter/sort
You initially chose Kanban (C), but after viewing the mockup on the visual companion, you switched to Approach A: Single Page -- the best balance between features and complexity.
AI continues asking about layout:
- A) Sidebar + Main Content (like Todoist)
- B) Top Filter Bar + Centered List (minimalist)
You choose: B) Top Filter Bar + Centered List -- clean and minimalist.
AI writes a detailed design spec with 3 sections:
DESIGN SPEC: Todo App
=== Section 1: Architecture & Data Model ===
Data Model:
interface Todo {
id: string
title: string
completed: boolean
priority: 'high' | 'medium' | 'low'
category: 'Work' | 'Personal' | 'Study'
dueDate: string | null
order: number
createdAt: string
}
State Management:
- useReducer for todo state (add, edit, delete, toggle, reorder)
- Custom hook useTodos() -- handles logic + localStorage sync
- Custom hook useTheme() -- dark/light mode toggle
Component Structure:
App
|-- Header (title, stats, dark mode toggle)
|-- FilterBar (status pills, priority pills, category pills, search)
|-- TodoInput (add new todo form -- expands on click)
|-- TodoList (DnD container)
| +-- TodoItem[] (checkbox, title, priority badge, category, due date, actions)
+-- EditTodoDialog (shadcn dialog)
=== Section 2: UI Components & Interactions ===
FilterBar:
- Horizontal pill buttons: Status (All|Active|Done) | Priority | Category
- Combined with AND logic (Active + High + Work -> only shows todos matching all)
- Search input on the right
TodoItem:
- Checkbox | Title | Priority badge (colored) | Category tag | Due date | Menu (...)
- Hover -> shows drag handle on the left
- Completed -> faded + strikethrough
- Overdue -> due date shown in red
Drag & Drop:
- @dnd-kit/sortable for drag-and-drop reordering
- When dragging in filtered view, only updates relative order;
items hidden by filters keep their original order
=== Section 3: Dark Mode & Persistence ===
Dark Mode: Tailwind dark: class + system preference as default
localStorage: 300ms debounce on write, fallback to empty array if invalid data
Testing: Vitest + RTL for useTodos hook, TodoInput, TodoItem
AI dispatches a spec reviewer to check spec quality. Reviewer approves with 3 minor recommendations (already incorporated into the spec).
You approve. Moving to the next phase.
Note: The design spec is saved to
docs/superpowers/specs/, and the spec reviewer automatically checks it before moving on to writing the plan. See Brainstorming for more details.
Step 2: Superpowers Writes a Detailed Plan
Based on the design spec, AI breaks the work into 11 tasks (significantly more than for a simple app):
## Plan: Todo App
### Task 1: Project Scaffold
- Vite + React + TS, Tailwind, shadcn/ui, @dnd-kit, date-fns
- Vitest + React Testing Library
- Verification: npm run build succeeds
### Task 2: Types & Storage Utilities
- src/types/todo.ts -- interface Todo, Filters, constants
- src/lib/storage.ts -- localStorage helpers
- Verification: TypeScript compile OK
### Task 3: useTodos Hook (TDD)
- Test first: src/hooks/use-todos.test.ts
- Code: src/hooks/use-todos.ts
- Verification: 6/6 tests pass
### Task 4: Filter Logic & useTheme Hook
- src/lib/filters.ts -- applyFilters() function
- src/hooks/use-theme.ts -- dark mode toggle
### Task 5: Header & FilterBar Components
- src/components/header.tsx
- src/components/filter-bar.tsx
### Task 6: TodoInput Component (TDD)
- Test first: src/components/todo-input.test.tsx
- Code: src/components/todo-input.tsx
- Verification: 3/3 tests pass
### Task 7: TodoItem Component (TDD)
- Test first: src/components/todo-item.test.tsx (with DndContext wrapper)
- Code: src/components/todo-item.tsx
- Verification: 3/3 tests pass
### Task 8: TodoList + Drag & Drop
- src/components/todo-list.tsx
### Task 9: EditTodoDialog
- src/components/edit-todo-dialog.tsx
### Task 10: Assemble App + Toast
- Connect all components in App.tsx
- Verification: npm run build succeeds
### Task 11: Final Polish & All Tests
- Verification: 12/12 tests pass, tsc --noEmit OK, build OK
AI dispatches a plan reviewer to check. The reviewer finds 2 issues:
- TodoItem test missing DndContext wrapper --
useSortablerequires aDndContextprovider, test will fail - Sonner not installed in Task 1 -- will cause errors in Task 10
AI fixes both before starting implementation.
Note: The plan is saved to
docs/superpowers/plans/and automatically reviewed before execution. See Writing Plans for more details.
You confirm: "OK, start implementing."
Step 3: Implement According to Plan (TDD: RED -> GREEN -> REFACTOR)
AI executes each task according to the plan. All tasks with tests follow the TDD cycle.
Task 1: Project Scaffold
Scaffold Vite + React + TS, install all dependencies. Real-world issues encountered:
- Vite 8 not yet compatible with
@tailwindcss/vite-> used--legacy-peer-deps - shadcn/ui init failed due to missing import alias -> configured
@/alias in tsconfig + vite.config - Vite 8 conflict with shadcn -> downgraded to Vite 7
Real-world lesson: Scaffolding doesn't always go smoothly. Compatibility issues between libraries are common. What matters is knowing how to debug and find workarounds.
Task 2: Types & Storage Utilities
| File | Description |
|---|---|
src/types/todo.ts | Interface Todo, Filters, type aliases, constants (PRIORITIES, CATEGORIES) |
src/lib/storage.ts | loadTodos(), saveTodos(), loadTheme(), saveTheme() with error handling |
Task 3: useTodos Hook (TDD)
| File | Description | |
|---|---|---|
| Test | src/hooks/use-todos.test.ts | 6 test cases: starts empty, add todo, toggle todo, delete todo, edit todo, reorder todos |
| Code | src/hooks/use-todos.ts | useReducer + localStorage sync, exposes: addTodo, toggleTodo, deleteTodo, editTodo, reorderTodos |
RED -> npx vitest run -> FAIL (file doesn't exist yet) -> GREEN -> Implement hook -> 6/6 PASS
Task 4: Filter Logic & useTheme
| File | Description |
|---|---|
src/lib/filters.ts | applyFilters() -- combined AND filter for status, priority, category, search |
src/hooks/use-theme.ts | Toggle dark/light, sync with localStorage + system preference |
Task 5: Header & FilterBar
| File | Description |
|---|---|
src/components/header.tsx | App name, stats counter, dark mode toggle (Sun/Moon icon) |
src/components/filter-bar.tsx | Pill buttons for status/priority/category + search input |
Task 6: TodoInput (TDD)
| File | Description | |
|---|---|---|
| Test | src/components/todo-input.test.tsx | 3 test cases: render placeholder, call onAdd on submit, clear input after submit |
| Code | src/components/todo-input.tsx | Input expands into form: title, priority dropdown, category dropdown, date picker |
RED -> FAIL -> GREEN -> 3/3 PASS
Task 7: TodoItem (TDD)
| File | Description | |
|---|---|---|
| Test | src/components/todo-item.test.tsx | 3 test cases: render title + priority, toggle checkbox, line-through when completed. Note: Test requires DndContext + SortableContext wrapper |
| Code | src/components/todo-item.tsx | Sortable item with drag handle, checkbox, priority badge, category tag, due date, dropdown menu |
RED -> FAIL -> GREEN -> 3/3 PASS
Tasks 8-9: TodoList + EditTodoDialog
| File | Description |
|---|---|
src/components/todo-list.tsx | DnD container with @dnd-kit/core + @dnd-kit/sortable, empty state |
src/components/edit-todo-dialog.tsx | shadcn Dialog with edit form: title, priority, category, date picker |
Task 10: Assemble App
Connect everything in App.tsx: useTodos + useTheme + applyFilters + Toaster. Production build succeeds.
Task 11: Final Polish
Running tsc --noEmit passes OK, but npm run build reveals a TypeScript error with the asChild prop -- shadcn v2 uses base-ui instead of radix, requiring a switch to the render prop. After fixing -> build OK, 12/12 tests pass.
TDD workflow per task: AI writes test first -> runs test to confirm FAIL -> implements minimal code -> runs test to confirm PASS -> refactors if needed -> commits. See TDD for more details.
Step 4: Verification -- Full Validation
All 11 tasks are complete. Running final verification.
Run the full test suite
npx vitest run
src/hooks/use-todos.test.ts (6 tests)
useTodos > starts with empty todos
useTodos > adds a todo
useTodos > toggles a todo
useTodos > deletes a todo
useTodos > edits a todo
useTodos > reorders todos
src/components/todo-input.test.tsx (3 tests)
TodoInput > renders placeholder input
TodoInput > calls onAdd with todo data on submit
TodoInput > clears input after submit
src/components/todo-item.test.tsx (3 tests)
TodoItem > renders todo title and priority
TodoItem > calls onToggle when checkbox clicked
TodoItem > shows line-through when completed
Test Files 3 passed (3)
Tests 12 passed (12)
Type check & Build
npx tsc --noEmit # No errors
npm run build # Build successful
Summary
Todo App complete. 12/12 tests pass. Production build OK. No TypeScript errors. 10 clean commits per feature.
Results
After completing the entire workflow, you have:
Complete feature set:
- CRUD todos (add, edit, delete, toggle complete)
- Combined AND filtering by status, priority, category + search
- Drag & drop reordering
- Due dates with overdue warnings (shown in red)
- Dark mode (toggle + system preference detection)
- localStorage persistence (300ms debounce)
- Responsive, minimalist UI with shadcn/ui
- Stats display (total tasks, active, done)
12 test cases passing at 100% covering:
- Custom hook
useTodos: add, toggle, delete, edit, reorder, empty state - Component
TodoInput: render, submit, clear - Component
TodoItem: render, toggle, completed style
File structure:
src/
App.tsx
index.css
test-setup.ts
types/
todo.ts
lib/
storage.ts
filters.ts
utils.ts
hooks/
use-todos.ts
use-todos.test.ts
use-theme.ts
components/
header.tsx
filter-bar.tsx
todo-input.tsx
todo-input.test.tsx
todo-item.tsx
todo-item.test.tsx
todo-list.tsx
edit-todo-dialog.tsx
ui/ (shadcn components)
Real-World Issues Encountered
Unlike idealized tutorials, the actual session encountered many issues that needed handling:
1. Vite 8 not yet compatible with Tailwind plugin
@tailwindcss/vite didn't support Vite 8 yet -> used --legacy-peer-deps to install, then downgraded to Vite 7 when shadcn also conflicted.
2. shadcn/ui init failed due to missing import alias
shadcn requires the @/ import alias -> had to configure baseUrl + paths in tsconfig and resolve.alias in vite.config.
3. shadcn v2 uses base-ui instead of radix
The asChild prop no longer works -> had to switch to the render prop for PopoverTrigger and DropdownMenuTrigger. This error only appeared when running npm run build (vite build has its own type checking), while tsc --noEmit passed OK, and dev mode showed no warnings either.
4. TodoItem test needs DnD wrapper
The useSortable hook requires DndContext + SortableContext providers. Tests will crash without wrapping. The plan reviewer caught this and fixed it before implementation.
Lesson: This is why verification matters. Many errors only surface during production builds or strict type checking, not in dev mode.
Key Takeaways
1. Brainstorming helps you change your mind at the right time
You initially chose Kanban Board, but when viewing the mockup on the visual companion, you realized Single Page was a better fit. Changing during the brainstorm phase costs 0 lines of code. Changing after implementation costs hours of refactoring.
2. Plan reviewer catches bugs before coding
The reviewer found 2 issues in the plan (missing DndContext wrapper in test, missing sonner dependency). Without review, these bugs would have appeared mid-implementation and wasted debugging time.
3. Compatibility issues are normal
3 out of 11 tasks encountered compatibility issues (Vite 8, shadcn alias, asChild prop). These aren't your bugs -- this is the reality of the JavaScript ecosystem. The workflow helps you detect and fix them quickly instead of getting stuck.
4. useReducer + Custom Hook + TDD is a powerful combo
The useTodos hook encapsulates all logic (CRUD, reorder, localStorage sync) and has 6 test cases protecting it. When the UI gets complex (drag & drop, filter, edit dialog), the logic remains stable because it's been tested independently.
5. 11 tasks, but each one is small and clear
"Build an advanced Todo app" sounds daunting. But when broken into 11 tasks, each task only creates 1-2 files and has its own verification. You never have to hold the entire app in your head -- just focus on the current task.
6. This is a stepping stone for real projects
This "advanced" Todo app already includes: custom hooks, drag & drop, dark mode, shadcn/ui, localStorage persistence, TDD, automated review. These are patterns you'll reuse in every React project.
Reality isn't as clean as tutorials. You'll encounter compatibility issues, library changes, and unexpected errors. The Superpowers workflow doesn't eliminate these problems -- it helps you detect them early and handle them systematically instead of floundering without knowing where to start.