agentsclimarketplace

Tca developer

Skill ninjaproger/skills/skills/tca-developer

Develop new features in a modular iOS app using The Composable Architecture (TCA) and Swift Package Manager. Use when implementing a new screen, adding a sub-feature, extending an existing reducer, adding SwiftUI previews, or writing TCA tests. Covers the full development workflow: reading the existing codebase, creating reducer + view files, wiring navigation, writing SwiftUI previews for all meaningful states (loaded, empty, error, and feature-specific variants), and writing TestStore tests. Always explore the target module before writing code to match its existing style and conventions.From its SKILL.md

Install
npx -y skills add ninjaproger/skills --skill tca-developer

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

4.8 KB, ~1.0k tokens by cl100k_base, as published. Nobody here has run it

TCA Feature Development

Workflow

  1. Explore first — read the target module and its neighbours before writing anything
  2. Create the reducer — see references/feature-template.md
  3. Create the view — see references/view-patterns.md
  4. Add previews — one per meaningful state; see Preview Rules below
  5. Write tests — see references/testing-patterns.md
  6. Register — add target to Package.swift; wire into parent if it's a new tab

Explore Before Writing

Before implementing any feature, read:

  • An existing feature's reducer + view (understand current patterns)
  • The parent module (understand how this feature is composed in)
  • Sources/Services/ for available dependency clients
  • Sources/Models/ for the relevant data types

Reducer Checklist

  • @Reducer macro on a struct
  • @ObservableState on State, which conforms to Equatable
  • public init() {} when all state fields have defaults; explicit memberwise init otherwise
  • Idempotency guard in .onAppear: guard state.data == nil else { return .none }
  • @Reducer enum Destination when the feature navigates to children (@Presents + ifLet)
  • delegate(Delegate) action + @CasePathable enum Delegate for upward communication
  • case .delegate: return .none — the reducer always ignores its own delegate cases
  • Capture dependencies explicitly in .run: [client = someClient]
  • Errors stored as String? via error.localizedDescription, not as Error type

View Checklist

  • @Bindable var store: StoreOf<FeatureReducer> — always @Bindable
  • public init(store:) — always explicit public init
  • store.send(.onAppear) in .onAppear modifier
  • Use Group { } for multi-branch body (loading / error / empty / content)
  • Use ContentUnavailableView for error and empty states
  • Wire navigation destinations with $store.scope(state:action:)
  • Toggle bindings: Binding(get: { store.flag }, set: { _ in store.send(.toggleFlag) })
  • Break complex body into @ViewBuilder private var computed properties

Preview Rules

Every view must have at minimum 4 previews: loading (live reducer, fires .onAppear), content (pre-built state with sample data), empty, and any feature-specific variants (error, completed, failed, etc.).

  • Wrap in NavigationStack { } when the view uses .navigationTitle or .navigationDestination
  • Name format: "FeatureName - StateName" e.g. "Quiz - Partially Answered"
  • Do not use withDependencies in previews — use the live reducer directly
  • Add static var sample: Self / static var samples: [Self] on model types for preview data

See references/feature-template.md for complete #Preview block templates (Patterns A–D).

Key Decisions

QuestionAnswer
Reducer + View in one file?Yes, when combined ≤ ~200 lines
Where do computed properties go?On State, not the view
How to pass data to a child feature?Initialize child's State when setting destination
How to communicate upward?.delegate(Delegate) action
Where does error text live?state.loadError: String? via error.localizedDescription
How to cancel in-flight effects?.cancellable(id:, cancelInFlight: true)
Where do sub-view components live?File-private structs in the same .swift file
Should I use UIViewRepresentable?Only when SwiftUI has no equivalent (e.g. MKMapView, WKWebView). Never for styling convenience.
Which concurrency primitive?async/await + AsyncStream first; Combine only if the API has no async alternative; GCD/NSLock only for legacy C/ObjC callbacks

Reference Files

  • references/feature-template.md — Complete file templates: reducer, view with previews, tests, Package.swift snippet, AppCore wiring. Read when starting a new feature from scratch.
  • references/view-patterns.md — View sub-patterns: loading/error/empty states, navigation wiring, Toggle binding, private sub-views, file-local components, animation. Read when implementing or refining a view.
  • references/testing-patterns.md — TestStore setup, dependency mocking, async flow testing, delegate testing, computed property tests, idempotency tests. Read when writing or debugging tests.

What ships with it: 3 files

34.4 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.