
visionos-widgets
visionOS widget patterns including mounting styles, glass/paper textures, proximity-aware layouts, and spatial widget families. Use when creating or adapting widgets for visionOS.
- Installs
- 73
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/rshankras/claude-code-apple-skills --skill visionos-widgets- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads visionos-widgets automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
visionOS Widgets
Patterns for building widgets that live in physical space on visionOS. Covers mounting styles, textures, proximity-aware detail levels, spatial widget families, and rendering modes.
When This Skill Activates
Use this skill when the user:
- Asks to create or adapt a widget for visionOS
- Mentions mounting styles (elevated, recessed)
- Wants glass or paper texture on a widget
- Asks about proximity awareness or level of detail in widgets
- Mentions spatial widget families or
.systemExtraLargePortrait - Wants to control container backgrounds or rendering modes (full color vs accented)
- Is porting an existing iOS/iPadOS widget to visionOS
Decision Tree
What do you need for your visionOS widget?
|
+- Where should the widget appear?
| +- On a surface (table, shelf) -> .elevated (default)
| +- Embedded in a wall -> .recessed
| +- Both -> .supportedMountingStyles([.elevated, .recessed])
|
+- What visual treatment?
| +- Transparent, blends with environment -> .glass (default)
| +- Opaque, poster-like appearance -> .paper
|
+- How should it respond to user distance?
| +- Full detail when close -> @Environment(\.levelOfDetail) == .default
| +- Simplified when far -> @Environment(\.levelOfDetail) == .simplified
|
+- What size families?
| +- Standard -> .systemSmall, .systemMedium, .systemLarge, .systemExtraLarge
| +- Tall portrait -> .systemExtraLargePortrait (visionOS only)
|
+- How should colors render?
| +- Full color (default) -> No extra work
| +- System-tinted monochrome -> Mark backgrounds with .containerBackground(for:)
API Availability
| API | Minimum Version | Notes |
|---|---|---|
| WidgetKit on visionOS | visionOS 1.0 | Basic widget support |
.containerBackground(for: .widget) | visionOS 1.0 | Removable background marking |
@Environment(\.showsWidgetContainerBackground) | visionOS 1.0 | Background visibility check |
.supportedMountingStyles() | visionOS 2.0 | Elevated and recessed placement |
.widgetTexture(.glass / .paper) | visionOS 2.0 | Widget surface material |
@Environment(\.levelOfDetail) | visionOS 2.0 | Proximity-aware layouts |
.systemExtraLargePortrait | visionOS 2.0 | Tall portrait widget family |
Complete Widget Example
This example demonstrates mounting styles, textures, families, and proximity awareness together:
struct MyWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(
kind: "com.example.mywidget",
provider: Provider()
) { entry in
MyWidgetView(entry: entry)
}
.supportedFamilies([
.systemSmall, .systemMedium, .systemLarge,
.systemExtraLarge, .systemExtraLargePortrait
])
.supportedMountingStyles([.elevated, .recessed])
.widgetTexture(.glass) // .glass is default, .paper for opaque
}
}
Mounting styles: .elevated (default) sits on surfaces like tables. .recessed embeds into walls like a framed picture. Omit .supportedMountingStyles() to use elevated only. Recessed works only on vertical surfaces — placements on horizontal surfaces are always elevated. On horizontal surfaces the system also applies a gentle tilt toward the user; design for that angle rather than fighting it.
Textures: .glass (default) blends with the environment; .paper is opaque, best for rich imagery.
Spatial Behavior (WWDC25)
Widgets are permanent, physical-surface-only room fixtures — they persist across sessions, room changes, and power cycles, and multiple instances can coexist in a room.
- User resizing: a corner affordance lets users scale a widget from 75% to 125% of its template size — layouts must survive the entire range.
- Frames: users pick from five frame widths (thin to thick), independent of template size. The recessed style fixes the frame width.
- Frame tinting: the widget frame always receives the user's color tint and cannot opt out. Even when the background opts out of tinting, foregrounds must hold up under all 7 light and 7 dark system palettes.
- Assets: widgets render at real-world scale — ship high-resolution assets so imagery stays sharp at close range.
Proximity Awareness (Level of Detail)
The system transitions automatically, with animation, between .default (close) and .simplified (far) based on user distance — simplify by cutting density and enlarging key info.
struct MyWidgetView: View {
let entry: Provider.Entry
@Environment(\.levelOfDetail) private var levelOfDetail
var body: some View {
switch levelOfDetail {
case .default:
VStack(alignment: .leading, spacing: 8) {
Text(entry.title).font(.headline)
Text(entry.subtitle).font(.subheadline).foregroundStyle(.secondary)
DetailChart(data: entry.chartData)
}
.padding()
case .simplified:
VStack(spacing: 4) {
Image(systemName: entry.iconName).font(.largeTitle)
Text(entry.title).font(.headline)
}
.padding()
@unknown default:
Text(entry.title).padding()
}
}
}
Always handle @unknown default for forward compatibility.
Widget Families
| Family | Description |
|---|---|
.systemSmall | Compact square -- glanceable info |
.systemMedium | Wide rectangle -- two-column or list preview |
.systemLarge | Large square -- charts, detailed content |
.systemExtraLarge | Extra-large landscape -- dashboards |
.systemExtraLargePortrait | Extra-large portrait -- visionOS only; wall-art "statement" widgets |
Guard the visionOS-only family in multiplatform targets:
.supportedFamilies({
var families: [WidgetFamily] = [.systemSmall, .systemMedium, .systemLarge]
#if os(visionOS)
families.append(.systemExtraLargePortrait)
#endif
return families
}())
Container Backgrounds and Rendering Modes
In accented rendering mode, the system removes backgrounds and applies a tint color. Mark removable backgrounds so the widget renders correctly in both modes.
struct MyWidgetView: View {
let entry: Provider.Entry
@Environment(\.showsWidgetContainerBackground) var showsBackground
var body: some View {
VStack {
Image(systemName: "star.fill").font(.largeTitle)
Text(entry.title)
.font(.headline)
.foregroundStyle(showsBackground ? .white : .primary)
}
.padding()
.containerBackground(for: .widget) {
LinearGradient(
colors: [.blue, .purple],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
}
}
}
- Full color (default): All colors render intact.
- Accented: Container background is removed; system applies a monochrome tint.
Previewing visionOS Widgets
#Preview("Close Up", as: .systemSmall) {
MyWidget()
} timelineProvider: {
Provider()
}
#Preview("Extra Large Portrait", as: .systemExtraLargePortrait) {
MyWidget()
} timelineProvider: {
Provider()
}
Top 5 Mistakes
| # | Mistake | Fix |
|---|---|---|
| 1 | Missing .containerBackground(for: .widget) -- accented mode renders blank | Always wrap backgrounds in .containerBackground(for: .widget) { } |
| 2 | Ignoring levelOfDetail -- detailed views unreadable from across the room | Provide a .simplified layout with larger text, fewer elements |
| 3 | Using .systemExtraLargePortrait on iOS -- build error or runtime crash | Guard with #if os(visionOS) or visionOS-only targets |
| 4 | Hardcoding colors that clash with glass texture | Use .foregroundStyle(.primary / .secondary) and system colors |
| 5 | No @unknown default in levelOfDetail switch | Always include for forward compatibility |
Anti-Patterns
// ❌ No container background — accented mode shows nothing
struct BadWidgetView: View {
var body: some View {
ZStack {
Color.blue // Not marked as removable
Text("Hello")
}
}
}
// ✅ Background marked as removable
struct GoodWidgetView: View {
var body: some View {
Text("Hello")
.containerBackground(for: .widget) { Color.blue }
}
}
// ❌ Same complex layout at all distances
struct BadProximityView: View {
var body: some View {
VStack {
Text(entry.title).font(.caption2) // Unreadable far away
DetailChart(data: entry.data)
}
}
}
// ✅ Simplified layout when far away
struct GoodProximityView: View {
@Environment(\.levelOfDetail) private var levelOfDetail
var body: some View {
switch levelOfDetail {
case .default: DetailedLayout(entry: entry)
case .simplified: SimplifiedLayout(entry: entry)
@unknown default: SimplifiedLayout(entry: entry)
}
}
}
Review Checklist
Mounting and Texture
- Mounting style explicitly set if widget should appear recessed or support both
- Texture set to
.paperfor widgets with rich imagery - Widget tested in both elevated and recessed placements (if both supported)
- Layout survives user resizing from 75% to 125% of the template size
Proximity Awareness
-
@Environment(\.levelOfDetail)provides simplified layout for distant viewers -
.simplifiedlayout uses larger text, fewer elements, high-contrast visuals -
@unknown defaultcase present inlevelOfDetailswitch
Families and Layout
-
.systemExtraLargePortraitguarded with#if os(visionOS)in multiplatform targets - Widget content adapts to each supported family size
- Layout tested in all declared family sizes via Xcode previews
Backgrounds and Rendering
-
.containerBackground(for: .widget) { }used to mark removable backgrounds - Widget renders correctly in both full color and accented modes
-
showsWidgetContainerBackgroundchecked if foreground colors depend on background - System semantic colors used for glass texture compatibility
- Foreground legible under all 7 light and 7 dark frame-tint palettes
References
FAQ
What does the visionos-widgets skill do?
visionOS widget patterns including mounting styles, glass/paper textures, proximity-aware layouts, and spatial widget families. Use when creating or adapting widgets for visionOS.
How do I install visionos-widgets?
Run npx skills add https://github.com/rshankras/claude-code-apple-skills --skill visionos-widgets in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/visionos-widgets/ (personal) or .claude/skills/visionos-widgets/ (project).
Which AI agents can use visionos-widgets?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is visionos-widgets safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains visionos-widgets?
It is published by rshankras in rshankras/claude-code-apple-skills. It has 73 recorded installs.
More from rshankras/claude-code-apple-skills
macos-development
rshankras/claude-code-apple-skills
Comprehensive macOS development guidance including Swift 6+, SwiftUI, SwiftData, architecture patterns, AppKit bridging, and macOS 26 Tahoe APIs. Use for macOS code review, best practices, UI review, or platform-specific features.
ios-development
rshankras/claude-code-apple-skills
Comprehensive iOS development guidance including Swift best practices, SwiftUI patterns, UI/UX review against HIG, and app planning. Use for iOS code review, best practices, accessibility audits, or planning new iOS apps.
design
rshankras/claude-code-apple-skills
Design skills for Apple platform UI — Liquid Glass, animations, game feel (haptics, sound, celebrations), UI prototyping, UX writing, SF Symbols, and typography. Use when implementing design language features, adding juice/feedback, writing interface copy, or choosing type and iconography.
app-store
rshankras/claude-code-apple-skills
App Store optimization and marketing skills for descriptions, screenshots, keywords, review responses, and comprehensive promotional strategy. Use when user needs help with App Store presence, ASO, marketing, or customer communication.
watchos
rshankras/claude-code-apple-skills
watchOS development guidance including SwiftUI for Watch, Watch Connectivity, complications, and watch-specific UI patterns. Use for watchOS code review, best practices, or Watch app development.
product-development
rshankras/claude-code-apple-skills
End-to-end product development for iOS/macOS apps. Covers market research, competitive analysis, PRD generation, architecture specs, UX design, implementation guides, testing, and App Store release. Use for product planning, validation, or generating specification documents.
Popular education & science skills
teach
mattpocock/skills
Teach the user a new skill or concept, within this workspace.
scaffold-exercises
mattpocock/skills
Create exercise directory structures with sections, problems, solutions, and explainers that pass linting. Use when user wants to scaffold exercises, create exercise stubs, or set up a new course section.
paper-context-resolver
lllllllama/rigorpilot-skills
Rigor Paper Context helper for README-first deep learning repo reproduction. Use only when the README and repository files leave a narrow reproduction-critical gap and the task is to resolve a specific paper detail such as dataset split, preprocessing, evaluation protocol, checkpoint mapping, or runtime assumption from primary paper sources while recording conflicts. Do not use for general paper summary, repo scanning, environment setup, command execution, title-only paper lookup, or replacing README guidance by default.
caveman-learn
juliusbrussee/caveman
Act on a Caveman learn report - review the ranked token sinks, apply cost-lowering fixes with per-edit consent, and report what those fixes returned. Use when asked to lower an agent's token cost, what caveman has saved, to trim a heavy CLAUDE.md, or to offload re-pasted context into cavemem.
gsap-plugins
greensock/gsap-skills
Official GSAP skill for GSAP plugins — registration, ScrollToPlugin, ScrollSmoother, Flip, Draggable, Inertia, Observer, SplitText, ScrambleText, SVG and physics plugins, CustomEase, EasePack, CustomWiggle, CustomBounce, GSDevTools. Use when the user asks about a GSAP plugin, scroll-to, flip animations, draggable, SVG drawing, or plugin registration.
teach-impeccable
pbakaus/impeccable
DEPRECATED: Use /impeccable teach instead. This command has been folded into the impeccable skill.