RORK LABJP
TOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the roundTOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the round
Articles/App Dev
App Dev/2026-05-26Advanced

Bolting WidgetKit onto a Rork iOS App: Implementation Notes from Rolling It Out to Six Wallpaper Apps Simultaneously

A hands-on note on adding a WidgetKit Extension to a Rork-generated iOS app, with operational lessons from rolling out widgets to six wallpaper apps at once — App Group plumbing, Timeline Provider choices, memory ceilings, and ASO side effects.

Rork515WidgetKit10iOS109SwiftUI63App Group4Wallpaper3AppIntent

Premium Article

I'm Masaki Hirokawa, building iOS apps as a solo developer since 2014. I recently bolted WidgetKit-based widgets onto a set of wallpaper apps whose foundations were originally generated by Rork, and rolled them out to my existing lineup that has now passed 50 million cumulative downloads. Rork ships a React Native foundation quickly, but a Widget Extension cannot host a JavaScript runtime — so adding one after the fact means designing a small, self-contained native world that sits on top of the codebase Rork gave you.

These are the rollout notes from doing that across six wallpaper apps at once. I'll focus on the parts that tend to bite when widgets are added retroactively: Timeline Provider choices, App Group disk I/O, and the strict 30 MB memory ceiling for widgets.

Why I added widgets to Rork-based apps after the fact

The trigger was a small cluster of App Store reviews asking to "see today's wallpaper without opening the app." Until then, all wallpaper data lived in the Rork-generated React Native UI, so adding widgets meant drawing a new boundary between the JS layer and the native layer.

A second reason was ASO. App Store listings display a "Widgets" badge in screenshots once an app ships a widget, and searches for widget-related terms become more likely to surface the listing. In the two weeks after Beautiful HD Wallpapers shipped its widget update, impressions for the query "wallpaper widget" rose about 11% versus the prior two weeks. The absolute volume is modest, but when each app takes only about a day to a day and a half to retrofit, the math works out.

Operationally, widgets also let users "browse a little" without launching the app. That improved how often people came back to the wallpaper detail screen, which is harder to measure in numbers but visible in retention. Of the six apps, only the home-screen widget kept consistent weekly use; lock-screen widgets spiked briefly on release and then settled into a much smaller share of impressions.

App Group and shared storage — bridging Rork's JS layer to a native widget

A widget extension cannot execute JavaScript, so whatever the Rork-generated app stores via AsyncStorage or React state is invisible to the widget by default. The bridge is an App Group: a shared UserDefaults suite plus a shared container directory on disk.

In my setup, the main app exposes a thin native module that writes to the App Group from React Native via a bridge. The widget reads the same App Group suite directly.

// AppGroup.swift — included in BOTH the main app target and the widget extension
import Foundation
 
enum AppGroup {
    static let identifier = "group.net.dolice.wallpapers.shared"
 
    static var defaults: UserDefaults {
        guard let d = UserDefaults(suiteName: identifier) else {
            fatalError("App Group suite missing. Check Capabilities.")
        }
        return d
    }
 
    static var containerURL: URL {
        guard let url = FileManager.default.containerURL(
            forSecurityApplicationGroupIdentifier: identifier
        ) else {
            fatalError("App Group container unavailable. Check provisioning.")
        }
        return url
    }
}

Two pitfalls are worth flagging. First, the App Group identifier has to be enabled on the Signing & Capabilities tab of both the main app and the widget extension. Forgetting this on the widget target produces a release build whose widget is silently blank; the simulator can mask it, so I always re-verify on a TestFlight build.

Second, keep filenames in the shared container ASCII and short. I observed several intermittent failures on devices in low-power mode when filenames included localized characters or were unusually long. Today I store thumbnails as wallpaper-thumb.jpg, and any metadata goes into UserDefaults via Codable.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A minimum-viable recipe for adding a WidgetKit Extension to a Rork-generated React Native iOS project, without touching the JS layer
How I chose between three Timeline Provider patterns (static, timer-based, app-driven) when rolling widgets out to six wallpaper apps in parallel
Operational lessons on AppIntent-based configuration, App Group disk I/O, the 30 MB widget memory ceiling, and Lock Screen widget tradeoffs
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

App Dev2026-04-26
Building a Native iOS App with Rork — From SwiftUI Generation to TestFlight, Step by Step
Trying to ship a native iOS app with Rork but unsure how SwiftUI gets generated and built behind the scenes? Here's the actual workflow I run, end to end, with concrete examples.
Dev Tools2026-05-10
Why Your Rork iOS Widget Keeps Showing Stale Data — Rebuilding the App Group + WidgetKit Pipeline That Actually Refreshes
Your Rork-built iOS widget shows yesterday's data. Rebuild the App Group, shared UserDefaults, and timeline reload pipeline so parent and widget share state.
App Dev2026-07-01
Building SharePlay in Rork Max's Native Swift — Keeping Two Screens in the Same State
Implementation notes on building SharePlay with GroupActivities in Rork Max's native Swift — moving two screens through the same state over FaceTime. Covers declaring the GroupActivity, joining a GroupSession, syncing state with GroupSessionMessenger, handling latency and conflicts, catching up late joiners, and the boundary for bridging from React Native, with the pitfalls I actually hit.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →