widgets

A guide for building Apple home-screen and in-app widgets with WidgetKit, Apple’s framework for small views that show changing information.

In plain words
What is it for?
Use it when adding widget extensions, defining the data shown at each update, supplying update schedules, and creating views for different widget sizes.
Why use it?
It explains the separate files and data-sharing setup widgets need so they can work alongside the main app.

Skill for Claude CodeCodex

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add skills/abdullah4ai/apple-developer-toolkit/widgets
Any agent
npx skills add Abdullah4AI/apple-developer-toolkit --skill widgets
Clone the repo
git clone --depth 1 https://github.com/Abdullah4AI/apple-developer-toolkit

Made for: Claude Code, Codex.

Per session 30 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 911 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00030 $0.00911
Opus 5 $0.00015 $0.00456
Sonnet 5 $0.00006 $0.00182
Haiku 4.5 $0.00003 $0.00091

Measured 2d ago against content hash 3b62cb180523, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

widgets scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

swiftship/internal/skills/data/extensions/widgets/SKILL.md · 89 lines

What it actually says

Widgets

WIDGETS (WidgetKit): FRAMEWORK: import WidgetKit

SETUP:

  • Requires separate widget extension target (kind: "widget" in plan extensions array)
  • Use AppGroup for data sharing between app and widget (auto-configured in project.yml)
  • Widget code goes in Targets/{WidgetName}/ directory

TIMELINE ENTRY (data for a single widget render): struct MyEntry: TimelineEntry { let date: Date let title: String let value: Double }

TIMELINE PROVIDER (supplies entries to the system): struct MyProvider: TimelineProvider { func placeholder(in context: Context) -> MyEntry { MyEntry(date: .now, title: "Placeholder", value: 0) } func getSnapshot(in context: Context, completion: @escaping (MyEntry) -> Void) { completion(MyEntry(date: .now, title: "Snapshot", value: 42)) } func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { let entry = MyEntry(date: .now, title: "Current", value: 42) let timeline = Timeline(entries: [entry], policy: .after(.now.addingTimeInterval(3600))) completion(timeline) } }

WIDGET VIEW: struct MyWidgetView: View { var entry: MyProvider.Entry @Environment(.widgetFamily) var family var body: some View { switch family { case .systemSmall: VStack { Text(entry.title).font(AppTheme.Fonts.headline); Text("(Int(entry.value))").font(AppTheme.Fonts.largeTitle) } case .systemMedium: HStack { VStack(alignment: .leading) { Text(entry.title); Text("(Int(entry.value))").font(AppTheme.Fonts.title) }; Spacer() } default: Text(entry.title) } } }

WIDGET DEFINITION: struct MyWidget: Widget { let kind: String = "MyWidget" var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: MyProvider()) { entry in MyWidgetView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) // REQUIRED iOS 17+ } .configurationDisplayName("My Widget") .description("Shows current status") .supportedFamilies([.systemSmall, .systemMedium]) } }

WIDGET BUNDLE (when multiple widgets exist): @main struct MyWidgetBundle: WidgetBundle { var body: some Widget { MyWidget() AnotherWidget() } }

MANDATORY FILES (every widget extension MUST have ALL of these):

  1. {Name}Bundle.swift — @main WidgetBundle entry point. Without this, the extension has no entry point → linker error "undefined symbol: _main" → CodeSign failure.
  2. Provider.swift — TimelineProvider implementation.
  3. WidgetView.swift — The widget's SwiftUI view.
  4. (Optional) Intent.swift — AppIntent for interactive widgets (tap-to-complete, etc.).

CRITICAL RULES:

  • .containerBackground(.fill.tertiary, for: .widget) is REQUIRED on the widget view in iOS 17+. Without it, the widget renders with no background.
  • The @main entry point is MANDATORY. Use @main on WidgetBundle (multiple widgets) or Widget (single widget). An extension target with NO @main will fail to link.
  • Shared data types between app and widget go in the Shared/ directory at the project root (both targets compile it). NEVER define shared types only in the main app's Models/ — the widget extension cannot see them.
  • Widget views must be self-contained — they cannot use @StateObject, @ObservedObject, or network calls. All data comes through the TimelineEntry.
  • Use .supportedFamilies() to declare which sizes the widget supports.
  • AppIntent static properties MUST use "static let" (not "static var") for Swift 6 concurrency safety. Using "static var" causes "not concurrency-safe because it is nonisolated global shared mutable state" error.
Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 89 lines · 30 tokens per session scan A 3b62cb180523

Subscribe to this mod's changes

widgets is a skill published in the GitHub repository Abdullah4AI/apple-developer-toolkit (10 stars, last pushed 4d ago), licensed MIT. It adds 30 tokens to every session and 911 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

Other skills, from other repositories

systematic-debugging

Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes.

obra/superpowers · 21 tokens

next-cache-components-adoption

Turn on Cache Components in a Next.js app and resolve the blocking routes it surfaces. Use when the user wants to enable, adopt, or migrate to Cache Components, flip the cacheComponents flag, work through a flood of blocking-prerender / instant validation errors, run the cache-components-instant-false codemod, or…

vercel/next.js · 95 tokens

babysit-pr

Babysit a GitHub pull request after creation by continuously polling review comments, CI checks/workflow runs, and mergeability state until the PR is merged/closed or user help is required. Diagnose failures, retry likely flaky failures up to 3 times, auto-fix/push branch-related issues when appropriate, and keep…

openai/codex · 114 tokens

imagegen

Generate or edit raster images when the task benefits from AI-created bitmap visuals such as photos, illustrations, textures, sprites, mockups, or transparent-background cutouts. Use when Codex should create a brand-new image, transform an existing image, or derive visual variants from references, and the output…

openai/codex · 113 tokens

cpu-profile-analysis

Analyze V8/Chrome CPU profiles (.cpuprofile) and DevTools trace files (Trace-.json). Use when: profiling performance, investigating slow functions, comparing code paths, finding bottlenecks, analyzing timeToRequest, understanding call trees from sampling profiler data, analyzing layout/paint/rendering, investigating…

microsoft/vscode · 71 tokens

next-cache-components-optimizer

Drive a Next.js route to instant navigation by setting up an agentic loop, under Cache Components / PPR, on initial load (hard navigation) and client-side navigation (soft navigation). Encode the goal as a failing @next/playwright instant() e2e and work it to green, one verified route at a time; the shipped test then…

vercel/next.js · 170 tokens