{"id":29536760,"url":"https://github.com/0xleif/appletkit","last_synced_at":"2026-05-15T21:38:23.006Z","repository":{"id":303706795,"uuid":"1016387553","full_name":"0xLeif/AppletKit","owner":"0xLeif","description":"🧱 The building blocks for your next great Swift app","archived":false,"fork":false,"pushed_at":"2025-07-09T01:37:01.000Z","size":47,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-09T02:40:36.350Z","etag":null,"topics":["apple","architecture","composable","ios","macos","modules","spm","swift","tvos","visionos","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0xLeif.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["0xLeif"]}},"created_at":"2025-07-09T00:12:55.000Z","updated_at":"2025-07-09T01:37:04.000Z","dependencies_parsed_at":"2025-07-09T02:52:32.945Z","dependency_job_id":null,"html_url":"https://github.com/0xLeif/AppletKit","commit_stats":null,"previous_names":["0xleif/appletkit"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/0xLeif/AppletKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FAppletKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FAppletKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FAppletKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FAppletKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0xLeif","download_url":"https://codeload.github.com/0xLeif/AppletKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FAppletKit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265562377,"owners_count":23788516,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apple","architecture","composable","ios","macos","modules","spm","swift","tvos","visionos","watchos"],"created_at":"2025-07-17T03:09:30.096Z","updated_at":"2026-05-15T21:38:22.956Z","avatar_url":"https://github.com/0xLeif.png","language":"Swift","funding_links":["https://github.com/sponsors/0xLeif"],"categories":[],"sub_categories":[],"readme":"# AppletKit: A Modular Architecture for Swift Applications\n\n**AppletKit is a template repository for building modern, modular, and scalable applications in Swift.**\n\nIt provides a flexible architecture where features are encapsulated into independent modules called **\"Applets.\"** These applets can be developed and tested in isolation but can also seamlessly communicate and share state with one another, creating a cohesive user experience.\n\nThis project is designed to be **forked**, providing a robust foundation for your next application.\n\n## The AppletKit Architecture\n\nAppletKit is built on a clean, layered architecture that promotes a clear separation of concerns. This makes your project easier to manage, scale, and maintain. The architecture can be understood in two key ways: the module dependency hierarchy and the data flow.\n\n### Module Dependency Hierarchy\n\nThe project is organized into layers, where higher-level modules depend on lower-level ones. This prevents circular dependencies and ensures a clear structure.\n\n  * **`AppletKit`** (The Host Application Shell)\n      * Depends on: **`Applets`** (e.g., `ExampleApplet`, `ExampleAppletInteroperability`)\n          * Depend on: **`Applet`** \u0026 **`AppletUI`** (Core Protocol \u0026 Shared UI)\n              * Depend on: **`AppletNavigation`** (Manages UI Flow \u0026 Routing)\n                  * Depends on: **`AppState`** (State Management Library)\n\n### Data Flow\n\nWhile modules depend on each other in one direction, data flows in a cycle, which keeps the state predictable:\n\n1.  **State**: A central store, managed by the `AppState` library, holds the application's state.\n2.  **Views**: Applets and other SwiftUI views read data from `AppState` to render the UI.\n3.  **Actions**: User interactions (like tapping a button) modify the properties exposed by `@AppState`.\n4.  **Update**: The change is sent back to the central `AppState` store, which updates its value and automatically notifies all subscribed views to re-render with the new information.\n\nThis approach decouples the state from the UI, allowing multiple independent applets to react to and modify the same shared data source without needing to know about each other.\n\n## How to Use AppletKit\n\nThis repository is a **template**. The best way to start is to create your own copy.\n\n**1. Fork this Repository**\nClick the \"Fork\" button to create a copy under your own GitHub account. Then, clone your forked repository to your local machine.\n\n```bash\ngit clone https://github.com/YOUR_USERNAME/AppletKit.git # Replace YOUR_USERNAME\n```\n\n**2. Open in Xcode**\nNavigate to the cloned directory and open the `Package.swift` file at the root of the project. Xcode will resolve all the local package dependencies automatically.\n\n**3. Run the Example**\nSelect a simulator or device and run the project. You will see the example application, which demonstrates two applets working together in a `TabView` and sharing state.\n\n## Building Your Application\n\nOnce you have the project running, you can start removing the example code and building your own app.\n\n### Two Ways to Use Your Applets\n\nAppletKit offers two primary ways to structure your application:\n\n#### 1\\. Use the Central `AppletKitView` Navigator\n\nThe default setup uses `AppletKitView` to host your applets in a `TabView`. This is ideal for apps where the main navigation is simple and known ahead of time. To customize this:\n\n  * Modify `Sources/AppletKit/AppletKit.swift` to use your preferred navigation container (e.g., `NavigationView`).\n  * Instantiate your own applets instead of the examples.\n\n#### 2\\. Use Applets Independently\n\nBecause each applet is a standalone Swift Package, you don't have to use `AppletKitView` at all. You can import your applets directly into any view in your existing application.\n\n```swift\nimport SwiftUI\nimport YourFirstApplet // Assuming you created this applet\nimport YourSecondApplet // And this one\n\nstruct MyCustomView: View {\n    var body: some View {\n        VStack {\n            // Instantiate your applets wherever you need them.\n            YourFirstApplet()\n            Divider()\n            YourSecondApplet()\n        }\n    }\n}\n```\n\nEven when used independently, applets can still communicate through their **Interface packages** and the shared `AppState` mechanism.\n\n### Creating Your First Applet\n\n1.  **Delete the Examples**: Remove the `Applets/ExampleApplet` and `Applets/ExampleAppletInteroperability` directories and update the root `Package.swift` dependencies.\n\n2.  **Create a New Swift Package**: In the `Applets/` directory, create a new Swift package for your feature.\n\n3.  **Define the Applet**: Create a struct that conforms to the `Applet` protocol.\n\n    ```swift\n    // In: Applets/YourNewApplet/Sources/YourNewApplet/YourNewApplet.swift\n    import Applet // Provides the Applet protocol\n\n    public struct YourNewApplet: Applet {\n        public let id: String = \"your.new.applet\"\n        public let title: String = \"My New Applet\"\n\n        public init() { } // Required by the Applet protocol\n\n        public var body: some View {\n            Text(\"Hello from My New Applet!\")\n        }\n    }\n    ```\n\n### Inter-Applet Communication with AppState\n\n1.  **Create an Interface Package (Recommended)**: In your applet's `Package.swift`, define a separate library target for the interface (e.g., `ExampleAppletInterface`). This avoids circular dependencies.\n\n2.  **Define Shared State**: In the interface package, define your `Codable`, `Equatable`, and `Sendable` state object.\n\n    ```swift\n    // In: Applets/YourNewApplet/Sources/YourNewAppletInterface/YourAppState.swift\n    import Foundation\n\n    public struct YourFeatureState: Codable, Equatable, Sendable {\n        public var someValue: String = \"Initial Value\"\n        public var counter: Int = 0\n    }\n    ```\n\n3.  **Register the State**: Extend the `Application` object from `AppState` to register your state with an initial value.\n\n    ```swift\n    // In: Applets/YourNewApplet/Sources/YourNewAppletInterface/Application+YourAppState.swift\n    import AppState\n    \n    extension Application {\n        public var yourFeatureState: State\u003cYourFeatureState\u003e {\n            state(initial: YourFeatureState())\n        }\n    }\n    ```\n\n4.  **Access Shared State**: In any SwiftUI view, use the `@AppState` property wrapper with the keypath you defined to read and write to the shared state.\n\n    ```swift\n    import AppletUI\n    import YourNewAppletInterface\n\n    struct InteractingAppletView: View {\n        @AppState(\\.yourFeatureState) private var YourFeatureState\n\n        public var body: some View {\n            VStack {\n                Text(\"Shared Counter: \\(yourFeatureState.counter)\")\n                Button(\"Increment\") {\n                    sharedCounter += 1\n                }\n            }\n        }\n    }\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xleif%2Fappletkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0xleif%2Fappletkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xleif%2Fappletkit/lists"}