{"id":51038890,"url":"https://github.com/logseq/bonsai-native","last_synced_at":"2026-06-24T11:00:30.257Z","repository":{"id":365717433,"uuid":"1272248315","full_name":"logseq/bonsai-native","owner":"logseq","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-18T14:20:35.000Z","size":136,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-23T10:27:17.786Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/logseq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2026-06-17T12:31:35.000Z","updated_at":"2026-06-23T02:16:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/logseq/bonsai-native","commit_stats":null,"previous_names":["logseq/bonsai-native"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/logseq/bonsai-native","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fbonsai-native","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fbonsai-native/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fbonsai-native/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fbonsai-native/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/logseq","download_url":"https://codeload.github.com/logseq/bonsai-native/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fbonsai-native/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34728928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":"2026-06-22T09:01:10.942Z","updated_at":"2026-06-24T11:00:30.239Z","avatar_url":"https://github.com/logseq.png","language":"OCaml","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bonsai-native\n\n`bonsai-native` is an OCaml native UI experiment for building iOS and Android\napps with the Bonsai programming model.\n\nThe app UI is authored in OCaml. Platform code is only the renderer bridge:\n\n```text\nBonsai component\n  -\u003e bonsai_native node tree\n  -\u003e platform renderer + event table\n  -\u003e Android JNI / iOS Camlkit\n  -\u003e Jetpack Compose / UIKit\n  -\u003e native app UI\n```\n\nThis is not a WebView and not a SwiftUI wrapper.\n\n## Packages\n\n- `bonsai_native`: shared OCaml node DSL, JSON/event bridge, and Bonsai driver\n  integration.\n- `bonsai_android`: Android facade over `bonsai_native`; rendered by Kotlin\n  Compose through JNI.\n- `bonsai_apple`: iOS/macOS-facing API and renderer abstractions; UIKit backend\n  lives under `apple/uikit`.\n\nBackend package names intentionally remain explicit. Existing Android code can\ncontinue to open `Bonsai_android`, and iOS code can continue to open\n`Bonsai_apple`.\n\n## OCaml UI Example\n\n```ocaml\nlet component graph =\n  let open Bonsai.Let_syntax in\n  let count, set_count = Bonsai.state 0 graph in\n  let%arr count and set_count in\n  Bonsai_android.vstack\n    [ Bonsai_android.text (Int.to_string count)\n    ; Bonsai_android.button \"Increment\" ~on_click:(set_count (count + 1))\n    ]\n```\n\nOn Android, Compose receives a native node tree JSON payload and sends event ids\nback to OCaml through JNI. OCaml owns the Bonsai driver and event table, so\nstate updates are still Bonsai effects.\n\n## Repository Layout\n\n- `native/`: shared `bonsai_native` implementation.\n- `src/`: Android OCaml facade.\n- `android/`: Gradle/Compose demo app.\n- `jni/`: Android JNI bridge into OCaml.\n- `apple/`: Apple OCaml package, UIKit backend, and iOS examples.\n- `examples/`: Android demo entrypoints and smoke examples.\n- `scripts/`: Android and iOS bootstrap/build helpers.\n- `docs/`: architecture and platform build notes.\n\n## Android Quick Check\n\nUse a switch with the Android cross compiler and Jane preview packages. The\ncurrent working path is documented in\n[docs/android-native-build.md](docs/android-native-build.md).\n\n```sh\nexport BONSAI_NATIVE_OPAM_SWITCH=/path/to/your/ocaml-android-switch\n\nscripts/build-android-native.sh\ncd android\nrtk proxy ./gradlew :app:assembleDebug\n```\n\nThe debug APK should contain:\n\n```text\nlib/arm64-v8a/libbonsai_android_counter.so\n```\n\nRun the emulator smoke test:\n\n```sh\nscripts/test-android-emulator.sh\n```\n\nIt installs the APK, launches the counter, taps `Increment`, and verifies the UI\nchanges from `0` to `1`. It also switches through the Android `Todo` and\n`Search` tabs, which mirror the current iOS demo tabs.\n\n## iOS Quick Check\n\nThe iOS package is under `apple/` and builds through Camlkit/opam-cross-ios\ncontexts. See [docs/apple-native-build.md](docs/apple-native-build.md).\n\nThe simulator app target is:\n\n```sh\nopam exec -- dune build apple/examples/BonsaiNativeDemos.app \\\n  --workspace dune-workspace.simulator\n```\n\n## Status\n\nWorking now:\n\n- Shared OCaml DSL for text, button, text fields, stacks, scroll views, keyed\n  lists, navigation stacks, images, custom views, and common modifiers.\n- Android JNI native library built with OCaml 5.2.1, Core, Bonsai, and\n  `bonsai.ppx_bonsai`.\n- Android Compose renderer loads real native OCaml state and dispatches clicks\n  back into Bonsai.\n- Android and iOS demo apps expose the same `Counter`, `Todo`, and `Search`\n  OCaml views.\n- Apple source/backend scaffolding is included in the same repo.\n\nStill early:\n\n- Android release-size optimization.\n- More complete iOS packaging automation.\n- AppKit backend.\n- Shared persistence/sync packages above the UI layer.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flogseq%2Fbonsai-native","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flogseq%2Fbonsai-native","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flogseq%2Fbonsai-native/lists"}