view-refactor
Skill0 starsChanged 7 months agoMITView on GitHub
Refactor SwiftUI view files for consistent structure, dependency injection, and Observation usage. Use when asked to clean up a SwiftUI view's layout, handle view models safely, or standardize how dependencies are initialized and passed.
3 other projects use a version of this.
Adopted by
Most recently taken up by
- MMACABRE/SKILLStheir own version, first seen Nov 8, 2026
- openai/pluginstheir own version, first seen Oct 13, 2026
- patrickserrano/skillsword for word, first seen Jan 17, 2026
Other versions3 projects use a version of this.
Word for word · 1
- patrickserrano/skills★ 13100% same
Edited · 0
None found.
Wrote their own version · 2
- openai/plugins★ 7.8ksame name
- MMACABRE/SKILLS★ 1same name
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 repository8 other files it gives its agents.
- app-store-preflight-skillsSkill
- fastapi-patternsSkill
- frontend-designSkill
- mcp-builderSkill
- code-documentationSkill
- python-testingSkill
- ui-patternsSkill
- theme-factorySkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 6 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 27
Default to MV: views are lightweight state expressions.
- Very specific: line 34
If body grows beyond a screen or has multiple logical sections, split it:
- Distinctive: line 79
Do not introduce a view model unless the request or existing code clearly calls for one
- Distinctive: line 80
If a view model exists, make it non-optional when possible
- Distinctive: line 95
Avoid optional state unless required
- Very specific: line 101
If a view model exists, replace optional with non-optional @State initialized in init
- Distinctive: line 103
Keep behavior intact: do not change layout or business logic unless requested
- Distinctive: line 107
When a SwiftUI view file exceeds ~300 lines:
- Very specific: line 111
Use // MARK: - comments (e.g., // MARK: - Actions, // MARK: - Subviews)
- Very specific: line 112
Keep main struct focused on stored properties, init, and body
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “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 consistent structure and dependency patterns to SwiftUI views, focusing on ordering, MV patterns, careful view model handling, and correct Observation usage.
View Ordering (top to bottom)
- Environment properties
private/publicletconstants@State/ other stored properties- Computed
var(non-view) initbody- Computed view builders / view helpers
- Helper / async functions
Core Guidelines
1) Prefer MV (Model-View) Patterns
- Default to MV: views are lightweight state expressions; models/services own business logic
- Favor
@State,@Environment,@Query,task, andonChangefor orchestration - Inject services and shared models via
@Environment - Split large views into smaller views instead of introducing a view model
2) Split Large Bodies
If body grows beyond a screen or has multiple logical sections, split it:
var body: some View {
VStack(alignment: .leading, spacing: 16) {
HeaderSection(title: title, isPinned: isPinned)
DetailsSection(details: details)
ActionsSection(onSave: onSave, onCancel: onCancel)
}
}Or use computed view properties 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 }
}
}
}
}3) 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 into the view model
@State private var viewModel: SomeViewModel
init(dependency: Dependency) {
_viewModel = State(initialValue: SomeViewModel(dependency: dependency))
}4) Observation Usage
- For
@Observablereference types, store them as@Statein the root view - Pass observables down explicitly as needed
- Avoid optional state unless required
Refactor Workflow
- Reorder the view to match the ordering rules
- Favor MV: move orchestration into the view using
@State,@Environment,task,onChange - If a view model exists, replace optional with non-optional
@Stateinitialized ininit - Confirm Observation usage:
@Statefor root@Observable, no redundant wrappers - Keep behavior intact: do not change layout or business logic unless requested
Large-View Handling
When a SwiftUI view file exceeds ~300 lines:
- Split using extensions to group related helpers
- Move async functions into dedicated
privateextensions - Use
// MARK: -comments (e.g.,// MARK: - Actions,// MARK: - Subviews) - Keep main
structfocused on stored properties, init, andbody
struct LargeView: View {
@Environment(Store.self) private var store
@State private var items: [Item] = []
var body: some View {
List {
content
}
.task { await loadItems() }
}
}
// MARK: - Subviews
private extension LargeView {
var content: some View {
ForEach(items) { item in
ItemRow(item: item)
}
}
}
// MARK: - Actions
private extension LargeView {
func loadItems() async {
items = await store.fetchItems()
}
}Checklist
- Properties ordered correctly (Environment → let → @State → computed → init → body)
- Large body split into subviews or computed view properties
- No unnecessary ViewModels introduced
- Existing ViewModels are non-optional where possible
@Observabletypes stored as@Statein root view- Dependencies injected via
@Environment - File organized with MARK comments if >300 lines
- Behavior unchanged unless explicitly requested
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.

