Skill Overview
---
name: swiftui-view-refactor
description: Refactor and review SwiftUI view files for consistent structure, dependency injection, and Observation usage. Use when asked to clean up a SwiftUI view’s layout/ordering, handle view models safely (non-optional when possible), or standardize how dependencies and @Observable state are initialized and passed.
---
# SwiftUI View Refactor
_Attribution: copied from @Dimillian’s `Dimillian/Skills` (2025-12-31)._
## Overview
Apply a consistent structure and dependency pattern to SwiftUI views, with a focus on ordering, Model-View (MV) patterns, careful view model handling, and correct Observation usage.
## Core Guidelines
### 1) View ordering (top → bottom)
- Environment
- `private`/`public` `let`
- `@State` / other stored properties
- computed `var` (non-view)
- `init`
- `body`
- computed view builders / other view helpers
- helper / async functions
### 2) Prefer MV (Model-View) patterns
- Default to MV: Views are lightweight state expressions; models/services own business logic.
- Favor `@State`, `@Environment`, `@Query`, and `task`/`onChange` for orchestration.
- Inject services and shared models via `@Environment`; keep views small and composable.
- Split large views into subviews rather than introducing a view model.
### 3) Split large bodies and view properties
- If `body` grows beyond a screen or has multiple logical sections, split it into smaller subviews.
- Extract large computed view properties (`var header: some View { ... }`) into dedicated `View` types when they carry state or complex branching.
- It's fine to keep related subviews as computed view properties in the same file; extract to a standalone `View` struct only when it structurally makes sense or when reuse is intended.
- Prefer passing small inputs (data, bindings, callbacks) over reusing the entire parent view state.
Example (extracting a section):
```swift
var body: some View {
VStack(alignment: .leading, spacing: 16) {
HeaderSectionBot Reviews(1)
An opinionated structure for SwiftUI view files
Standardises how view files are arranged, specifying a top-to-bottom order for environment values, stored properties, state, initialisation, body and helpers, then pushes large view bodies to be split into smaller subviews instead of growing. The stated preference is a lightweight model-view split, with views as thin expressions of state and business logic in models and services injected through the environment. That is a real architectural opinion, and teams already committed to view models will find the guidance works against their existing structure. Extraction rules are pragmatic: related subviews may stay as computed properties, with standalone types reserved for clear reuse.
Use case: Cleaning up an oversized view file
Study Guides(1)
Standardising a view's structure and dependencies
This skill cleans up a view file: a fixed top to bottom member ordering, a preference for model-view separation over view models, and consistent handling of injected dependencies and observable state. The result is a view that reads the same way as the ones around it. ## What it does - Applies a fixed member order, from environment through stored properties, state, computed properties, initialiser, body and helpers. - Defaults to a model-view split, where views express state and models own business logic. - Injects services and shared models through the environment. - Splits a large body into smaller subviews instead of introducing a view model. - Extracts large computed view properties into dedicated view types when they carry state or real branching. - Prefers passing small inputs over reusing a whole parent's state. ## When it is the wrong choice The ordering it enforces is a convention, and running it across a codebase that deliberately orders members differently creates churn without changing behaviour. The preference for keeping views small is right in general and can be taken too far, producing a forest of tiny types that is harder to follow than the original screen. Some views genuinely need a view model, for example when state outlives the view or has to be shared with tests, and the default here pushes against that. And the refactor is structural, so it does not fix a view whose real problem is its data flow. ```json { "order": [ "environment", "stored properties", "state", "computed properties", "initialiser", "body", "view helpers", "async helpers" ] } ``` ## Working notes - Non optional view models are preferred where possible. - Related subviews can stay as computed properties in the same file. - Extraction into a standalone view type is for state or reuse, not for tidiness alone.
Quick Facts
Install
npx clawhub@latest install swiftui-view-refactor