agentleFS
LWaetzigLWaetzig/claude-code-skills/skills/swiftui-view-refactor/SKILL.md

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

  • Other versions3 projects use a version of this.

    Word for word · 1

    1. patrickserrano/skills★ 13100% same

    Edited · 0

    None found.

    Wrote their own version · 2

    1. openai/plugins★ 7.8ksame name
    2. 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.

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
  1. Distinctive:

    Default to MV: views are lightweight state expressions.

    line 27
  2. Very specific:

    If body grows beyond a screen or has multiple logical sections, split it:

    line 34
  3. Distinctive:

    Do not introduce a view model unless the request or existing code clearly calls for one

    line 79
  4. Distinctive:

    If a view model exists, make it non-optional when possible

    line 80
  5. Distinctive:

    Avoid optional state unless required

    line 95
  6. Very specific:

    If a view model exists, replace optional with non-optional @State initialized in init

    line 101
  7. Distinctive:

    Keep behavior intact: do not change layout or business logic unless requested

    line 103
  8. Distinctive:

    When a SwiftUI view file exceeds ~300 lines:

    line 107
  9. Very specific:

    Use // MARK: - comments (e.g., // MARK: - Actions, // MARK: - Subviews)

    line 111
  10. Very specific:

    Keep main struct focused on stored properties, init, and body

    line 112

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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)

  1. Environment properties
  2. private/public let constants
  3. @State / other stored properties
  4. Computed var (non-view)
  5. init
  6. body
  7. Computed view builders / view helpers
  8. 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, and onChange for 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 @Observable reference types, store them as @State in the root view
  • Pass observables down explicitly as needed
  • Avoid optional state unless required

Refactor Workflow

  1. Reorder the view to match the ordering rules
  2. Favor MV: move orchestration into the view using @State, @Environment, task, onChange
  3. If a view model exists, replace optional with non-optional @State initialized in init
  4. Confirm Observation usage: @State for root @Observable, no redundant wrappers
  5. Keep behavior intact: do not change layout or business logic unless requested

Large-View Handling

When a SwiftUI view file exceeds ~300 lines:

  1. Split using extensions to group related helpers
  2. Move async functions into dedicated private extensions
  3. Use // MARK: - comments (e.g., // MARK: - Actions, // MARK: - Subviews)
  4. Keep main struct focused on stored properties, init, and body
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
  • @Observable types stored as @State in root view
  • Dependencies injected via @Environment
  • File organized with MARK comments if >300 lines
  • Behavior unchanged unless explicitly requested

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.