Overview
The_shared directory pattern allows you to link files to multiple targets simultaneously. This is essential when files need to be compiled into both your main app and one or more extensions.
Why Shared Files?
Some scenarios require the same source file to be included in multiple targets:- Control Widgets with
openAppWhenRun = trueneed intent files in both the widget and main app - App Groups data models shared between the app and extensions
- Utility functions used across multiple targets
- SwiftUI components reused in widgets and the main app
Directory Structure
There are two types of_shared directories:
Target-Specific Shared Files
Place a_shared directory inside any target to share files between that target and the main app:
Global Shared Files
Place a_shared directory at the root of /targets to share files across ALL targets:
Example: Control Widgets
Control widgets withopenAppWhenRun = true require their intent definitions in both targets. Here’s the complete pattern:
Directory Structure
Directory Structure
Intent File (intents.swift)
Intent File (intents.swift)
Widget Bundle File
Widget Bundle File
You must manually add the control widgets to your WidgetBundle:
Example: Shared Data Models
Share App Group data structures between your app and widget:How Linking Works
Xcode Project Structure
Xcode Project Structure
When you run Each file shows multiple target checkboxes enabled in the File Inspector.
npx expo prebuild, the plugin:- Scans all
_shareddirectories - Creates file references in the Xcode project
- Adds those references to multiple target memberships
- Maintains the files outside the
/iosdirectory
Build Phase Integration
Build Phase Integration
Shared files are automatically added to the “Compile Sources” build phase of each target they’re linked to. No manual configuration needed.
When to Prebuild
You must runnpx expo prebuild --clean after:
Changing the content of existing shared files does NOT require prebuild—Xcode tracks the files and picks up changes automatically.
File Type Support
The_shared directory supports any file type Xcode recognizes:
- Swift source files (
.swift) - Objective-C files (
.m,.h) - SwiftUI views
- Data models
- Metal shaders (
.metal) - Asset catalogs (
.xcassets) - though these should typically go in target-specific locations
Limitations
No Runtime Linking
Shared files create independent copies at build time. Changes in one target’s compiled code don’t affect the other:- App Groups with
UserDefaultsor file containers - CloudKit for cloud-synced data
- Core Data with shared app group containers
Namespace Collisions
If multiple_shared directories define the same type, you’ll get build errors:
Best Practices
- Keep shared code minimal - Only share what’s absolutely necessary
- Use descriptive names -
WidgetIntents.swiftis clearer thanintents.swift - Document dependencies - Add comments explaining why files are shared
- Prefer target-specific - Use global
_sharedsparingly - Watch file count - Many shared files can slow prebuild
Next Steps
- Learn about JavaScript bundling with exportJs
- Configure CocoaPods for React Native targets
- Set up App Groups for data sharing