Claude Code Tasks: Complete Guide (2026)

Master the new Tasks system that replaced Todos. Learn TaskCreate, TaskUpdate, TaskGet, and TaskList for managing complex projects across sessions and subagents.

Introduction

In January 2026, Anthropic released a fundamental change to how Claude Code manages work: Tasks. Released alongside the Opus 4.5 model, Tasks replace the simpler Todos system with a more powerful primitive designed for longer projects spanning multiple sessions and coordinated subagents.

If you've been using Claude Code for complex projects, you've probably hit the limitations of Todos. They were simple checklists that didn't persist well, couldn't express dependencies, and had no way to coordinate work across multiple Claude instances. Tasks solve all of these problems.

This guide covers everything you need to know about Tasks: what changed, how the four Task tools work, how to build dependency chains, and how to coordinate work across sessions and subagents. By the end, you'll be equipped to manage complex, multi-phase projects with confidence.

What Changed: Tasks vs Todos

Understanding what Tasks replaced helps you appreciate why they matter. Here's how the two systems compare:

The Old Way: Todos

Todos were essentially simple checklists. Claude could create them, mark them done, and that was about it. They lived only in the current session's memory, which meant:

  • Starting a new conversation meant losing your todo list
  • No way to express "Task B depends on Task A"
  • No visibility into what other Claude sessions were working on
  • No structured way to track complex, multi-step projects

The New Way: Tasks

Tasks are a proper data structure with persistence, dependencies, and coordination features:

  • Persistent storage: Tasks are stored in the file system at ~/.claude/tasks, surviving across sessions
  • Dependencies: Tasks can block other tasks, creating execution pipelines
  • Status tracking: Tasks have explicit states (pending, in_progress, completed, blocked)
  • Ownership: Tasks can be claimed by specific sessions or agents
  • Broadcasting: Updates propagate to all sessions watching the same task list
Migration Note: If you have existing workflows using TodoWrite or TodoRead, you'll need to update them. The Todo tools still exist but are deprecated and will be removed in a future release.

The Four Task Tools

Tasks are managed through four dedicated tools. Each has a specific purpose in the task lifecycle.

TaskCreate

Creates a new task with a subject, description, and active form. The active form is particularly important: it describes what "doing" this task looks like, helping Claude understand when to work on it.

TaskCreate Example
TaskCreate:
  subject: "Implement user authentication"
  description: "Add login and signup flows with JWT tokens"
  activeForm: "Building the auth module with login, signup, and token management"

The activeForm field is what Claude shows when actively working on the task. It should be a present-tense description of the work being done.

TaskGet

Retrieves the full details of a specific task by its ID. Use this when you need to see all task metadata including dependencies, blockers, and full description.

TaskGet Example
TaskGet:
  id: "task_abc123"

Returns:
  id: "task_abc123"
  subject: "Implement user authentication"
  description: "Add login and signup flows with JWT tokens"
  status: "in_progress"
  owner: "session_xyz"
  blockedBy: []
  blocks: ["task_def456", "task_ghi789"]

TaskUpdate

Modifies an existing task. You can update status, set the owner, add dependencies, or modify the description. This is how tasks progress through their lifecycle.

TaskUpdate Example
TaskUpdate:
  id: "task_abc123"
  status: "completed"

TaskUpdate:
  id: "task_def456"
  addBlockedBy: ["task_abc123"]
  owner: "session_xyz"

Common status values:

  • pending - Task is waiting to be started
  • in_progress - Task is actively being worked on
  • blocked - Task is waiting on dependencies
  • completed - Task is finished

TaskList

Returns all tasks with summary information. Essential for understanding the current state of a project and finding tasks to work on.

TaskList Output
TaskList returns:
  - id: "task_abc123"
    subject: "Implement user authentication"
    status: "completed"

  - id: "task_def456"
    subject: "Build user profile page"
    status: "in_progress"
    owner: "session_xyz"

  - id: "task_ghi789"
    subject: "Add email notifications"
    status: "blocked"
    blockedBy: ["task_abc123"]

Task Dependencies

Dependencies are what make Tasks powerful for complex projects. They let you express relationships between pieces of work and automatically track what's ready to be done.

Using addBlockedBy and addBlocks

There are two ways to express dependencies:

  • addBlockedBy: "This task cannot start until these other tasks complete"
  • addBlocks: "These other tasks cannot start until this task completes"

Both achieve the same result from different directions. Use whichever makes more sense for your workflow:

Dependency Examples
# When creating the blocked task:
TaskUpdate:
  id: "task_profile_page"
  addBlockedBy: ["task_auth", "task_database_schema"]

# Or when updating the blocking task:
TaskUpdate:
  id: "task_auth"
  addBlocks: ["task_profile_page", "task_settings_page"]

How Downstream Tasks Auto-Unblock

When a task is marked as completed, all tasks that were blocked by it automatically update. If a blocked task has no remaining blockers, its status changes from blocked to pending, signaling it's ready for work.

Auto-Unblock Flow
# Initial state:
task_auth: status=in_progress
task_profile: status=blocked, blockedBy=[task_auth]
task_settings: status=blocked, blockedBy=[task_auth, task_database]

# After completing auth:
TaskUpdate: id="task_auth", status="completed"

# Resulting state:
task_auth: status=completed
task_profile: status=pending, blockedBy=[]  # Auto-unblocked!
task_settings: status=blocked, blockedBy=[task_database]  # Still blocked

Building Pipelines with Dependencies

For complex projects, you can create entire execution pipelines:

Pipeline Example
# Phase 1: Foundation (no dependencies)
task_schema: "Design database schema"
task_auth_design: "Design authentication flow"

# Phase 2: Implementation (depends on Phase 1)
task_database: blockedBy=[task_schema]
task_auth_impl: blockedBy=[task_auth_design]

# Phase 3: Integration (depends on Phase 2)
task_api: blockedBy=[task_database, task_auth_impl]

# Phase 4: Frontend (depends on Phase 3)
task_ui: blockedBy=[task_api]

# Phase 5: Testing (depends on everything)
task_tests: blockedBy=[task_ui]

Cross-Session Collaboration

One of the most powerful features of Tasks is the ability to share them across multiple Claude sessions. This enables parallel development workflows where different terminals work on different parts of a project.

The CLAUDE_CODE_TASK_LIST_ID Environment Variable

By default, each Claude session has its own task list. To share tasks across sessions, set the CLAUDE_CODE_TASK_LIST_ID environment variable to the same value in each terminal:

Terminal
# Terminal 1: Start Claude with a shared task list
CLAUDE_CODE_TASK_LIST_ID=myproject claude

# Terminal 2: Join the same task list
CLAUDE_CODE_TASK_LIST_ID=myproject claude

# Terminal 3: Also joins
CLAUDE_CODE_TASK_LIST_ID=myproject claude

All three terminals now see the same tasks and receive updates when any session modifies them.

Broadcasting Updates to All Sessions

When a session updates a task, the change broadcasts to all other sessions watching that task list. This means:

  • When Terminal 1 marks a task complete, Terminal 2 sees it immediately
  • When Terminal 2 claims a task, Terminal 1 knows not to work on it
  • Blocked tasks auto-unblock for all sessions simultaneously
Coordination Tip: Have sessions claim tasks by setting the owner field before starting work. This prevents two sessions from accidentally working on the same task.

Practical Workflow: Parallel Development

Here's a workflow for a team working on different parts of a feature:

Parallel Development Workflow
# Session 1: Create the task list with dependencies
TaskCreate: subject="Design API endpoints", activeForm="Designing REST API"
TaskCreate: subject="Build backend", blockedBy=[api_design_task]
TaskCreate: subject="Build frontend", blockedBy=[api_design_task]
TaskCreate: subject="Integration tests", blockedBy=[backend_task, frontend_task]

# Session 1: Works on API design
TaskUpdate: id="api_design_task", owner="session_1", status="in_progress"
# ... does the work ...
TaskUpdate: id="api_design_task", status="completed"

# Backend and frontend tasks auto-unblock

# Session 2: Claims backend
TaskUpdate: id="backend_task", owner="session_2", status="in_progress"

# Session 3: Claims frontend (in parallel!)
TaskUpdate: id="frontend_task", owner="session_3", status="in_progress"

# Both complete, integration tests unblock automatically

Using Tasks with Subagents

Tasks become even more powerful when combined with Claude's subagent capabilities. Subagents can claim tasks, report progress, and mark work complete just like top-level sessions.

How Subagents Claim and Update Tasks

When spawning a subagent for specific work, you can pass it a task ID to work on:

Subagent Task Assignment
# Main agent creates tasks
TaskCreate: subject="Build auth service", activeForm="Implementing authentication"
TaskCreate: subject="Build user service", activeForm="Implementing user management"

# Main agent spawns subagents for each task
Spawn subagent:
  task: "Work on task_auth_123. Claim it, implement authentication, mark complete."

Spawn subagent:
  task: "Work on task_user_456. Claim it, implement user service, mark complete."

# Subagents work in parallel, each updating their assigned task

Coordinating Work Across Multiple Agents

The ownership system prevents conflicts when multiple agents are active:

Agent Coordination
# Agent checks for unowned, unblocked tasks
TaskList
# Finds: task_xyz is pending with no owner

# Agent claims it
TaskUpdate: id="task_xyz", owner="agent_abc", status="in_progress"

# Other agents see the task is claimed and skip it
TaskList
# Shows: task_xyz is in_progress, owned by agent_abc

Best Practices for Parallel Execution

  • Always set owner before starting: Prevents duplicate work
  • Use fine-grained tasks: Smaller tasks enable more parallelism
  • Design for independence: Tasks that can run in parallel should have no shared dependencies
  • Check TaskList before claiming: Another agent might have just claimed it
  • Update status immediately: Don't leave tasks in misleading states

Going Further: Specialist Agents

Tasks solve the problem of tracking what needs to be done. But for complex projects, who does the work matters just as much.

Consider a multi-platform project with iOS, web, and backend components. Tasks can track that you need to "build the login screen," but which agent should do it? A generic Claude session might not know your iOS conventions, your CSS patterns, or your Firebase security rules.

The Specialist Agent Pattern

The most effective Claude Code workflows pair Tasks with specialist agents, each pre-configured with domain expertise:

  • Frontend Designer: Knows your design system, CSS patterns, accessibility requirements
  • iOS Developer: Understands SwiftUI, your app architecture, platform conventions
  • Web Developer: Knows your JavaScript patterns, framework quirks, API contracts
  • Firebase Developer: Understands security rules, Cloud Functions, Firestore patterns

Instead of telling a generic Claude session everything it needs to know, you spawn the right specialist for each task. The specialist already has the context baked in.

Ready for Specialist Agents?

Claude Architect provides pre-built specialist agents with deep domain expertise. Stop repeating instructions and start delegating to experts.

Join the Waitlist