Skip to content

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:

  1. Brainstorming & Design -- Explore requirements through Q&A, compare approaches, choose layout with visual companion
  2. Writing Plans -- Break down into 11 tasks with clear verification steps
  3. TDD -- Write tests first for hooks and components
  4. 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:

  1. TodoItem test missing DndContext wrapper -- useSortable requires a DndContext provider, test will fail
  2. 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

FileDescription
src/types/todo.tsInterface Todo, Filters, type aliases, constants (PRIORITIES, CATEGORIES)
src/lib/storage.tsloadTodos(), saveTodos(), loadTheme(), saveTheme() with error handling

Task 3: useTodos Hook (TDD)

FileDescription
Testsrc/hooks/use-todos.test.ts6 test cases: starts empty, add todo, toggle todo, delete todo, edit todo, reorder todos
Codesrc/hooks/use-todos.tsuseReducer + 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

FileDescription
src/lib/filters.tsapplyFilters() -- combined AND filter for status, priority, category, search
src/hooks/use-theme.tsToggle dark/light, sync with localStorage + system preference

Task 5: Header & FilterBar

FileDescription
src/components/header.tsxApp name, stats counter, dark mode toggle (Sun/Moon icon)
src/components/filter-bar.tsxPill buttons for status/priority/category + search input

Task 6: TodoInput (TDD)

FileDescription
Testsrc/components/todo-input.test.tsx3 test cases: render placeholder, call onAdd on submit, clear input after submit
Codesrc/components/todo-input.tsxInput expands into form: title, priority dropdown, category dropdown, date picker

RED -> FAIL -> GREEN -> 3/3 PASS

Task 7: TodoItem (TDD)

FileDescription
Testsrc/components/todo-item.test.tsx3 test cases: render title + priority, toggle checkbox, line-through when completed. Note: Test requires DndContext + SortableContext wrapper
Codesrc/components/todo-item.tsxSortable item with drag handle, checkbox, priority badge, category tag, due date, dropdown menu

RED -> FAIL -> GREEN -> 3/3 PASS

Tasks 8-9: TodoList + EditTodoDialog

FileDescription
src/components/todo-list.tsxDnD container with @dnd-kit/core + @dnd-kit/sortable, empty state
src/components/edit-todo-dialog.tsxshadcn 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.