WidgetKit is an Apple framework introduced in iOS 14 that allows developers to place dynamic widgets on the iPhone and iPad home screen, Mac desktop, and Apple Watch face. Widgets display key information without opening the app — weather forecast, exchange rates, calendar, steps. According to Apple Developer Documentation, 2026, WidgetKit processes up to 2 billion widget updates daily in the Apple ecosystem, making it one of the most used frameworks for displaying information on system screens.
Key Takeaways
WidgetKit is an Apple framework for creating widgets that display content on Apple devices’ system screens. A widget is a miniature representation of your app that the user places on the home screen in jiggle mode. Unlike watchOS complications that existed before WidgetKit, the new framework unified widget creation for all Apple platforms through a single SwiftUI API.
The WidgetKit operating principle is based on TimelineProvider — an object that creates an ordered array of TimelineEntry, where each entry contains a Snapshot (a specific widget state at a given point in time). The system displays entries sequentially, updating the widget when moving to the next entry on the timeline. Between entries, WidgetKit does not call app code — CPU time is only spent when creating a new Timeline.
According to WWDC 2024 Session “WidgetKit: What’s new”, the average iOS user has 8–12 widgets on their home screen, with the most popular categories being weather, time, calendar, fitness, and finance. WidgetKit consumes less than 1% of battery charge per day under typical usage thanks to scheduled updates rather than real-time updates.
Before iOS 14, widgets only existed as Today View — a panel accessible by swiping left from the first screen. Today Extensions had serious limitations: they were only available on the “Today” screen, required opening the app to update content, and had limited size support. WidgetKit completely replaced Today Extensions, providing widgets on the home screen, lock screen (iOS 16+), and Mac desktop.
WidgetKit architecture is built on three key protocols: TimelineProvider, TimelineEntry, and Widget. TimelineEntry is a data model representing the widget state at a specific point in time. TimelineProvider creates an array of such entries (Timeline), specifying the activation date for each. Widget is the entry point that connects the provider to the SwiftUI view.
The Timeline method getTimeline is called by the system when the widget is first added and then periodically — usually every 1–6 hours depending on the provider type. A Timeline can contain entries for hours or days ahead, allowing the widget to work without calling app code between updates. If an urgent widget update is needed (e.g., exchange rate changed), the app can call WidgetCenter.shared.reloadAllTimelines() forcibly.
struct SimpleEntry: TimelineEntry {
let date: Date
let value: Double
}
struct Provider: TimelineProvider {
typealias Entry = SimpleEntry
func placeholder(in context: Context) -> Entry {
Entry(date: Date(), value: 0)
}
func getSnapshot(
in context: Context,
completion: @escaping (Entry) -> Void
) {
Entry(date: Date(), value: 42.5)
}
func getTimeline(
in context: Context,
completion: @escaping (Timeline<Entry>, Error?) -> Void
) {
let entry = Entry(date: Date(), value: fetchLatestValue())
let nextUpdate = Calendar.current
.date(byAdding: .hour, value: 1, to: Date())!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline, nil)
}
}
WidgetKit supports three widget sizes, each with fixed proportions. Small (170×170 pt on iPhone) displays compact information — a single value, icon, or short text. Medium (364×170 pt) is twice as wide as small and is suitable for displaying pairs of values or mini-charts. Large (364×382 pt) takes almost half the screen vertically and can display tables, lists, or expanded data.
The developer must support at least two sizes — Apple recommends small + medium. Large widget is only required if the app has enough content to fill that volume. Each size gets its own SwiftUI View, which WidgetKit renders on the system screen. Importantly, WidgetKit does not support custom sizes — only three fixed sizes, ensuring interface consistency.
struct WeatherWidget: Widget {
let kind: String = "WeatherWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WeatherWidgetView(entry: entry)
}
.configurationDisplayName("Weather")
.description("Current temperature and forecast")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
WidgetKit offers two configuration types — StaticConfiguration and IntentConfiguration. StaticConfiguration is suitable for widgets that display the same content for all users: exchange rates, weather, calendar. IntentConfiguration allows the user to customize the widget when adding it through the Siri intents system — for example, selecting a specific city for weather or a specific ticker for stock prices.
IntentConfiguration uses INWidgetIntent — a subclass of INIntent from SiriKit. When the user adds a widget and selects parameters (e.g., city), the system saves this intent and passes it to TimelineProvider on each update. The provider receives the intent in the getTimeline method and uses its parameters to form the content. IntentConfiguration is the preferred approach for personalized widgets as it integrates with Siri and Shortcuts.
struct WeatherWidgetEntryView: View {
var entry: WeatherEntry
var body: some View {
VStack(alignment: .leading) {
Text(entry.cityName)
.font(.caption)
.foregroundColor(.secondary)
Text("\(entry.temperature)°C")
.font(.largeTitle)
}
}
}
struct WeatherWidget: Widget {
var body: some WidgetConfiguration {
IntentConfiguration(
kind: "WeatherWidget",
intent: WeatherConfigIntent.self,
provider: WeatherTimelineProvider()
) { entry in
WeatherWidgetEntryView(entry: entry)
}
}
}
Creating a widget starts with adding a Widget Extension Target in Xcode: File → New → Target → Widget Extension. Xcode automatically generates a structure with TimelineEntry, TimelineProvider, and WidgetConfiguration. The developer only needs to implement the SwiftUI View for displaying data and configure the provider for a correct update schedule.
Below is a complete example of a simple widget for displaying the current Bitcoin price: Provider loads the rate via URLSession and creates a Timeline with hourly updates. WidgetSwiftUIView displays the rate in large font and the last update time in small font.
struct BTCPriceEntry: TimelineEntry {
let date: Date
let price: Double
let change24h: Double
}
struct BTCWidgetEntryView: View {
var entry: BTCPriceEntry
var body: some View {
VStack {
Text("BTC/USD").font(.caption)
Text("$\(entry.price, specifier: "%.0f")")
.font(.title2).fontWeight(.bold)
Text(entry.change24h > 0 ? "+" : "")
}
}
}
With iOS 16, WidgetKit extended support to the Lock Screen — the iPhone lock screen. Lock Screen widgets come in two types: inline (a single line of text below the clock) and rectangular (a rectangular area). Unlike Home Screen widgets, Lock Screen widgets update more frequently — the system trigger allows updates every 15–30 minutes to display current information without unlocking the phone.
Lock Screen widgets require separate configuration via WidgetConfiguration with accessoryFamilies: accessoryCircular, accessoryRectangular, accessoryInline. These families have strict size and content limitations — they do not support images, animation, or custom fonts. Apple recommends using only text information and SF Symbols system icons for Lock Screen widgets.
When developing widgets, it is important to consider the limitations of WidgetKit. Widgets are read-only views: they do not handle touch events (except for a tap that opens the app). Widgets do not support animation, video, keyboard input, scrolling, or interactive elements. Each widget is a static snapshot of data at a given point in time, and attempting to add interactivity will result in app rejection from the App Store.
Best practices include using Widget Center for forced updates, caching data at the TimelineProvider level for quick response, and using placeholders for the initial state. It is also important to support multiple sizes — users expect the widget to be available in both small and medium variants. Religiously avoid displaying inaccurate or outdated data — users remember incorrect information from widgets for a long time.
| What is Not Allowed | Why |
|---|---|
| Animation and Video | Widgets are static snapshots; animation drains battery |
| Interactivity | WidgetKit does not support UI elements except app links |
| Scrolling | Fixed size without scrolling |
| Keyboard | Text input in widgets is not possible |
| Live Data | Data updates on a Timeline schedule, not in real time |
| Custom Sizes | Only small, medium, large, accessory* fixed sizes |
Frequently Asked Questions
Yes, WidgetKit is cross-platform. The same Widget Extension can be included in iOS, iPadOS, and macOS targets with a single SwiftUI codebase. Differences only appear in supported Families — Mac does not have accessoryRectangular.
According to the Timeline schedule. The developer determines when the next update will occur — in a minute or a day. The system can also accelerate updates for frequently used widgets.
No, WidgetKit does not support UIButton or any interactive elements. The only action is a tap on the widget, which opens the app via deep link.
Use WidgetCenter.shared.reloadAllTimelines() or reloadTimelines(ofKind:) for a specific widget. The call from the app immediately requests a new Timeline from the provider.
Minimally — less than 1% charge per day under typical usage. WidgetKit limits background updates and does not keep the app active. The main cost is creating the Timeline on first addition.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also