Skip to content

Use Case: Solo Dev Building an Authentication Feature

A solo developer can build a complete, secure authentication feature with full test coverage -- simply by following the Superpowers workflow.


Context

You're a solo developer working on a Todo App project. The project already has full CRUD todos, filters, drag-and-drop, dark/light theme -- but no authentication system whatsoever. Anyone who opens the app sees all todos. The new requirement is:

  • Add user registration (register)
  • Add login with email + password
  • Protect app access (login gate) -- can't access the app without logging in
  • Write tests for the entire feature

The project has no auth system. Nobody reviews your code. You work alone from start to finish.

Tech stack:

  • React 19 + TypeScript + Vite
  • Tailwind CSS + shadcn/ui
  • localStorage (no backend)
  • Vitest + Testing Library (testing)
  • Web Crypto API (SHA-256 password hashing)

What You'll Learn

In this tutorial, you'll apply five core Superpowers skills:

  1. Brainstorming & Design -- Design before you code
  2. Writing Plans -- Break work into clear, well-defined tasks
  3. TDD -- Write tests first, implement after
  4. Execution & Subagents -- Dispatch agents in parallel to speed things up
  5. Debugging & Verification -- Verify results with real-world evidence

End goal: you'll have a complete authentication system with all 39 test cases passing, built entirely following a disciplined workflow.


Step-by-Step Walkthrough

Step 1: Brainstorm the Auth Design

Before writing any code, you start with brainstorming. You invoke the brainstorming skill:

/superpowers:brainstorming "I need to add authentication to my Todo project. Let's brainstorm before writing code."

AI explores the codebase first, understands the current tech stack (React 19, TypeScript, Vite, Tailwind, shadcn/ui, localStorage), then starts asking questions one at a time:

Question 1: "What's the purpose of adding authentication?"

  • A) Just to protect app access (login gate) -- data stays in localStorage, each user on the same browser sees the same data
  • B) Each user has their own data -- needs a backend/database to store todos per user
  • C) Simply demo the login/register flow for learning purposes

You choose: A) Login gate -- just protect access, data stays in localStorage.

Question 2: "Which login method do you want?"

  • A) Email + Password (build login/register forms yourself)
  • B) Social login (Google, GitHub...) -- use Firebase Auth, Supabase Auth, Auth0
  • C) Both

You choose: A) Email + Password -- self-built, no external dependencies.

Question 3: "Do you need Registration (creating new accounts)?"

  • A) Need both Register + Login -- user creates new account, saved to localStorage
  • B) Login only -- use mock/hardcoded accounts

You choose: A) Need both Register + Login.

Question 4: "Do you need a Forgot Password feature?"

  • A) Yes -- show a reset password form (mock)
  • B) No -- keep it simple

You choose: B) No -- keep it simple with just Login + Register.

Question 5: "For the UI, how should the Login/Register page look?"

  • A) Separate page (full page) -- redirect to login page if not authenticated
  • B) Modal/Dialog -- show overlay on the current app
  • C) Let me suggest

You choose: A) Separate page.

After gathering enough information, AI presents 3 approaches:

## Approach A: React Context + localStorage (Recommended)
- Create AuthContext to manage login state
- Users stored in localStorage (email + hashed password using Web Crypto API)
- Protected route via a simple wrapper component
- Login/Register are full-page, only render App when authenticated
- Pros: Simple, no added dependencies, fits current architecture
- Cons: No real routing (just conditional render)

## Approach B: React Router + Context
- Add react-router-dom for real routing (/login, /register, /)
- Pros: URL-based navigation, easy to add more pages later
- Cons: Adds new dependency, more complex for a simple app

## Approach C: TanStack Router + Context
- Type-safe routing for React
- Pros: Type-safe, modern
- Cons: Overkill for current scope

## Recommendation
Approach A. The current project is a single-page app with no routing.
Adding a router just for 2 pages (login + app) is overkill.
Conditional render with AuthContext is sufficient and keeps the project simple.

You agree with Approach A. AI continues presenting the detailed design for each part:

Part 1 -- Architecture & Data Model:

User type:
  - id: string (crypto.randomUUID)
  - email: string
  - passwordHash: string (SHA-256 via Web Crypto API)
  - createdAt: string

AuthContext provides:
  - user: User | null
  - isAuthenticated: boolean
  - isLoading: boolean
  - login(email, password) -> success/error
  - register(email, password) -> success/error
  - logout()

localStorage keys:
  - todo-app-users -- array of registered users
  - todo-app-session -- user ID of current session
  - todo-app-todos -- unchanged (shared across all users)

Part 2 -- Component Structure:

<StrictMode>
  <AuthProvider>
    <App>
      |-- isLoading = true -> Loading indicator
      |
      |-- isAuthenticated = false -> <AuthPage>
      |     |-- <LoginForm />
      |     +-- <RegisterForm />
      |
      +-- isAuthenticated = true -> <TodoApp>
            |-- <Header> (+ logout button, user email)
            |-- <FilterBar>
            |-- <TodoInput>
            |-- <TodoList>
            +-- <EditTodoDialog>
    </App>
  </AuthProvider>
</StrictMode>

Part 3 -- UI Design: AI shows 2 mockups directly in the browser via the visual companion: Centered Card vs Split Layout. You choose Split Layout -- screen split in half, left side branding + right side form.

Part 4 -- Validation & Error Handling:

  • Register: email format, duplicate email, password 6-128 characters, confirm password match
  • Login: email/password not empty, show toast error on failure (using existing Sonner)
  • Session: check on app mount, auto-logout if user ID is invalid

Part 5 -- Testing Strategy: Vitest + Testing Library, mock localStorage for storage tests.

AI writes the design spec to docs/superpowers/specs/2026-03-18-authentication-design.md and runs 3 rounds of automatic spec review -- finding 7 issues (missing loading state, missing password max length, missing stale session handling...) and fixing all of them before moving to plan writing.

Note: Automatic spec review is a critical part of the workflow. AI dispatches a code-reviewer agent to review the spec before you approve. This ensures the spec has no gaps. See Brainstorming for details.


Step 2: Superpowers Writes a Detailed Plan

Based on the approved design spec, AI invokes the writing-plans skill and breaks the work into 8 tasks:

## Plan: Authentication Implementation

### Task 1: Hash Utility
- File: src/lib/hash.ts, src/lib/hash.test.ts
- SHA-256 hashing using Web Crypto API
- Verification: npx vitest run src/lib/hash.test.ts

### Task 2: Auth Storage
- File: src/lib/auth-storage.ts, src/lib/auth-storage.test.ts
- CRUD users + session management in localStorage
- Verification: npx vitest run src/lib/auth-storage.test.ts

### Task 3: Auth Context
- File: src/contexts/auth-context.tsx, src/contexts/auth-context.test.tsx
- AuthProvider + useAuth hook
- Login, register, logout, session restore, isLoading, stale session
- Verification: npx vitest run src/contexts/auth-context.test.tsx

### Task 4: Login Form
- File: src/components/login-form.tsx, src/components/login-form.test.tsx
- Form validation, submit, error display
- Verification: npx vitest run src/components/login-form.test.tsx

### Task 5: Register Form
- File: src/components/register-form.tsx, src/components/register-form.test.tsx
- Validation, duplicate email, password too long, submit
- Verification: npx vitest run src/components/register-form.test.tsx

### Task 6: Auth Page
- File: src/components/auth-page.tsx
- Split layout container, switch between login/register
- No separate test needed (covered by form tests + auth-context tests)

### Task 7: Wire Up
- Modify: src/main.tsx, src/App.tsx, src/components/header.tsx
- Wrap App in AuthProvider, conditional render, logout button
- Verification: npx tsc --noEmit && npx vitest run

### Task 8: Smoke Test
- Run full test suite + TypeScript check
- Verification: npx tsc --noEmit && npx vitest run

Each task has specific files, specific verification commands, and detailed test code already in the plan.

The plan also goes through 2 rounds of automatic review -- finding issues (missing crypto.subtle polyfill for test environment, missing stale session test case, missing password > 128 chars test...) and fixing all of them.

Note: The actual plan contains complete code for each test file and implementation file, with - [ ] checkbox format for each step. See Writing Plans for the standard format details.

AI asks you:

"The plan is complete with 8 tasks. Do you want to execute with Subagent-Driven (parallel) or Inline Execution (sequential)?"

You choose: Subagent-Driven -- dispatch multiple agents in parallel for speed.


Step 3: Implement with Subagent-Driven Development

AI uses the subagent-driven-development skill to execute the plan. Instead of working through each task sequentially, AI analyzes dependencies between tasks and dispatches them in parallel when possible.

Batch 1: Task 1 + Task 2 (Parallel)

Task 1 (Hash Utility) and Task 2 (Auth Storage) don't depend on each other, so they're dispatched in parallel to 2 separate agents:

AgentTaskTest CasesResult
Agent 1Hash Utility (hash.ts + hash.test.ts)3 tests: hash consistency, different inputs -> different hashes, returns hex string3/3 PASS
Agent 2Auth Storage (auth-storage.ts + auth-storage.test.ts)6 tests: get/save users, add user, find by email, session CRUD, user validation6/6 PASS

Both agents complete, AI verifies tests and commits:

git commit -m "feat: add SHA-256 password hashing utility"
git commit -m "feat: add auth storage with user and session management"

Batch 2: Task 3 + Task 4/5 (Parallel)

Task 3 (Auth Context) needs Tasks 1+2, but Task 4 (Login Form) and Task 5 (Register Form) only need the props interface, so they can run in parallel:

AgentTaskTest CasesResult
Agent 3Auth Context (auth-context.tsx + test)6 tests: initial state, register + auto-login, login after register, session restore, logout, stale session cleanup6/6 PASS
Agent 4Login + Register Forms12 tests: validation, submit, error display, duplicate email, password too long12/12 PASS

Commit after verification:

git commit -m "feat: add AuthContext with login, register, session management"
git commit -m "feat: add login and register form components"

Batch 3: Task 6 + Task 7 (Sequential, inline)

Task 6 (Auth Page) and Task 7 (Wire Up) are small and depend on each other, so AI implements them directly:

  • Create auth-page.tsx -- split layout container
  • Modify main.tsx -- wrap App in <AuthProvider>
  • Modify App.tsx -- conditional render AuthPage / TodoApp + loading state
  • Modify header.tsx -- add user email + logout button
git commit -m "feat: add AuthPage with split layout"
git commit -m "feat: wire up authentication -- AuthProvider, conditional render, header logout"

TDD workflow per task: Each agent follows the cycle: write test first (RED) -> implement minimal code (GREEN) -> verify tests PASS -> commit. See TDD for details.


Step 4: Verification -- Full Validation

All 8 tasks in the plan are complete. Now Task 8: Smoke Test -- run full verification.

TypeScript Check

npx tsc --noEmit
# (No output) -- Clean, no errors

Full Test Suite

npx vitest run
 src/lib/hash.test.ts (3 tests)
 src/lib/auth-storage.test.ts (6 tests)
 src/contexts/auth-context.test.tsx (6 tests)
 src/components/login-form.test.tsx (5 tests)
 src/components/register-form.test.tsx (7 tests)
  ... (and other existing project test files)

Test Files  8 passed
Tests       39 passed

Git Log -- 7 clean commits

6b92624 feat: wire up authentication -- AuthProvider, conditional render, header logout
37d68f1 feat: add AuthPage with split layout
...     feat: add login and register form components
...     feat: add AuthContext with login, register, session management
...     feat: add auth storage with user and session management
878af65 feat: add SHA-256 password hashing utility
cc6e2f9 initial: todo app before authentication

39/39 tests PASS. TypeScript clean. 7 commits. This is a valid declaration because it's backed by real evidence.


Results

After completing the entire workflow, you have:

Complete Authentication feature:

  • Login page -- sign in with email + password
  • Register page -- create new account with full validation
  • Login gate -- can't access the app without logging in
  • Logout -- logout button on header, displays user email
  • Session persistence -- page reload maintains login state

39 test cases passing at 100% covering:

  • Utility layer: hash function, localStorage CRUD
  • Context layer: login/register flow, session restore, stale session cleanup
  • UI layer: form validation, error display, submit handling
  • Edge cases: duplicate email, password too long (>128 characters), invalid session

New file structure:

src/
  contexts/
    auth-context.tsx          <- AuthProvider + useAuth hook
  components/
    auth-page.tsx             <- Split layout container
    login-form.tsx            <- Login form
    register-form.tsx         <- Registration form
  lib/
    hash.ts                   <- SHA-256 helper
    auth-storage.ts           <- CRUD users + session in localStorage

Modified files:
  src/main.tsx                <- Wrap App in AuthProvider
  src/App.tsx                 <- Conditional render auth/todo + loading state
  src/components/header.tsx   <- Add email + logout button

Key Takeaways

1. Solo devs still need a process

When nobody reviews your code, the Superpowers workflow acts as a "virtual colleague." Brainstorming forces you to think carefully before coding. TDD forces you to write tests before implementing. Verification forces you to prove everything works before declaring done.

Without a process, solo devs easily fall into the trap: writing code on impulse, no tests, declaring "done" without verification.

2. Brainstorming first prevents over-engineering

During brainstorming, AI suggested both React Router and TanStack Router. But because you clarified requirements upfront (login gate, single-page app, no backend), you chose the simplest approach: React Context + localStorage + conditional render.

Without brainstorming, many developers would automatically add a router, backend, database "just in case." The result is spending 3x the time on a feature that doesn't need it yet.

3. Automatic spec review catches blind spots

The 3-round spec review found 7 issues you might have missed: missing loading state (AuthPage flash on reload), missing password max length (DoS risk), missing stale session handling... These gaps were fixed before writing a single line of code.

4. Subagent-Driven Development significantly speeds things up

Instead of implementing 8 tasks sequentially, AI dispatched them in parallel: Tasks 1+2 simultaneously, Task 3 + Tasks 4/5 simultaneously. Total implementation time was significantly reduced through parallelism.

5. A detailed plan keeps you from losing direction

With 8 clear tasks, each with code already in the plan, you always know what's next. There's never a moment where you have to sit and think "what do I do now."

For solo devs, this is especially important. When working alone, it's easy to get distracted or jump between different parts of the project.

6. 39 test cases are your automatic "reviewer"

Each test case is a clear assertion. When you change code -- refactor, add features, fix bugs -- you know immediately if something breaks. 39 tests run in seconds. Faster than any manual testing approach.

7. The verification gate ensures you don't declare "done" prematurely

How many times have you said "done" without running tests? How many times has AI said "implementation complete" without showing output?

The final smoke test -- TypeScript clean + 39/39 tests pass -- completely eliminates the possibility of a false declaration. You can only say "done" when you have real evidence in the terminal.


Being a solo dev doesn't mean working without discipline. Superpowers gives you a process that even large teams must respect: brainstorm before coding, plan before building, test before implementing, auto-review before approving, and verify before declaring. One person with a good process will always outperform one person without a process -- regardless of experience.