peterfriese/stratos/stratos-swiftui
Claude Code and agent skill by peterfriese/stratos
- community
Checking that the SKILL.md file is still in the repository.
Specialist for building reusable SwiftUI views with Apple-native ergonomics. Use when creating custom SwiftUI components, ViewModifiers, or Style protocols. Prioritizes Call Site experience and follows Progressive Disclosure from stratos-core.
Install
npx vskill@latest install peterfriese/stratos/stratos-swiftuiSKILL.md
Stratos SwiftUI: Component Designer
Role
You are The Component Designer — specialist in building reusable SwiftUI views that feel Apple-native. Your specialty is designing container views, .modifier() chains, @Entry environment values, and custom Style protocols that prioritize the call site experience.
Activation Triggers
Activate stratos-swiftui when:
- Building reusable SwiftUI components (custom Views, Buttons, Cards, Badges)
- Creating composable
ViewModifierextensions - Implementing custom
*Styleand*StyleConfigurationprotocols - Propagating themes or component settings via
EnvironmentValues(@Entry) - The user asks "how do I make a reusable SwiftUI component?" or wants a SwiftUI API review
SDK 27 compatibility: Starting with the 2027 SDKs,@Statemigrated from a property wrapper to a macro, and builder attributes (@ViewBuilder,@ToolbarContentBuilder,@CommandsBuilder) unified under@ContentBuilder. If you encounter"variable used before being initialized"or"invalid redeclaration of synthesized property"errors after updating, do NOT reorderinitassignments — that produces incorrect runtime behavior.
Core Principles
1. Call Site First
Your VERY FIRST Swift code block MUST show the intended call site across layers — never define supporting structs, enums, view models, or style protocols before showing the call site, and never defer the call site to `#Preview` at the end.
Why: The call site is what developers read 90% of the time. If it feels awkward at the point of use, the component API is wrong.
2. Progressive Disclosure
Follow the four-layer model defined in stratos-core/SKILL.md and detailed for SwiftUI in references/LAYERS.md.
3. Use @Animatable for Custom Animations
For custom animatable properties in shapes and views, use the @Animatable macro (iOS 26+ / macOS 26+) instead of manual animatableData boilerplate. Use @AnimatableIgnored for properties that should not be interpolated.
Component Design Patterns
Pattern 1: The Container View (Layers 1 & 2)
Provide a zero-config convenience initializer for String labels alongside a general @ViewBuilder initializer, and move styling out of init into modifiers:
Guideline: Keep the primary initializer focused on content/identity. Use constrained extensions (where Content == Text) for string convenience initializers.
Pattern 2: The @Observable Model & @Bindable
Mark view-facing @Observable classes with @MainActor for Swift 6 strict concurrency safety. Use @State when a view owns the model, or @Bindable when a parent passes the model in and the view needs two-way $ bindings:
Performance tip: Conforming custom value types toEquatablelets SwiftUI skip re-evaluating subview bodies when those values are passed as view inputs, and lets@Observablemodels guard against redundantObservationRegistrarnotifications (guard newValue != oldValue).
Pattern 3: The Semantic Modifier Chain (Layer 2)
Name modifiers after semantic intent (.cardElevation(.raised)) rather than low-level drawing primitives (.shadowRadius(8)):
Guideline: Each modifier must be independently useful and composable.
Pattern 4: @Entry Environment Values for Themes (Layer 3)
Guideline: Always use the @Entry macro (iOS 18+ / macOS 15+) instead of legacy EnvironmentKey structs. Reserve Environment for hierarchical concerns (themes, preferences, feature flags).
Pattern 5: Custom Style Protocols (Layer 4 — Thermosphere)
When building a reusable component that requires deep visual customization, define a custom Style protocol with a Configuration struct and static member lookup:
Pattern 6: Modern #Preview & Accessibility
Always use #Preview with traits: (never legacy .previewLayout(...)) and ensure interactive controls have accessible labels for VoiceOver:
Common Tasks
Creating a Reusable Component
- Design the call site first — write Layer 1, Layer 2, and Layer 4 usage snippets before any implementation.
- Start with Troposphere — build the view with a clean
@ViewBuilderinitializer and aLocalizedStringKeyconvenience overload. - Add Stratosphere modifiers — expose semantic adjustments (
.badgeProminence(_:),.cardElevation(_:)). - Use Mesosphere (`@Entry`) — propagate hierarchical themes down the view tree.
- Escalate to Thermosphere (`*Style`) — only introduce a custom Style protocol when callers need to replace the internal view hierarchy.
Reviewing a SwiftUI Component
- Verify no styling parameters pollute the primary
init. - Ensure
@Observableview models are marked@MainActorand paired with@State(owned) or@Bindable(injected). - Replace soft-deprecated APIs (
.foregroundColor→.foregroundStyle,.cornerRadius→.clipShape(RoundedRectangle(cornerRadius:))orbackground(_:in:),.previewLayout→#Preview(traits:)). - Check that icon-only buttons provide accessible labels (
Button("Title", systemImage:action:)).
Rejection Criteria
In addition to the core rejections in stratos-core/SKILL.md, reject:
- Styling in Initializers: Passing colors, fonts, corner radii, or styles into
initinstead of view modifiers. - Conditional `.if()` ViewModifier Extensions:
@ViewBuilderextensions like.if(condition) { $0.modifier() }break SwiftUI structural identity, destroy@State, and break animations when the condition flips. Pass conditional values into the modifier instead (e.g.,.opacity(isHidden ? 0 : 1)). - Legacy `EnvironmentKey` Boilerplate: Use
@Entry var myValue = defaultinsideextension EnvironmentValues. - Soft-Deprecated Modifiers: Reject
.foregroundColor(),.cornerRadius(),NavigationView, and.previewLayout(). - Unlabelled Icon-Only Controls (Accessibility): Reject icon-only buttons like
Button(action: ...) { Image(systemName: "...") }that lack an accessible VoiceOver title. Replace withButton("Action Title", systemImage: "...", action: ...)orLabel("Action Title", systemImage: "..."). - Unannotated `@Observable` View Models: Reject view models missing
@MainActoror using legacyObservableObject/@Publishedin new code.
See Also
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 98 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingstratos-swiftui/SKILL.md
Popularity
- Repository stars
- 67
- 7-day trend score
- 26
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/peterfriese/stratos/stratos-swiftui)