{"id":28435131,"url":"https://github.com/skiptools/skip-fuse-ui","last_synced_at":"2026-04-15T00:05:28.859Z","repository":{"id":276700201,"uuid":"922617483","full_name":"skiptools/skip-fuse-ui","owner":"skiptools","description":"Native Swift package that bridges the SwiftUI API to Android via SkipUI","archived":false,"fork":false,"pushed_at":"2026-04-11T01:41:49.000Z","size":1538,"stargazers_count":16,"open_issues_count":9,"forks_count":12,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-04-11T03:25:14.394Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skiptools.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://skip.dev/sponsor"]}},"created_at":"2025-01-26T17:22:28.000Z","updated_at":"2026-04-11T01:41:56.000Z","dependencies_parsed_at":"2025-12-29T09:03:08.392Z","dependency_job_id":null,"html_url":"https://github.com/skiptools/skip-fuse-ui","commit_stats":null,"previous_names":["skiptools/skip-fuse-ui"],"tags_count":61,"template":false,"template_full_name":null,"purl":"pkg:github/skiptools/skip-fuse-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skiptools%2Fskip-fuse-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skiptools%2Fskip-fuse-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skiptools%2Fskip-fuse-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skiptools%2Fskip-fuse-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skiptools","download_url":"https://codeload.github.com/skiptools/skip-fuse-ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skiptools%2Fskip-fuse-ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31820370,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T18:05:02.291Z","status":"ssl_error","status_checked_at":"2026-04-14T18:05:01.765Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-06-05T20:06:40.635Z","updated_at":"2026-04-15T00:05:28.844Z","avatar_url":"https://github.com/skiptools.png","language":"Swift","funding_links":["https://skip.dev/sponsor"],"categories":[],"sub_categories":[],"readme":"# SkipFuseUI\n\nSkipFuseUI provides the SwiftUI API surface for [Skip Fuse](https://skip.dev/docs/modes/#fuse) apps on Android. It acts as a thin Swift bridging layer that delegates rendering to [SkipUI](https://skip.dev/docs/modules/skip-ui/), which implements SwiftUI views as Jetpack Compose composables. On iOS, `import SwiftUI` resolves to Apple's framework as usual; on Android, it resolves to SkipFuseUI, giving you a single SwiftUI codebase that runs natively on both platforms.\n\n## How It Works\n\nSkipFuseUI sits between your SwiftUI code and SkipUI's Compose implementation. Your Swift views are compiled natively for Android by the Swift Android SDK, and at render time each view produces a Kotlin-side SkipUI counterpart that Compose renders on screen.\n\n```mermaid\nflowchart LR\n    A[\"Your SwiftUI Code\"] --\u003e B[\"SkipFuseUI\\n(Swift on Android)\"]\n    B --\u003e|\"Java_view\"| C[\"SkipUI\\n(Kotlin/Compose)\"]\n    C --\u003e D[\"Jetpack Compose\\nUI on Screen\"]\n\n    style A fill:#555555,stroke:#333,color:#fff\n    style B fill:#6b3fa0,stroke:#4a2d6e,color:#fff\n    style C fill:#2e6da4,stroke:#1a4a6e,color:#fff\n    style D fill:#2d7a2d,stroke:#1a5c1a,color:#fff\n```\n\nThe key mechanism is the `SkipUIBridging` protocol. Every SkipFuseUI view type conforms to it by exposing a `Java_view` property that returns the equivalent SkipUI Kotlin object. When Compose needs to render your view hierarchy, it walks the tree of `Java_view` references — each one backed by [SkipBridge](https://skip.dev/docs/modules/skip-bridge/) JNI calls between Swift and Kotlin.\n\n### Module Relationships\n\n```mermaid\nflowchart TB\n    subgraph \"Your App\"\n        APP[\"App SwiftUI Code\"]\n    end\n\n    subgraph \"SkipFuseUI Package\"\n        SFUI[\"SkipFuseUI\\n(re-exports SwiftUI\\non Android)\"]\n        SSU[\"SkipSwiftUI\\n(Swift view types,\\nproperty wrappers,\\nmodifiers)\"]\n    end\n\n    subgraph \"Bridging Infrastructure\"\n        SB[\"SkipBridge\\n(JNI object lifecycle,\\ntype conversion)\"]\n        SF[\"SkipFuse\\n(@Observable,\\nOSLog, bridging\\nsupport)\"]\n        SAB[\"SkipAndroidBridge\\n(Android-specific\\nJNI helpers)\"]\n        SJNI[\"SwiftJNI\\n(low-level JNI\\nC/Swift wrapper)\"]\n    end\n\n    subgraph \"Compose Implementation\"\n        SUI[\"SkipUI\\n(SwiftUI → Jetpack\\nCompose mapping)\"]\n        SM[\"SkipModel\\n(Compose state\\ntracking)\"]\n    end\n\n    APP --\u003e SFUI\n    SFUI --\u003e SSU\n    SSU --\u003e SB\n    SSU --\u003e SF\n    SSU --\u003e SUI\n    SB --\u003e SAB\n    SB --\u003e SJNI\n    SUI --\u003e SM\n\n    style APP fill:#555555,stroke:#333,color:#fff\n    style SFUI fill:#6b3fa0,stroke:#4a2d6e,color:#fff\n    style SSU fill:#6b3fa0,stroke:#4a2d6e,color:#fff\n    style SB fill:#b33030,stroke:#8a1a1a,color:#fff\n    style SF fill:#b33030,stroke:#8a1a1a,color:#fff\n    style SAB fill:#b33030,stroke:#8a1a1a,color:#fff\n    style SJNI fill:#b33030,stroke:#8a1a1a,color:#fff\n    style SUI fill:#2e6da4,stroke:#1a4a6e,color:#fff\n    style SM fill:#2e6da4,stroke:#1a4a6e,color:#fff\n```\n\nOn iOS, `SkipFuseUI` simply re-exports Apple's `SwiftUI` — the entire SkipSwiftUI layer is compiled away.\n\n### Bridging Pattern\n\nEvery SwiftUI type in SkipFuseUI follows the same pattern: a Swift struct or class holds the view's parameters, and its `Java_view` property constructs the Kotlin equivalent on demand.\n\n```mermaid\nsequenceDiagram\n    participant App as Your View (Swift)\n    participant Fuse as SkipFuseUI VStack (Swift)\n    participant Bridge as SkipBridge (JNI)\n    participant UI as SkipUI VStack (Kotlin)\n    participant Compose as Jetpack Compose\n\n    App-\u003e\u003eFuse: VStack { Text(\"Hello\") }\n    Note over Fuse: Stores alignment,\u003cbr/\u003espacing, content\n    Compose-\u003e\u003eFuse: Request Java_view\n    Fuse-\u003e\u003eBridge: Create SkipUI.VStack\u003cbr/\u003ewith bridged content\n    Bridge-\u003e\u003eUI: JNI call → Kotlin object\n    UI-\u003e\u003eCompose: Emit Column composable\n```\n\nContent views are recursively bridged via `Java_viewOrEmpty`, which walks the view tree and converts each Swift view into its Kotlin counterpart.\n\n### State Bridging\n\nSwiftUI property wrappers (`@State`, `@Binding`, `@AppStorage`) are backed by bridge-aware box types that synchronize values between Swift and Compose's reactive state system:\n\n```mermaid\nflowchart LR\n    S[\"@State var count = 0\\n(Swift)\"] --\u003e|\"BridgedStateBox\"| K[\"StateSupport\\n(Kotlin/Compose)\"]\n    K --\u003e|\"MutableState\"| C[\"Compose\\nRecomposition\"]\n    C --\u003e|\"read triggers\\naccess()\"| S\n\n    style S fill:#6b3fa0,stroke:#4a2d6e,color:#fff\n    style K fill:#2e6da4,stroke:#1a4a6e,color:#fff\n    style C fill:#2d7a2d,stroke:#1a5c1a,color:#fff\n```\n\nWhen Swift code writes to a `@State` property, the `BridgedStateBox` notifies Compose's `MutableState`, triggering recomposition. When Compose reads the value, it calls back into Swift via the bridge. This two-way sync ensures that SwiftUI's declarative state model works identically on Android.\n\n`@Observable` types require `import SkipFuse` to enable this state tracking. See the [App Development](https://skip.dev/docs/app-development/#ui) guide for details.\n\n## What SkipFuseUI Covers\n\nSkipFuseUI mirrors the SwiftUI API surface for iOS 16+, including:\n\n- **Containers**: `VStack`, `HStack`, `ZStack`, `List`, `ScrollView`, `LazyVGrid`, `LazyHGrid`, `NavigationStack`, `TabView`, `Form`, `Section`, `Group`\n- **Controls**: `Button`, `Toggle`, `Slider`, `Stepper`, `Picker`, `DatePicker`, `TextField`, `SecureField`, `TextEditor`\n- **Components**: `Text`, `Image`, `AsyncImage`, `Label`, `Link`, `ProgressView`, `Divider`, `ShareLink`\n- **Graphics**: `Color`, `Gradient`, `Shape` (Circle, Rectangle, Capsule, etc.), `Path`, `Material`\n- **Layout**: `GeometryReader`, `Alignment`, `EdgeInsets`, `ViewThatFits`, `Grid`\n- **State**: `@State`, `@Binding`, `@Environment`, `@AppStorage`, `@FocusState`\n- **Modifiers**: `.padding`, `.frame`, `.background`, `.overlay`, `.opacity`, `.rotation`, `.shadow`, `.clipShape`, `.sheet`, `.alert`, `.onAppear`, `.task`, and many more\n- **Navigation**: `NavigationStack`, `NavigationLink`, `NavigationPath`, `.navigationTitle`, `.toolbar`\n- **Gestures**: `TapGesture`, `LongPressGesture`, `DragGesture`\n- **Animation**: `withAnimation`, `.animation`, `.transition`, `Spring`\n- **UIKit compatibility**: `UIApplication`, `UIColor`, `UIImage`, `UIPasteboard`\n\nFor the full list of supported SwiftUI components, see the [SkipUI documentation](https://skip.dev/docs/modules/skip-ui/#supported-swiftui).\n\n## Related Documentation\n\n- [App Development](https://skip.dev/docs/app-development/) — Building dual-platform apps with Skip, including UI and view model coding\n- [Skip Modes](https://skip.dev/docs/modes/) — Fuse vs. Lite mode and when to use each\n- [Bridging Reference](https://skip.dev/docs/bridging/) — Supported Swift language features and types for bridging\n- [Cross-Platform Topics](https://skip.dev/docs/platformcustomization/) — Integrating platform-specific code with `#if SKIP` and `#if os(Android)`\n- [SkipUI Module](https://skip.dev/docs/modules/skip-ui/) — Supported SwiftUI components and Compose integration topics\n- [SkipBridge Module](https://skip.dev/docs/modules/skip-bridge/) — The JNI bridging infrastructure that SkipFuseUI depends on\n- [SkipFuse Module](https://skip.dev/docs/modules/skip-fuse/) — Observable state tracking and Android runtime support\n\n## License\n\nThis software is licensed under the\n[Mozilla Public License 2.0](https://www.mozilla.org/MPL/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskiptools%2Fskip-fuse-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskiptools%2Fskip-fuse-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskiptools%2Fskip-fuse-ui/lists"}