[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6686":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":22,"hasPages":24,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":32,"readmeContent":33,"aiSummary":34,"trendingCount":16,"starSnapshotCount":16,"syncStatus":35,"lastSyncTime":36,"discoverSource":37},6686,"swift-composable-architecture","pointfreeco\u002Fswift-composable-architecture","pointfreeco","A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind.","https:\u002F\u002Fwww.pointfree.co\u002Fcollections\u002Fcomposable-architecture",null,"Swift",14709,1665,218,17,0,22,91,6,44.67,"MIT License",false,"main",true,[26,27,28,29,30,31],"architecture","composition","modularity","swiftui","testability","uikit","2026-06-12 02:01:28","# The Composable Architecture\n\n[![CI](https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Factions\u002Fworkflows\u002Fci.yml)\n[![Slack](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fslack-chat-informational.svg?label=Slack&logo=slack)](https:\u002F\u002Fwww.pointfree.co\u002Fslack-invite)\n[![](https:\u002F\u002Fimg.shields.io\u002Fendpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fpointfreeco%2Fswift-composable-architecture%2Fbadge%3Ftype%3Dswift-versions)](https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture)\n[![](https:\u002F\u002Fimg.shields.io\u002Fendpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fpointfreeco%2Fswift-composable-architecture%2Fbadge%3Ftype%3Dplatforms)](https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture)\n\nThe Composable Architecture (TCA, for short) is a library for building applications in a consistent \nand understandable way, with composition, testing, and ergonomics in mind. It can be used in \nSwiftUI, UIKit, and more, and on any Apple platform (iOS, macOS, iPadOS, visionOS, tvOS, and watchOS).\n\n* [What is the Composable Architecture?](#what-is-the-composable-architecture)\n* [Learn more](#learn-more)\n* [Examples](#examples)\n* [Basic usage](#basic-usage)\n* [Documentation](#documentation)\n* [FAQ](#faq)\n* [Community](#community)\n* [Installation](#installation)\n* [Translations](#translations)\n\n## What is the Composable Architecture?\n\nThis library provides a few core tools that can be used to build applications of varying purpose and \ncomplexity. It provides compelling stories that you can follow to solve many problems you encounter \nday-to-day when building applications, such as:\n\n* **State management**\n  \u003Cbr> How to manage the state of your application using simple value types, and share state across \n  many screens so that mutations in one screen can be immediately observed in another screen.\n\n* **Composition**\n  \u003Cbr> How to break down large features into smaller components that can be extracted to their own, \n  isolated modules and be easily glued back together to form the feature.\n\n* **Side effects**\n  \u003Cbr> How to let certain parts of the application talk to the outside world in the most testable \n  and understandable way possible.\n\n* **Testing**\n  \u003Cbr> How to not only test a feature built in the architecture, but also write integration tests \n  for features that have been composed of many parts, and write end-to-end tests to understand how \n  side effects influence your application. This allows you to make strong guarantees that your \n  business logic is running in the way you expect.\n\n* **Ergonomics**\n  \u003Cbr> How to accomplish all of the above in a simple API with as few concepts and moving parts as \n  possible.\n\n## Learn More\n\nThe Composable Architecture was designed over the course of many episodes on \n[Point-Free][pointfreeco], a video series exploring advanced programming topics in the Swift language, \nhosted by [Brandon Williams][mbrandonw] and [Stephen Celis][stephencelis].\n\nYou can watch all of the episodes [here][tca-episode-collection], as well as a dedicated, [multipart\ntour][tca-tour] of the architecture from scratch.\n\n\u003Ca href=\"https:\u002F\u002Fwww.pointfree.co\u002Fcollections\u002Ftours\u002Fcomposable-architecture-1-0\">\n  \u003Cimg alt=\"video poster image\" src=\"https:\u002F\u002Fd3rccdn33rt8ze.cloudfront.net\u002Fepisodes\u002F0243.jpeg\" width=\"600\">\n\u003C\u002Fa>\n\n## Examples\n\n[![Screen shots of example applications](https:\u002F\u002Fd3rccdn33rt8ze.cloudfront.net\u002Fcomposable-architecture\u002Fdemos.png)](.\u002FExamples)\n\nThis repo comes with _lots_ of examples to demonstrate how to solve common and complex problems with \nthe Composable Architecture. Check out [this](.\u002FExamples) directory to see them all, including:\n\n* [Case Studies](.\u002FExamples\u002FCaseStudies)\n  * Getting started\n  * Effects\n  * Navigation\n  * Higher-order reducers\n  * Reusable components\n* [Location manager](https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fcomposable-core-location\u002Ftree\u002Fmain\u002FExamples\u002FLocationManager)\n* [Motion manager](https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fcomposable-core-motion\u002Ftree\u002Fmain\u002FExamples\u002FMotionManager)\n* [Search](.\u002FExamples\u002FSearch)\n* [Speech Recognition](.\u002FExamples\u002FSpeechRecognition)\n* [SyncUps app](.\u002FExamples\u002FSyncUps)\n* [Tic-Tac-Toe](.\u002FExamples\u002FTicTacToe)\n* [Todos](.\u002FExamples\u002FTodos)\n* [Voice memos](.\u002FExamples\u002FVoiceMemos)\n\nLooking for something more substantial? Check out the source code for [isowords][gh-isowords], an \niOS word search game built in SwiftUI and the Composable Architecture.\n\n## Basic Usage\n\n> [!Note] \n> For a step-by-step interactive tutorial, be sure to check out [Meet the Composable\n> Architecture][meet-tca].\n\nTo build a feature using the Composable Architecture you define some types and values that model \nyour domain:\n\n* **State**: A type that describes the data your feature needs to perform its logic and render its \nUI.\n* **Action**: A type that represents all of the actions that can happen in your feature, such as \nuser actions, notifications, event sources and more.\n* **Reducer**: A function that describes how to evolve the current state of the app to the next \nstate given an action. The reducer is also responsible for returning any effects that should be \nrun, such as API requests, which can be done by returning an `Effect` value.\n* **Store**: The runtime that actually drives your feature. You send all user actions to the store \nso that the store can run the reducer and effects, and you can observe state changes in the store \nso that you can update UI.\n\nThe benefits of doing this are that you will instantly unlock testability of your feature, and you \nwill be able to break large, complex features into smaller domains that can be glued together.\n\nAs a basic example, consider a UI that shows a number along with \"+\" and \"−\" buttons that increment \nand decrement the number. To make things interesting, suppose there is also a button that when \ntapped makes an API request to fetch a random fact about that number and displays it in the view.\n\nTo implement this feature we create a new type that will house the domain and behavior of the \nfeature, and it will be annotated with the `@Reducer` macro:\n\n```swift\nimport ComposableArchitecture\n\n@Reducer\nstruct Feature {\n}\n```\n\nIn here we need to define a type for the feature's state, which consists of an integer for the \ncurrent count, as well as an optional string that represents the fact being presented:\n\n```swift\n@Reducer\nstruct Feature {\n  @ObservableState\n  struct State: Equatable {\n    var count = 0\n    var numberFact: String?\n  }\n}\n```\n\n> [!Note] \n> We've applied the `@ObservableState` macro to `State` in order to take advantage of the\n> observation tools in the library.\n\nWe also need to define a type for the feature's actions. There are the obvious actions, such as \ntapping the decrement button, increment button, or fact button. But there are also some slightly \nnon-obvious ones, such as the action that occurs when we receive a response from the fact API \nrequest:\n\n```swift\n@Reducer\nstruct Feature {\n  @ObservableState\n  struct State: Equatable { \u002F* ... *\u002F }\n  enum Action {\n    case decrementButtonTapped\n    case incrementButtonTapped\n    case numberFactButtonTapped\n    case numberFactResponse(String)\n  }\n}\n```\n\nAnd then we implement the `body` property, which is responsible for composing the actual logic and \nbehavior for the feature. In it we can use the `Reduce` reducer to describe how to change the\ncurrent state to the next state, and what effects need to be executed. Some actions don't need to\nexecute effects, and they can return `.none` to represent that:\n\n```swift\n@Reducer\nstruct Feature {\n  @ObservableState\n  struct State: Equatable { \u002F* ... *\u002F }\n  enum Action { \u002F* ... *\u002F }\n\n  var body: some Reducer\u003CState, Action> {\n    Reduce { state, action in\n      switch action {\n      case .decrementButtonTapped:\n        state.count -= 1\n        return .none\n\n      case .incrementButtonTapped:\n        state.count += 1\n        return .none\n\n      case .numberFactButtonTapped:\n        return .run { [count = state.count] send in\n          let (data, _) = try await URLSession.shared.data(\n            from: URL(string: \"http:\u002F\u002Fnumber-trivia.com\u002F\\(count)\u002Ftrivia\")!\n          )\n          await send(\n            .numberFactResponse(String(decoding: data, as: UTF8.self))\n          )\n        }\n\n      case let .numberFactResponse(fact):\n        state.numberFact = fact\n        return .none\n      }\n    }\n  }\n}\n```\n\nAnd then finally we define the view that displays the feature. It holds onto a `StoreOf\u003CFeature>` \nso that it can observe all changes to the state and re-render, and we can send all user actions to \nthe store so that state changes:\n\n```swift\nstruct FeatureView: View {\n  let store: StoreOf\u003CFeature>\n\n  var body: some View {\n    Form {\n      Section {\n        Text(\"\\(store.count)\")\n        Button(\"Decrement\") { store.send(.decrementButtonTapped) }\n        Button(\"Increment\") { store.send(.incrementButtonTapped) }\n      }\n\n      Section {\n        Button(\"Number fact\") { store.send(.numberFactButtonTapped) }\n      }\n      \n      if let fact = store.numberFact {\n        Text(fact)\n      }\n    }\n  }\n}\n```\n\nIt is also straightforward to have a UIKit controller driven off of this store. You can observe\nstate changes in the store in `viewDidLoad`, and then populate the UI components with data from\nthe store. The code is a bit longer than the SwiftUI version, so we have collapsed it here:\n\n\u003Cdetails>\n  \u003Csummary>Click to expand!\u003C\u002Fsummary>\n\n  ```swift\n  class FeatureViewController: UIViewController {\n    let store: StoreOf\u003CFeature>\n\n    init(store: StoreOf\u003CFeature>) {\n      self.store = store\n      super.init(nibName: nil, bundle: nil)\n    }\n\n    required init?(coder: NSCoder) {\n      fatalError(\"init(coder:) has not been implemented\")\n    }\n\n    override func viewDidLoad() {\n      super.viewDidLoad()\n\n      let countLabel = UILabel()\n      let decrementButton = UIButton()\n      let incrementButton = UIButton()\n      let factLabel = UILabel()\n      \n      \u002F\u002F Omitted: Add subviews and set up constraints...\n      \n      observe { [weak self] in\n        guard let self \n        else { return }\n        \n        countLabel.text = \"\\(self.store.count)\"\n        factLabel.text = self.store.numberFact\n      }\n    }\n\n    @objc private func incrementButtonTapped() {\n      self.store.send(.incrementButtonTapped)\n    }\n    @objc private func decrementButtonTapped() {\n      self.store.send(.decrementButtonTapped)\n    }\n    @objc private func factButtonTapped() {\n      self.store.send(.numberFactButtonTapped)\n    }\n  }\n  ```\n\u003C\u002Fdetails>\n\nOnce we are ready to display this view, for example in the app's entry point, we can construct a \nstore. This can be done by specifying the initial state to start the application in, as well as \nthe reducer that will power the application:\n\n```swift\nimport ComposableArchitecture\n\n@main\nstruct MyApp: App {\n  var body: some Scene {\n    WindowGroup {\n      FeatureView(\n        store: Store(initialState: Feature.State()) {\n          Feature()\n        }\n      )\n    }\n  }\n}\n```\n\nAnd that is enough to get something on the screen to play around with. It's definitely a few more \nsteps than if you were to do this in a vanilla SwiftUI way, but there are a few benefits. It gives \nus a consistent manner to apply state mutations, instead of scattering logic in some observable \nobjects and in various action closures of UI components. It also gives us a concise way of \nexpressing side effects. And we can immediately test this logic, including the effects, without \ndoing much additional work.\n\n### Testing\n\n> [!Note] \n> For more in-depth information on testing, see the dedicated [testing][testing-article] article. \n\nTo test use a `TestStore`, which can be created with the same information as the `Store`, but it \ndoes extra work to allow you to assert how your feature evolves as actions are sent:\n\n```swift\n@Test\nfunc basics() async {\n  let store = TestStore(initialState: Feature.State()) {\n    Feature()\n  }\n}\n```\n\nOnce the test store is created we can use it to make an assertion of an entire user flow of steps. \nEach step of the way we need to prove that state changed how we expect. For example, we can \nsimulate the user flow of tapping on the increment and decrement buttons:\n\n```swift\n\u002F\u002F Test that tapping on the increment\u002Fdecrement buttons changes the count\nawait store.send(.incrementButtonTapped) {\n  $0.count = 1\n}\nawait store.send(.decrementButtonTapped) {\n  $0.count = 0\n}\n```\n\nFurther, if a step causes an effect to be executed, which feeds data back into the store, we must \nassert on that. For example, if we simulate the user tapping on the fact button we expect to \nreceive a fact response back with the fact, which then causes the `numberFact` state to be \npopulated:\n\n```swift\nawait store.send(.numberFactButtonTapped)\n\nawait store.receive(\\.numberFactResponse) {\n  $0.numberFact = ???\n}\n```\n\nHowever, how do we know what fact is going to be sent back to us?\n\nCurrently our reducer is using an effect that reaches out into the real world to hit an API server, \nand that means we have no way to control its behavior. We are at the whims of our internet \nconnectivity and the availability of the API server in order to write this test.\n\nIt would be better for this dependency to be passed to the reducer so that we can use a live \ndependency when running the application on a device, but use a mocked dependency for tests. We can \ndo this by adding a property to the `Feature` reducer:\n\n```swift\n@Reducer\nstruct Feature {\n  let numberFact: (Int) async throws -> String\n  \u002F\u002F ...\n}\n```\n\nThen we can use it in the `reduce` implementation:\n\n```swift\ncase .numberFactButtonTapped:\n  return .run { [count = state.count] send in \n    let fact = try await self.numberFact(count)\n    await send(.numberFactResponse(fact))\n  }\n```\n\nAnd in the entry point of the application we can provide a version of the dependency that actually \ninteracts with the real world API server:\n\n```swift\n@main\nstruct MyApp: App {\n  var body: some Scene {\n    WindowGroup {\n      FeatureView(\n        store: Store(initialState: Feature.State()) {\n          Feature(\n            numberFact: { number in\n              let (data, _) = try await URLSession.shared.data(\n                from: URL(string: \"http:\u002F\u002Fnumber-trivia.com\u002F\\(number)\")!\n              )\n              return String(decoding: data, as: UTF8.self)\n            }\n          )\n        }\n      )\n    }\n  }\n}\n```\n\nBut in tests we can use a mock dependency that immediately returns a deterministic, predictable \nfact: \n\n```swift\n@Test\nfunc basics() async {\n  let store = TestStore(initialState: Feature.State()) {\n    Feature(numberFact: { \"\\($0) is a good number Brent\" })\n  }\n}\n```\n\nWith that little bit of upfront work we can finish the test by simulating the user tapping on the \nfact button, and then receiving the response from the dependency to present the fact:\n\n```swift\nawait store.send(.numberFactButtonTapped)\n\nawait store.receive(\\.numberFactResponse) {\n  $0.numberFact = \"0 is a good number Brent\"\n}\n```\n\nWe can also improve the ergonomics of using the `numberFact` dependency in our application. Over \ntime the application may evolve into many features, and some of those features may also want access \nto `numberFact`, and explicitly passing it through all layers can get annoying. There is a process \nyou can follow to “register” dependencies with the library, making them instantly available to any \nlayer in the application.\n\n> [!Note] \n> For more in-depth information on dependency management, see the dedicated\n> [dependencies][dependencies-article] article. \n\nWe can start by wrapping the number fact functionality in a new type:\n\n```swift\nstruct NumberFactClient {\n  var fetch: (Int) async throws -> String\n}\n```\n\nAnd then registering that type with the dependency management system by conforming the client to\nthe `DependencyKey` protocol, which requires you to specify the live value to use when running the\napplication in simulators or devices:\n\n```swift\nextension NumberFactClient: DependencyKey {\n  static let liveValue = Self(\n    fetch: { number in\n      let (data, _) = try await URLSession.shared\n        .data(from: URL(string: \"http:\u002F\u002Fnumber-trivia.com\u002F\\(number)\")!\n      )\n      return String(decoding: data, as: UTF8.self)\n    }\n  )\n}\n\nextension DependencyValues {\n  var numberFact: NumberFactClient {\n    get { self[NumberFactClient.self] }\n    set { self[NumberFactClient.self] = newValue }\n  }\n}\n```\n\nWith that little bit of upfront work done you can instantly start making use of the dependency in \nany feature by using the `@Dependency` property wrapper:\n\n```diff\n @Reducer\n struct Feature {\n-  let numberFact: (Int) async throws -> String\n+  @Dependency(\\.numberFact) var numberFact\n   \n   …\n\n-  try await self.numberFact(count)\n+  try await self.numberFact.fetch(count)\n }\n```\n\nThis code works exactly as it did before, but you no longer have to explicitly pass the dependency \nwhen constructing the feature's reducer. When running the app in previews, the simulator or on a \ndevice, the live dependency will be provided to the reducer, and in tests the test dependency will \nbe provided.\n\nThis means the entry point to the application no longer needs to construct dependencies:\n\n```swift\n@main\nstruct MyApp: App {\n  var body: some Scene {\n    WindowGroup {\n      FeatureView(\n        store: Store(initialState: Feature.State()) {\n          Feature()\n        }\n      )\n    }\n  }\n}\n```\n\nAnd the test store can be constructed without specifying any dependencies, but you can still \noverride any dependency you need to for the purpose of the test:\n\n```swift\nlet store = TestStore(initialState: Feature.State()) {\n  Feature()\n} withDependencies: {\n  $0.numberFact.fetch = { \"\\($0) is a good number Brent\" }\n}\n\n\u002F\u002F ...\n```\n\nThat is the basics of building and testing a feature in the Composable Architecture. There are \n_a lot_ more things to be explored, such as composition, modularity, adaptability, and complex \neffects. The [Examples](.\u002FExamples) directory has a bunch of projects to explore to see more \nadvanced usages.\n\n## Documentation\n\nThe documentation for releases and `main` are available here:\n\n* [`main`](https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture)\n* [1.x.x](https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002F~\u002Fdocumentation\u002Fcomposablearchitecture)\n\nThere are a number of articles in the documentation that you may find helpful as you become more \ncomfortable with the library:\n\n* [Getting started][getting-started-article]\n* [Dependencies][dependencies-article]\n* [Testing][testing-article]\n* [Navigation][navigation-article]\n* [Sharing state][sharing-state-article]\n* [Performance][performance-article]\n* [Concurrency][concurrency-article]\n* [Bindings][bindings-article]\n\n## FAQ\n\nWe have a [dedicated article][faq-article] for all of the most frequently asked questions and\ncomments people have concerning the library.\n\n## Community\n\nIf you want to discuss the Composable Architecture or have a question about how to use it to solve \na particular problem, there are a number of places you can discuss with fellow \n[Point-Free](http:\u002F\u002Fwww.pointfree.co) enthusiasts:\n\n* For long-form discussions, we recommend the [discussions][gh-discussions] tab of this repo.\n* For casual chat, we recommend the [Point-Free Community slack](http:\u002F\u002Fpointfree.co\u002Fslack-invite).\n\n## Installation\n\nYou can add ComposableArchitecture to an Xcode project by adding it as a package dependency.\n\n  1. From the **File** menu, select **Add Package Dependencies...**\n  2. Enter \"https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fswift-composable-architecture\" into the package \n     repository URL text field\n  3. Depending on how your project is structured:\n      - If you have a single application target that needs access to the library, then add \n        **ComposableArchitecture** directly to your application.\n      - If you want to use this library from multiple Xcode targets, or mix Xcode targets and SPM \n        targets, you must create a shared framework that depends on **ComposableArchitecture** and \n        then depend on that framework in all of your targets. For an example of this, check out the \n        [Tic-Tac-Toe](.\u002FExamples\u002FTicTacToe) demo application, which splits lots of features into \n        modules and consumes the static library in this fashion using the **tic-tac-toe** Swift \n        package.\n\n## Companion libraries\n\nThe Composable Architecture is built with extensibility in mind, and there are a number of\ncommunity-supported libraries available to enhance your applications:\n\n* [Composable Architecture Extras](https:\u002F\u002Fgithub.com\u002FRyu0118\u002Fswift-composable-architecture-extras):\n  A companion library to the Composable Architecture.\n* [TCAComposer](https:\u002F\u002Fgithub.com\u002Fmentalflux\u002Ftca-composer): A macro framework for generating\n  boiler-plate code in the Composable Architecture.\n* [TCACoordinators](https:\u002F\u002Fgithub.com\u002Fjohnpatrickmorgan\u002FTCACoordinators): The coordinator pattern\n  in the Composable Architecture.\n\nIf you'd like to contribute a library, please [open a\nPR](https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fedit\u002Fmain\u002FREADME.md) with a link\nto it!\n\n## Translations\n\nThe following translations of this README have been contributed by members of the community:\n\n* [Arabic](https:\u002F\u002Fgist.github.com\u002FNorhanBoghdadi\u002F1b98d55c02b683ddef7e05c2ebcccd47)\n* [French](https:\u002F\u002Fgist.github.com\u002Fnikitamounier\u002F0e93eb832cf389db12f9a69da030a2dc)\n* [Hindi](https:\u002F\u002Fgist.github.com\u002Fakashsoni01\u002Fb358ee0b3b747167964ef6946123c88d)\n* [Indonesian](https:\u002F\u002Fgist.github.com\u002Fwendyliga\u002F792ea9ac5cc887f59de70a9e39cc7343)\n* [Italian](https:\u002F\u002Fgist.github.com\u002FBellaposa\u002F5114e6d4d55fdb1388e8186886d48958)\n* [Japanese](https:\u002F\u002Fgist.github.com\u002FAchoo-kr\u002F2d0712deb77f78b3379551ac7baea3e4)\n* [Korean](https:\u002F\u002Fgist.github.com\u002FAchoo-kr\u002F5d8936d12e71028fcc4a7c5e078ca038)\n* [Polish](https:\u002F\u002Fgist.github.com\u002FMarcelStarczyk\u002F6b6153051f46912a665c32199f0d1d54)\n* [Portuguese](https:\u002F\u002Fgist.github.com\u002FSevioCorrea\u002F2bbf337cd084a58c89f2f7f370626dc8)\n* [Russian](https:\u002F\u002Fgist.github.com\u002FSubvertDev\u002F3317d0c3b35ed601be330d6fc0df5aba)\n* [Simplified Chinese](https:\u002F\u002Fgist.github.com\u002Fsh3l6orrr\u002F10c8f7c634a892a9c37214f3211242ad)\n* [Spanish](https:\u002F\u002Fgist.github.com\u002Fpitt500\u002Ff5e32fccb575ce112ffea2827c7bf942)\n* [Turkish](https:\u002F\u002Fgist.github.com\u002Fgokhanamal\u002F93001244ef0c1cec58abeb1afc0de37c)\n* [Ukrainian](https:\u002F\u002Fgist.github.com\u002Fbarabashd\u002F33b64676195ce41f4bb73c327ea512a8)\n\nIf you'd like to contribute a translation, please [open a\nPR](https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fedit\u002Fmain\u002FREADME.md) with a link \nto a [Gist](https:\u002F\u002Fgist.github.com)!\n\n## Credits and thanks\n\nThe following people gave feedback on the library at its early stages and helped make the library \nwhat it is today:\n\nPaul Colton, Kaan Dedeoglu, Matt Diephouse, Josef Doležal, Eimantas, Matthew Johnson, George \nKaimakas, Nikita Leonov, Christopher Liscio, Jeffrey Macko, Alejandro Martinez, Shai Mishali, Willis \nPlummer, Simon-Pierre Roy, Justin Price, Sven A. Schmidt, Kyle Sherman, Petr Šíma, Jasdev Singh, \nMaxim Smirnov, Ryan Stone, Daniel Hollis Tavares, and all of the [Point-Free][pointfreeco] \nsubscribers 😁.\n\nSpecial thanks to [Chris Liscio](https:\u002F\u002Ftwitter.com\u002Fliscio) who helped us work through many strange \nSwiftUI quirks and helped refine the final API.\n\nAnd thanks to [Shai Mishali](https:\u002F\u002Fgithub.com\u002Ffreak4pc) and the\n[CombineCommunity](https:\u002F\u002Fgithub.com\u002FCombineCommunity\u002FCombineExt\u002F) project, from which we took \ntheir implementation of `Publishers.Create`, which we use in `Effect` to help bridge delegate and \ncallback-based APIs, making it much easier to interface with 3rd party frameworks.\n\n## Other libraries\n\nThe Composable Architecture was built on a foundation of ideas started by other libraries, in \nparticular [Elm](https:\u002F\u002Felm-lang.org) and [Redux](https:\u002F\u002Fredux.js.org\u002F).\n\nThere are also many architecture libraries in the Swift and iOS community. Each one of these has \ntheir own set of priorities and trade-offs that differ from the Composable Architecture.\n\n* [RIBs](https:\u002F\u002Fgithub.com\u002Fuber\u002FRIBs)\n* [Loop](https:\u002F\u002Fgithub.com\u002FReactiveCocoa\u002FLoop)\n* [ReSwift](https:\u002F\u002Fgithub.com\u002FReSwift\u002FReSwift)\n* [Workflow](https:\u002F\u002Fgithub.com\u002Fsquare\u002Fworkflow)\n* [ReactorKit](https:\u002F\u002Fgithub.com\u002FReactorKit\u002FReactorKit)\n* [RxFeedback](https:\u002F\u002Fgithub.com\u002FNoTests\u002FRxFeedback.swift)\n* [Mobius.swift](https:\u002F\u002Fgithub.com\u002Fspotify\u002Fmobius.swift)\n* \u003Cdetails>\n  \u003Csummary>And more\u003C\u002Fsummary>\n\n  * [Fluxor](https:\u002F\u002Fgithub.com\u002FFluxorOrg\u002FFluxor)\n  * [PromisedArchitectureKit](https:\u002F\u002Fgithub.com\u002FRPallas92\u002FPromisedArchitectureKit)\n  \u003C\u002Fdetails>\n\n## License\n\nThis library is released under the MIT license. See [LICENSE](LICENSE) for details.\n\n[pointfreeco]: https:\u002F\u002Fwww.pointfree.co\n[mbrandonw]: https:\u002F\u002Ftwitter.com\u002Fmbrandonw\n[stephencelis]: https:\u002F\u002Ftwitter.com\u002Fstephencelis\n[tca-episode-collection]: https:\u002F\u002Fwww.pointfree.co\u002Fcollections\u002Fcomposable-architecture\n[tca-tour]: https:\u002F\u002Fwww.pointfree.co\u002Fcollections\u002Ftours\u002Fcomposable-architecture-1-0\n[gh-isowords]: https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fisowords\n[gh-discussions]: https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fdiscussions\n[swift-forum]: https:\u002F\u002Fforums.swift.org\u002Fc\u002Frelated-projects\u002Fswift-composable-architecture\n[testing-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Ftestingtca\n[faq-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Ffaq\n[dependencies-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Fdependencymanagement\n[getting-started-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Fgettingstarted\n[navigation-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Fnavigation\n[performance-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Fperformance\n[concurrency-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Fswiftconcurrency\n[bindings-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Fbindings\n[sharing-state-article]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Fdocumentation\u002Fcomposablearchitecture\u002Fsharingstate\n[meet-tca]: https:\u002F\u002Fswiftpackageindex.com\u002Fpointfreeco\u002Fswift-composable-architecture\u002Fmain\u002Ftutorials\u002Fmeetcomposablearchitecture\n","Composable Architecture（TCA）是一个用于构建应用的库，旨在以一致且易于理解的方式进行开发，注重组合性、测试性和用户体验。它提供了状态管理、组件化设计、副作用处理等核心功能，支持通过简单的值类型来管理和共享应用状态，并将复杂特性分解为可独立测试的小模块。此外，TCA还简化了测试流程，使得开发者能够轻松地对业务逻辑进行单元测试和端到端测试。此框架特别适用于需要高度可维护性和可测试性的跨平台Swift应用开发场景，如iOS、macOS、watchOS等苹果生态下的应用程序。",2,"2026-06-11 03:08:18","top_language"]