Skip to content
CAI
Software that uses CAICheck a score

xtro/SwiftMVI

69.5

Adequate · 21 September 2026

1.6k

lines of production code

Swift

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

SwiftMVI is a multi-platform framework for building iOS, macOS, tvOS, and watchOS applications using a Model-View-Intent architecture. It provides a modern state management system that replaces immutable patterns with a \Modulable\ protocol and \ReducibleState\ to handle mutable and immutable states. The system integrates with external dependencies like SwiftUseCase and CasePaths to manage features and events within SwiftUI views.

Behavioural changes

Refactored state management to support mutable and immutable states

The framework now distinguishes between mutable and immutable state handling. Immutable state management has been removed, and the system now relies on a new \Modulable\ protocol and \ReducibleState\ for state management. This change introduces new core components like \AnyPath\, \Property\, and \ValueFeature\ to manage state and events, while removing older patterns like \ImmutableReducer\ and \Observer\. Users will now interact with features using the new \Modulable\ protocol and \ReducibleState\ for state updates, enabling more flexible state management in SwiftUI views.

Sources · high confidence

Test coverage

The copyright header in the SwiftMVI test file was updated to reflect the year 2023, indicating a maintenance update to the test suite's metadata.

Tests · high confidence

Dependencies

Add SwiftMVI dependencies and multi-platform support

The SwiftMVI library now depends on the SwiftUseCase and CasePaths packages, integrating their functionality into the core target. Additionally, the package now supports multiple Apple platforms, including macOS, iOS, tvOS, and watchOS.

(dependencies) · medium confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 69 → 70 (+0.4)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 100 (-0.4)
  • Architecture 100 → 100 (+0.0)
  • Maturity 62 → 66 (+4.8)
  • Readiness 57 → 55 (-1.8)
  • Security 92 → 97 (+5.4)

Resolved (10)

  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • No exposed public API
  • Scanner failed to run — not a clean result
  • Test reliability not included
  • The README is a single file with no dedicated Usage or Example section for new users to get started. (README.md)
  • complexity unreadable for .swift — churn × complexity hotspots could not be measured
  • early-stage repository — too little history to judge knowledge freshness
  • git history depth insufficient
  • single-maintainer — knowledge-concentration (bus factor) risk

New (12)

  • API Duplication/Inconsistency in Optional Handling. Property and OptionalProperty are nearly identical, differing only in the generic constraint of Value (non-optional vs optional). This forces users to choose between two types for essentially the same mechanism. In Swift, this is typically handled by a single generic type Property<Value> where Value can be optional. Having two separate types increases API surface and maintenance burden without clear benefit, unless there is a specific performance or semantic reason (e.g., OptionalProperty has different default behavior). The signatures are parallel, suggesting they should be unified.
  • Coverage not measured — Swift suite
  • Dependency hygiene PARTLY measured — SwiftPM pinning read, dependency currency NOT established
  • Dependency not covered by the committed resolution: swift-case-paths
  • Dependency not covered by the committed resolution: swiftusecase
  • Documentation: no usage examples (README.md)
  • Duplicated block (19 lines × 2) (Sources/Core/Property.swift)
  • Duplicated block (6 lines × 2) (Sources/Views/EventReducerView.swift)
  • Medium: security finding (details withheld)
  • Naming inconsistency with Swift standard library conventions. In Swift, KeyPath and CasePath are types, not actions. The methods keyPath and casePath sound like they are converting to those types, but they return Self (AnyPath). This is confusing compared to standard Swift patterns where you might expect init(keyPath:) or a static factory method. However, since they are constructors for AnyPath in the init section, having factory methods with the same name as the input type is a common pattern (e.g., String.init(String)). The real issue is that AnyPath has two distinct constructors (init(KeyPath) and init(CasePath)) but the factory methods keyPath and casePath are instance methods returning Self. This implies AnyPath is immutable or copy-on-write, but the naming keyPath on an instance of AnyPath is semantically ambiguous: does it return a new AnyPath wrapping that keypath, or does it return the underlying keypath? Given the return type Self, it returns a new AnyPath. This is consistent with SwiftUI's Binding or similar wrappers, but slightly non-standard. More critically, there is no init overload for AnyPath that takes a KeyPath or CasePath directly in the init list provided? Wait, yes there is: Constructor: AnyPath.init(KeyPath<Root, Value>). So the factory methods keyPath and casePath are redundant if init exists, OR they are convenience constructors. If they are convenience constructors, they should likely be static or init overloads. Having instance methods that return Self based on input parameters is unusual for value types unless they are mutating or creating new instances. If AnyPath is a value type, anyPath.keyPath(kp) creates a new AnyPath. This is consistent with SwiftUI's View modifiers, but the naming is slightly off. A more significant inconsistency is between Property and OptionalProperty.
  • No dependency advisory monitoring
  • Workflow token permissions not restricted

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

xtro/SwiftMVI was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 9b583728722b703b60f039b81998af04798c224e — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-b84573e22831.