widget-generator
Generate WidgetKit widgets for iOS/macOS home screen and lock screen with timeline providers, interactive elements, and App Intent configuration. Use when adding widgets to an app.
Best use case
widget-generator is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Generate WidgetKit widgets for iOS/macOS home screen and lock screen with timeline providers, interactive elements, and App Intent configuration. Use when adding widgets to an app.
Teams using widget-generator should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/widget-generator/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How widget-generator Compares
| Feature / Agent | widget-generator | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Generate WidgetKit widgets for iOS/macOS home screen and lock screen with timeline providers, interactive elements, and App Intent configuration. Use when adding widgets to an app.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Widget Generator
Generate a complete WidgetKit widget implementation with timeline providers, size-specific views, lock screen accessory widgets, interactive elements (iOS 17+), and App Intent configuration.
## When This Skill Activates
Use this skill when the user:
- Asks to "add widgets" or "add a widget" to their app
- Mentions "WidgetKit" or "home screen widgets"
- Wants "lock screen widgets" or "accessory widgets"
- Asks about "widget timelines" or "timeline providers"
- Wants "interactive widgets" with buttons or toggles
- Mentions "widget configuration" or "configurable widgets"
- Asks about "App Intent widgets" or "AppIntentConfiguration"
- Wants to show data on the home screen or lock screen
## Pre-Generation Checks
### 1. Project Context Detection
- [ ] Check for existing widget extension target
- [ ] Check for an existing `WidgetBundle`
- [ ] Verify deployment target (iOS 17+ recommended for interactive widgets)
- [ ] Identify source file locations and project structure
### 2. Conflict Detection
Search for existing widget code:
```
Glob: **/*Widget*.swift, **/*TimelineProvider*.swift
Grep: "WidgetKit" or "TimelineProvider" or "WidgetBundle" or "WidgetConfiguration"
```
If an existing widget extension is found:
- Ask if the new widget should be added to the existing widget extension
- Check for an existing `WidgetBundle` to extend
If a `WidgetBundle` already exists:
- Add the new widget to the existing bundle instead of creating a new one
- Do NOT create a second `@main` entry point
If widget code with the same name exists:
- Ask user whether to replace or rename
### 3. Required Capabilities
**Widgets require:**
- A widget extension target (File > New > Target > Widget Extension)
- App Groups capability if sharing data between the main app and widget
- iOS 14+ for basic widgets, iOS 16+ for lock screen, iOS 17+ for interactive widgets
## Configuration Questions
Ask user via AskUserQuestion:
1. **What is this widget for?** (freeform)
- Examples: weather forecast, task list, fitness stats, quick actions, countdown timer
- This determines the data model and timeline update strategy
2. **Which widget sizes should be supported?**
- Home screen: systemSmall, systemMedium, systemLarge, systemExtraLarge (iPad only)
- Lock screen: accessoryCircular, accessoryRectangular, accessoryInline
- All home screen sizes
- All home screen + lock screen sizes (recommended)
3. **What type of widget?**
- **Static** (`StaticConfiguration`) -- content updated on a schedule, no user configuration
- **Configurable** (`AppIntentConfiguration`, iOS 17+) -- user can choose what the widget displays via long-press edit
- **Interactive** (`AppIntentConfiguration` + `Button`/`Toggle`, iOS 17+) -- user can tap buttons or toggles directly on the widget
4. **What is the data source?**
- Local data (UserDefaults, SwiftData, Core Data)
- Shared data via App Groups (main app writes, widget reads)
- Network API (fetched during timeline refresh)
- Combination of local and network
5. **How often should the widget update?**
- Every 15 minutes (minimum practical interval)
- Every 30 minutes
- Every hour (recommended default)
- A few times per day
- Based on specific times (e.g., calendar events)
- On-demand from the main app via `WidgetCenter.shared.reloadTimelines(ofKind:)`
## Generation Process
### Step 1: Determine File Locations
Check project structure:
- If a widget extension target directory exists, add view and provider files there
- Otherwise, instruct user to create a Widget Extension target first
For widget extension files:
- Place inside the existing widget extension directory (e.g., `MyAppWidgets/`)
For shared data models (if using App Groups):
- If `Sources/` or `Shared/` exists --> place there
- Otherwise --> create alongside existing models
### Step 2: Create Core Files
Generate these files based on configuration answers:
1. **`{Name}Widget.swift`** -- Widget definition with configuration
- `Widget` struct with `StaticConfiguration` or `AppIntentConfiguration`
- Supported families declaration
- Display name and description
2. **`{Name}TimelineProvider.swift`** -- Timeline logic
- `TimelineProvider` (static) or `AppIntentTimelineProvider` (configurable)
- Placeholder, snapshot, and timeline methods
3. **`{Name}Entry.swift`** -- Timeline entry model
- `TimelineEntry` struct with date and display data
4. **`{Name}WidgetViews.swift`** -- Size-specific views
- Separate view struct for each supported family
- Uses `containerBackground` for iOS 17+ removable backgrounds
5. **`{Name}AppIntent.swift`** (if interactive or configurable)
- `WidgetConfigurationIntent` for configurable widgets
- `AppIntent` for interactive widget buttons/toggles
6. **WidgetBundle update** -- Register the new widget
- Add to existing bundle or create new one
### Step 3: Generate Code from Templates
Use the templates in **templates.md** and customize based on user answers:
- Replace placeholder names with the actual widget name
- Configure supported families based on size selection
- Include or exclude interactive elements
- Include or exclude lock screen accessory views
- Set up App Group shared data access if needed
- Configure timeline refresh policy based on update frequency
## Output Format
After generation, provide:
### Files Created
```
MyAppWidgets/
├── {Name}Widget.swift # Widget definition + configuration
├── {Name}TimelineProvider.swift # Timeline provider with placeholder/snapshot/timeline
├── {Name}Entry.swift # TimelineEntry data model
├── {Name}WidgetViews.swift # Size-specific views for each family
├── {Name}AppIntent.swift # (if configurable/interactive) App Intent
└── (update WidgetBundle if needed)
Shared/
└── {Name}DataProvider.swift # (if App Groups) Shared data access
```
### Integration Steps
**1. Add the widget extension target (if not present):**
- File > New > Target > Widget Extension
- Choose "Include Configuration App Intent" if configurable
- Ensure the widget extension embeds in the main app
**2. Enable App Groups (if sharing data with the main app):**
- Select the main app target > Signing & Capabilities > + Capability > App Groups
- Select the widget extension target > Signing & Capabilities > + Capability > App Groups
- Use the same group identifier (e.g., `group.com.yourcompany.yourapp`)
**3. Register the widget in the WidgetBundle:**
```swift
@main
struct MyAppWidgets: WidgetBundle {
var body: some Widget {
// Existing widgets...
{Name}Widget()
}
}
```
**4. Trigger widget updates from the main app when data changes:**
```swift
import WidgetKit
// Reload a specific widget
WidgetCenter.shared.reloadTimelines(ofKind: "{Name}Widget")
// Or reload all widgets
WidgetCenter.shared.reloadAllTimelines()
```
**5. For App Group data sharing, write from the main app:**
```swift
let sharedDefaults = UserDefaults(suiteName: "group.com.yourcompany.yourapp")
sharedDefaults?.set(encodedData, forKey: "widgetData")
// Then trigger reload
WidgetCenter.shared.reloadTimelines(ofKind: "{Name}Widget")
```
### Testing Instructions
1. **Simulator support:** Widgets can be previewed in Xcode Canvas and tested in Simulator.
2. **Add to home screen:** Long-press the home screen > tap "+" > find your app > select the widget size.
3. **Lock screen widgets:** Long-press the lock screen > "Customize" > select the widget area.
4. **Preview in Xcode:** Use `#Preview` with timeline entry data for rapid iteration.
5. **Timeline debugging:** Use `WidgetCenter.shared.getCurrentConfigurations` to verify registered widgets.
6. **Interactive widget testing (iOS 17+):** Tap buttons/toggles directly on the widget in Simulator or device.
7. **Memory profiling:** Widgets have a 40MB memory limit. Profile in Instruments if loading images or large datasets.
## Common Widget Patterns
### Weather Widget
- **Data:** Temperature, condition icon, hourly forecast
- **Sizes:** systemSmall (current temp), systemMedium (hourly), accessoryCircular (temp gauge)
- **Update:** Every 30 minutes via network API
- **Timeline:** Generate entries for next few hours with forecast data
### Calendar / Events Widget
- **Data:** Upcoming events, times, locations
- **Sizes:** systemSmall (next event), systemMedium (next 3 events), accessoryRectangular (next event)
- **Update:** Based on event start times using `.after(nextEventDate)` policy
- **Timeline:** One entry per upcoming event transition
### Fitness / Health Widget
- **Data:** Steps, calories, activity rings
- **Sizes:** systemSmall (ring summary), accessoryCircular (ring gauge), accessoryRectangular (stats)
- **Update:** Every 15-30 minutes from HealthKit via App Groups
- **Interactive:** None (read-only data display)
### Quick Actions Widget
- **Data:** Action buttons (start timer, toggle light, log water)
- **Sizes:** systemSmall (single action), systemMedium (2-4 actions)
- **Update:** Infrequent (actions are static, only state changes)
- **Interactive:** `Button(intent:)` for each action (iOS 17+)
### Countdown Widget
- **Data:** Target date, label, time remaining
- **Sizes:** systemSmall (days remaining), accessoryCircular (days number), accessoryInline (text countdown)
- **Update:** Daily or use `Text(date, style: .timer)` / `Text(date, style: .relative)` for automatic live updates
- **Timeline:** SwiftUI date styles update automatically without timeline refreshes
## Gotchas and Limits
- **Timeline budget:** The system limits how often your timeline provider runs. Typically ~40-70 refreshes per day. Do not rely on exact timing.
- **40MB memory limit:** Widget extensions are killed if they exceed 40MB. Avoid loading large images or datasets. Use thumbnails and minimal data.
- **`containerBackground` required (iOS 17+):** All widget views must use `.containerBackground(for: .widget)` to support the system's removable background feature. Without this, widgets show a default placeholder background.
- **Accessory family rendering:** Lock screen widgets render in a limited color space. Use `AccessoryWidgetBackground()` for backgrounds and keep designs simple with high contrast.
- **No animation:** Widgets do not support explicit animations. Use `Text(date, style: .timer)` for countdowns; the system animates these for you.
- **No scrolling:** Widgets cannot scroll. Design for fixed, visible content.
- **No video or maps:** MapKit and AVKit are not available in widget extensions.
- **Networking in timeline provider:** Network requests in `getTimeline` must complete quickly. The system may terminate long-running providers.
- **`@main` conflict:** Only one `@main` per widget extension. If you have multiple widgets, use a `WidgetBundle` as the single `@main` entry point.
- **Configurable widget data persistence:** `AppIntent` parameter values are stored by the system. Do not rely on UserDefaults for configuration state.
- **Xcode previews:** Use `#Preview(as: .systemSmall)` for family-specific widget previews.
- **Shared code with main app:** Timeline entries and data models referenced by both targets must have target membership in both the main app and the widget extension.
## References
- **templates.md** -- Production-ready code templates for widget definition, timeline provider, views, and App Intents
- [WidgetKit Documentation](https://developer.apple.com/documentation/widgetkit)
- [Creating a Widget Extension](https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension)
- [Making a Configurable Widget](https://developer.apple.com/documentation/widgetkit/making-a-configurable-widget)
- [Adding Interactivity to Widgets](https://developer.apple.com/documentation/widgetkit/adding-interactivity-to-widgets-and-live-activities)
- [WidgetKit Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/widgets)Related Skills
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.
characterization-test-generator
Generates tests that capture current behavior of existing code before refactoring. Use when you need a safety net before AI-assisted refactoring or modifying legacy code.
prd-generator
Generates comprehensive Product Requirements Document from product plan. Creates PRD.md with features, user stories, acceptance criteria, and success metrics. Use when creating product requirements.
idea-generator
Brainstorm and rank iOS/macOS app ideas tailored to developer skills. Use when user says "what should I build", "give me app ideas", "I don't know what to build", "brainstorm app ideas", or "help me find an app idea".
tipkit-generator
Generate TipKit infrastructure with inline/popover tips, rules, display frequency, and testing utilities. Use when adding contextual tips or feature discovery to an iOS/macOS app.
test-generator
Generate test templates for unit tests, integration tests, and UI tests using Swift Testing and XCTest. Use when adding tests to iOS/macOS apps.
Push Notifications Generator
Generate push notification infrastructure with APNs registration, handling, and rich notifications.
paywall-generator
Generates StoreKit 2 subscription paywall with modern SwiftUI views. Use when user wants to add subscriptions, paywall, or in-app purchases.
onboarding-generator
Generates multi-step onboarding flows with persistence for iOS/macOS apps. Use when user wants to add onboarding, welcome screens, or first-launch experience.
Localization Setup Generator
Generate internationalization (i18n) infrastructure for multi-language support in iOS/macOS apps.
live-activity-generator
Generate ActivityKit Live Activity infrastructure with Dynamic Island layouts, Lock Screen presentation, and push-to-update support. Use when adding Live Activities to an iOS app.
Deep Linking Generator
Generate deep linking infrastructure with URL schemes, Universal Links, and App Intents for Siri/Shortcuts.