swiftui-view-refactor
Skill430 starsChanged 6 months agoMITView on GitHub
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.
17 other projects use a version of this, 16 of them edited.
Adopted by
Most recently taken up by
- MMACABRE/SKILLSedited, first seen Nov 8, 2026
- tornikegomareli/Skillsedited, first seen Nov 8, 2026
- VelimirMueller/claude-skillsedited, first seen Nov 1, 2026
- VelimirMueller/ai-development-skillsedited, first seen Nov 1, 2026
- steipete/agent-scriptsedited, first seen Oct 20, 2026
- spokvulcan/claude-code-build-ios-appsedited, first seen Oct 17, 2026
Used with
Projects with it also use swiftui-pro.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
kingsidharthSkillswiftui-pro
Comprehensively reviews SwiftUI code for best practices on modern APIs, maintainability, and performance. Use when reading, writing, or reviewing SwiftUI projects.
Also in 3 projects that use this
Other versions17 projects use a version of this.
Word for word · 1
- eugenepyvovarov/mcpbundler-agent-skills-marketplace★ 12100% same
Edited · 16
- openai/plugins★ 7.8k25% same
- steipete/agent-scripts★ 7.4k92% same
- Dimillian/Skills★ 4k26% same
- omarshahine/HomeClaw★ 19125% same
- robinebers/skills★ 4825% same
- fiveonecode/agent-skills★ 2025% same
- VelimirMueller/ai-development-skills★ 726% same
- VelimirMueller/claude-skills★ 726% same
- Adhamxon/claude-code-skills★ 226% same
- ParkerRex/Skills★ 297% same
6 more not listed
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository18 other files it gives its agents.
- AGENTS.mdAGENTS.md
- macos/AGENTS.mdAGENTS.md
- sandbox-vm/AGENTS.mdAGENTS.md
- web/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- macos/CLAUDE.mdCLAUDE.md
- sandbox-vm/CLAUDE.mdCLAUDE.md
- app-store-changelogSkill
- bridge-agent-log-analyzerSkill
- gh-issue-fix-flowSkill
- githubSkill
- react-component-performanceSkill
- swift-concurrency-expertSkill
- swift-concurrencySkill
- swift-testing-expertSkill
- swiftui-expert-skillSkill
- swiftui-performance-auditSkill
- swiftui-ui-patternsSkill
The file
We split this skill into the rules it gives an agent
12 rules. 3 are common, 3 are distinctive, and 6 are very specific to this project.
3
Common
Most of the 16 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 24
Default to MV: Views are lightweight state expressions.
- Very specific: line 30
If body grows beyond a screen or has multiple logical sections, split it into smaller subviews.
- Distinctive: line 33
Prefer passing small inputs (data, bindings, callbacks) over reusing the entire parent view state.
- Very specific: line 101
Avoid patterns where a computed view (or body) returns completely different root branches using if/else.
- Very specific: line 102
Prefer a single stable base view, and place conditions inside sections/modifiers (overlay, opacity, disabled, toolbar, row content, etc.).
- Common: line 133
Do not introduce a view model unless the request or existing code clearly calls for one.
- Common: line 134
If a view model exists, make it non-optional when possible.
- Very specific: line 156
Ensure stable view structure: avoid top-level if-based branch swapping.
- Very specific: line 157
If a view model exists, replace optional view models with a non-optional @State view model initialized in init by passing dependencies from …
- Common: line 159
Keep behavior intact: do not change layout or business logic unless requested.
- Distinctive: line 163
Prefer small, explicit helpers over large conditional blocks.
- Very specific: line 164
Keep computed view builders below body and non-view computed vars above init.
“Common” is measured: kept by at least 6 in 10 of the 16 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
SwiftUI View Refactor
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/publiclet@State/ other stored properties- computed
var(non-view) initbody- 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, andtask/onChangefor 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
bodygrows beyond a screen or has multiple logical sections, split it into smaller subviews. - Extract large computed view properties (
var header: some View { ... }) into dedicatedViewtypes 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
Viewstruct 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):
var body: some View {
VStack(alignment: .leading, spacing: 16) {
HeaderSection(title: title, isPinned: isPinned)
DetailsSection(details: details)
ActionsSection(onSave: onSave, onCancel: onCancel)
}
}Example (long body → shorter body + computed views in the same file):
var body: some View {
List {
header
filters
results
footer
}
}
private var header: some View {
VStack(alignment: .leading, spacing: 6) {
Text(title).font(.title2)
Text(subtitle).font(.subheadline)
}
}
private var filters: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(filterOptions, id: \.self) { option in
FilterChip(option: option, isSelected: option == selectedFilter)
.onTapGesture { selectedFilter = option }
}
}
}
}Example (extracting a complex computed view):
private var header: some View {
HeaderSection(title: title, subtitle: subtitle, status: status)
}
private struct HeaderSection: View {
let title: String
let subtitle: String?
let status: Status
var body: some View {
VStack(alignment: .leading, spacing: 4) {
Text(title).font(.headline)
if let subtitle { Text(subtitle).font(.subheadline) }
StatusBadge(status: status)
}
}
}3b) Keep a stable view tree (avoid top-level conditional view swapping)
- Avoid patterns where a computed view (or
body) returns completely different root branches usingif/else. - Prefer a single stable base view, and place conditions inside sections/modifiers (
overlay,opacity,disabled,toolbar, row content, etc.). - Root-level branch swapping can cause identity churn, broader invalidation, and extra recomputation in SwiftUI.
Prefer:
var body: some View {
List {
documentsListContent
}
.toolbar {
if canEdit {
editToolbar
}
}
}Avoid:
var documentsListView: some View {
if canEdit {
editableDocumentsList
} else {
readOnlyDocumentsList
}
}4) View model handling (only if already present)
- Do not introduce a view model unless the request or existing code clearly calls for one.
- If a view model exists, make it non-optional when possible.
- Pass dependencies to the view via
init, then pass them into the view model in the view'sinit. - Avoid
bootstrapIfNeededpatterns.
Example (Observation-based):
@State private var viewModel: SomeViewModel
init(dependency: Dependency) {
_viewModel = State(initialValue: SomeViewModel(dependency: dependency))
}5) Observation usage
- For
@Observablereference types, store them as@Statein the root view. - Pass observables down explicitly as needed; avoid optional state unless required.
Workflow
- Reorder the view to match the ordering rules.
- Favor MV: move lightweight orchestration into the view using
@State,@Environment,@Query,task, andonChange. - Ensure stable view structure: avoid top-level
if-based branch swapping; move conditions to localized sections/modifiers. - If a view model exists, replace optional view models with a non-optional
@Stateview model initialized ininitby passing dependencies from the view. - Confirm Observation usage:
@Statefor root@Observableview models, no redundant wrappers. - Keep behavior intact: do not change layout or business logic unless requested.
Notes
- Prefer small, explicit helpers over large conditional blocks.
- Keep computed view builders below
bodyand non-view computed vars aboveinit. - For MV-first guidance and rationale, see
references/mv-patterns.md.
Large-view handling
- When a SwiftUI view file exceeds ~300 lines, split it using extensions to group related helpers. Move async functions and helper functions into dedicated
privateextensions, separated with// MARK: -comments that describe their purpose (e.g.,// MARK: - Actions,// MARK: - Subviews,// MARK: - Helpers). Keep the mainstructfocused on stored properties, init, andbody, with view-building computed vars also grouped via marks when the file is long.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

