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.

149 stars

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

$curl -o ~/.claude/skills/widget-generator/SKILL.md --create-dirs "https://raw.githubusercontent.com/rshankras/claude-code-apple-skills/main/skills/generators/widget-generator/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/widget-generator/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How widget-generator Compares

Feature / Agentwidget-generatorStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/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

149
from rshankras/claude-code-apple-skills

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

149
from rshankras/claude-code-apple-skills

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

149
from rshankras/claude-code-apple-skills

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

149
from rshankras/claude-code-apple-skills

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

149
from rshankras/claude-code-apple-skills

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

149
from rshankras/claude-code-apple-skills

Generate test templates for unit tests, integration tests, and UI tests using Swift Testing and XCTest. Use when adding tests to iOS/macOS apps.

paywall-generator

149
from rshankras/claude-code-apple-skills

Generates StoreKit 2 subscription paywall with modern SwiftUI views. Use when user wants to add subscriptions, paywall, or in-app purchases.

onboarding-generator

149
from rshankras/claude-code-apple-skills

Generates multi-step onboarding flows with persistence for iOS/macOS apps. Use when user wants to add onboarding, welcome screens, or first-launch experience.

live-activity-generator

149
from rshankras/claude-code-apple-skills

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.

app-icon-generator

149
from rshankras/claude-code-apple-skills

Generates app icons programmatically using CoreGraphics following Apple HIG. Use when user wants to create, generate, or design an app icon for macOS or iOS.

accessibility-generator

149
from rshankras/claude-code-apple-skills

Generate accessibility infrastructure for VoiceOver, Dynamic Type, and accessibility features. Use when improving app accessibility, adding accessibility labels and hints, or auditing compliance.

generators

149
from rshankras/claude-code-apple-skills

Code generator skills that produce production-ready Swift code for common app components. Use when user wants to add logging, analytics, onboarding, review prompts, networking, authentication, paywalls, settings, persistence, error monitoring, CI/CD pipelines, localization, push notifications, deep linking, testing, accessibility, widgets, feature flags, app icons, image caching, pagination, HTTP caching, share cards, social export, subscription lifecycle, referral systems, watermarks, streak tracking, milestone celebrations, what's new screens, lapsed user re-engagement, usage insights, variable rewards, consent flows, account deletion, permission priming, force updates, state restoration, debug menus, offline queues, feedback forms, announcement banners, quick win sessions, Spotlight indexing, App Clips, screenshot automation, background processing, app extensions, or data export.