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.
npx skills add https://github.com/rshankras/claude-code-apple-skills --skill 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.
Use this skill when the user:
WidgetBundleSearch for existing widget code:
Glob: **/*Widget*.swift, **/*TimelineProvider*.swift
Grep: "WidgetKit" or "TimelineProvider" or "WidgetBundle" or "WidgetConfiguration"
If an existing widget extension is found:
WidgetBundle to extendIf a WidgetBundle already exists:
@main entry pointIf widget code with the same name exists:
Widgets require:
Ask user via AskUserQuestion:
StaticConfiguration) -- content updated on a schedule, no user configurationAppIntentConfiguration, iOS 17+) -- user can choose what the widget displays via long-press editAppIntentConfiguration + Button/Toggle, iOS 17+) -- user can tap buttons or toggles directly on the widgetWidgetCenter.shared.reloadTimelines(ofKind:)Check project structure:
For widget extension files:
MyAppWidgets/)For shared data models (if using App Groups):
Sources/ or Shared/ exists --> place thereGenerate these files based on configuration answers:
{Name}Widget.swift -- Widget definition with configurationWidget struct with StaticConfiguration or AppIntentConfiguration{Name}TimelineProvider.swift -- Timeline logicTimelineProvider (static) or AppIntentTimelineProvider (configurable){Name}Entry.swift -- Timeline entry modelTimelineEntry struct with date and display data{Name}WidgetViews.swift -- Size-specific viewscontainerBackground for iOS 17+ removable backgrounds{Name}AppIntent.swift (if interactive or configurable)WidgetConfigurationIntent for configurable widgetsAppIntent for interactive widget buttons/togglesUse the templates in templates.md and customize based on user answers:
Apply these when generating the size-specific views. A good widget idea is at least one of personal (the user's own data), informational (the most-wanted status at a glance), or contextual (the right thing for this moment). Glanceability is the bar — a widget is read in about a second on the way somewhere else.
| Rule | Specific |
|------|----------|
| Small widget | Max ~4 pieces of information; exactly one tap target (the whole widget) |
| Medium/Large | Multiple tap targets allowed — cell style for visually contained targets, content style for uncontained lists |
| Margins | 16pt default; 11pt acceptable for tighter graphical shapes (circles, glyphs) |
| Corners | Inner shapes must be concentric with the widget's corner radius |
| Layouts | Design each family separately — never scale the small layout up to medium/large |
| Typography | SF Pro, SF Pro Rounded, or SF Mono; custom fonts only when core to the brand |
| Logo | Only if the app aggregates content from multiple sources — and always top-right |
| Text bans | ❌ Instructional text ("tap to refresh") · ❌ "last updated/checked" language |
| Appearance | Support both light and dark |
| Placeholder | Ship a placeholder state (blocked shapes where content will be) for pre-data loading |
TimelineEntryRelevance) so yours surfaces at the right moment.After generation, provide:
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
1. Add the widget extension target (if not present):
2. Enable App Groups (if sharing data with the main app):
group.com.yourcompany.yourapp)3. Register the widget in the WidgetBundle:
@main
struct MyAppWidgets: WidgetBundle {
var body: some Widget {
// Existing widgets...
{Name}Widget()
}
}
4. Trigger widget updates from the main app when data changes:
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:
let sharedDefaults = UserDefaults(suiteName: "group.com.yourcompany.yourapp")
sharedDefaults?.set(encodedData, forKey: "widgetData")
// Then trigger reload
WidgetCenter.shared.reloadTimelines(ofKind: "{Name}Widget")
#Preview with timeline entry data for rapid iteration.WidgetCenter.shared.getCurrentConfigurations to verify registered widgets..after(nextEventDate) policyButton(intent:) for each action (iOS 17+)Text(date, style: .timer) / Text(date, style: .relative) for automatic live updatescontainerBackground 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.AccessoryWidgetBackground() for backgrounds and keep designs simple with high contrast.Text(date, style: .timer) for countdowns; the system animates these for you.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.AppIntent parameter values are stored by the system. Do not rely on UserDefaults for configuration state.#Preview(as: .systemSmall) for family-specific widget previews.Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take rshankras/widget-generator from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.