modules/BlueskyClip/README.md
An iOS App Clip implementation for Bluesky starter packs. App Clips are lightweight app experiences that allow users to preview and join Bluesky through starter packs without installing the full app.
BlueskyClip provides a minimal, on-demand iOS app experience for viewing and joining Bluesky starter packs. When a user encounters a starter pack link (e.g., bsky.app/start/... or go.bsky.app/...), iOS can present the App Clip instead of requiring a full app install. The App Clip:
The App Clip is a standalone iOS target with its own minimal Swift implementation:
User taps starter pack link
↓
iOS presents BlueskyClip App Clip
↓
WKWebView loads bsky.app with ?clip=true parameter
↓
Web app detects clip mode and sends actions via postMessage
↓
ViewController receives messages and:
- Presents App Store overlay (action: "present")
- Stores starter pack URI in shared UserDefaults (action: "store")
↓
User downloads main app
↓
Main app reads starterPackUri from shared UserDefaults
↓
Main app displays starter pack onboarding flow
URL Detection (isStarterPackUrl):
bsky.app/start/* and bsky.app/starter-pack/* paths (4 path components)go.bsky.app/* (2 path components)WebView Communication (WKScriptMessageHandler):
present: Shows the App Store overlay using SKOverlaystore: Writes JSON data to shared UserDefaults with the specified keyData Sharing:
group.app.bsky (App Group)starterPackUri - stores the starter pack URLSharedPrefs.getString('starterPackUri') (see src/components/hooks/useStarterPackEntry.native.ts)The App Clip target is automatically configured via Expo config plugins located in /plugins/starterPackAppClipExtension/:
modules/BlueskyClip/ to the iOS build directoryMain App (app.entitlements):
com.apple.security.application-groups: group.app.bskycom.apple.developer.associated-appclip-app-identifiers: Links to the App Clip bundle IDApp Clip (BlueskyClip.entitlements):
com.apple.security.application-groups: group.app.bsky (for data sharing)com.apple.developer.parent-application-identifiers: Links to the main app bundle IDcom.apple.developer.associated-domains: Inherits from main app config (for universal links)[main-app-bundle-id].AppClipcom.apple.product-type.application.on-demand-install-capableB3LX46C5HSThe main app detects App Clip-originated starter packs through useStarterPackEntry hook:
Native (src/components/hooks/useStarterPackEntry.native.ts):
starterPackUri from SharedPrefs (App Group)Web (src/components/hooks/useStarterPackEntry.ts):
?clip=true URL parameterisClip: true flagmodules/BlueskyClip/
├── AppDelegate.swift # App lifecycle and URL handling
├── ViewController.swift # WebView management and message handling
└── Images.xcassets/ # App Clip icon assets
├── AppIcon.appiconset/
│ ├── [email protected]
│ └── Contents.json
└── Contents.json
yarn prebuildyarn prebuild to take effect