Skip to main content

Quick start

This guide will walk you through building a simple counter feature with TCA. You’ll learn how to manage state, handle actions, execute side effects, and write tests.
For a more in-depth, interactive tutorial, check out Meet the Composable Architecture.

What you’ll build

You’ll build a feature that displays a number along with increment and decrement buttons. It will also have a button that fetches a random fact about the current number from an API and displays it.

Step 1: Create the reducer

First, create a new type annotated with the @Reducer macro. This will house the domain and behavior of your feature.

Step 2: Define the state

Inside your reducer, define a State type that describes all the data your feature needs. Apply the @ObservableState macro to take advantage of Swift’s observation tools.
The state contains:
  • count: The current number to display
  • numberFact: An optional string for the fetched fact

Step 3: Define actions

Define an Action enum that represents all the actions that can happen in your feature.
The actions include:
  • User interactions: increment, decrement, and fact button taps
  • System events: receiving the fact response from the API

Step 4: Implement the reducer

Implement the body property to describe how state evolves when actions occur.
Actions that don’t need to execute side effects return .none. The fact button returns a .run effect that performs an asynchronous API request.

Step 5: Build the view

Create a SwiftUI view that holds a StoreOf<Feature> to observe state and send actions.

Step 6: Create the store

At your app’s entry point, construct a store with initial state and the reducer.

Step 7: Test your feature

TCA makes testing straightforward. Use TestStore to assert how your feature evolves over time.
The test above won’t compile yet because we haven’t extracted the number fact dependency. Continue to the next step to fix this.

Step 8: Extract dependencies

To make your feature testable, extract the API dependency so you can control it in tests.
1

Create a dependency client

2

Register with the dependency system

3

Use the dependency in your reducer

Now your test will compile and run! The test dependency is automatically used in tests, while the live dependency runs in the app.

What you learned

In this quick start guide, you:

Defined state

Created a state type with @ObservableState to hold feature data

Handled actions

Defined an action enum for user interactions and system events

Implemented logic

Used the Reduce reducer to evolve state based on actions

Executed effects

Used .run to perform asynchronous API requests

Built the UI

Created views that observe the store and send actions

Wrote tests

Used TestStore to verify feature behavior with mocked dependencies

Next steps

You’ve built your first TCA feature! Here’s what to explore next:

Navigation

Learn how to navigate between features and manage navigation state

Composition

Break down large features into smaller, reusable components

Testing

Deep dive into testing strategies and best practices

Examples

Explore real-world example applications built with TCA