{"id":50145389,"url":"https://github.com/ohhi-vn/dala","last_synced_at":"2026-05-24T04:01:41.482Z","repository":{"id":352132110,"uuid":"1204463222","full_name":"ohhi-vn/dala","owner":"ohhi-vn","description":"Dala - Mobile framework for Elixir","archived":false,"fork":false,"pushed_at":"2026-05-18T00:48:52.000Z","size":22977,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-18T02:45:06.903Z","etag":null,"topics":["dala","mobile-framework"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"GenericJam/mob","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ohhi-vn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-08T03:09:23.000Z","updated_at":"2026-05-18T02:14:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ohhi-vn/dala","commit_stats":null,"previous_names":["manhvu/mob","manhvu/dala","ohhi-vn/dala"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/ohhi-vn/dala","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohhi-vn%2Fdala","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohhi-vn%2Fdala/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohhi-vn%2Fdala/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohhi-vn%2Fdala/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ohhi-vn","download_url":"https://codeload.github.com/ohhi-vn/dala/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohhi-vn%2Fdala/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33420660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T22:14:44.296Z","status":"online","status_checked_at":"2026-05-24T02:00:06.296Z","response_time":57,"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":["dala","mobile-framework"],"created_at":"2026-05-24T04:01:37.102Z","updated_at":"2026-05-24T04:01:41.475Z","avatar_url":"https://github.com/ohhi-vn.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Hex.pm](https://img.shields.io/hexpm/v/dala.svg)](https://hex.pm/packages/dala)\n[![Docs](https://img.shields.io/badge/docs-hexdocs-blue.svg)](https://hexdocs.pm/dala)\n\n\u003e **Status:** Early development. Not yet ready for production use.\n\n# Dala\n\nDala is a native mobile framework for Elixir powered by the BEAM VM.\n\nIt brings OTP, lightweight processes, fault tolerance, and the actor model to iOS and Android development while using a Rust-powered native runtime for rendering and platform integration.\n\nUnlike WebView-based frameworks, Dala focuses on native execution, concurrent application architecture, and local-first intelligent applications.\n\n## Why Dala?\n\nModern mobile applications are becoming increasingly complex:\n\n- AI/ML pipelines running on-device\n- realtime synchronization\n- local-first data systems\n- streaming workloads\n- background processing\n- highly concurrent state management\n\nThese problems look more like distributed systems than traditional frontend applications.\n\nDala uses the strengths of the BEAM ecosystem to solve them naturally.\n\n## Features\n\n- Native iOS and Android runtime\n- Real BEAM VM on mobile devices\n- OTP and actor-model concurrency\n- Rust-powered rendering and native integrations\n- Declarative UI API\n- Designed for local-first and AI-powered applications\n- High-concurrency architecture\n- Binary protocol bridge for low-overhead communication\n- Future-focused AOT experimentation inspired by HiPE concepts\n\n## Architecture\n\n```text\nElixir/Erlang\n        ↓\n     BEAM VM\n        ↓\nRust Native Runtime\n        ↓\niOS / Android\n```\n\nDala keeps the BEAM runtime as the core execution engine while using Rust for performance-critical systems such as rendering, layout, native APIs, and ML integrations.\n\n## Vision\n\nDala is not trying to be another web wrapper for mobile apps.\n\nThe goal is to build an OTP-native runtime for modern mobile applications — especially apps that require:\n\n- concurrency\n- realtime coordination\n- offline-first architecture\n- resilient background systems\n- on-device AI/ML\n- complex local data flows\n\n## Status\n\nDala is experimental and evolving rapidly.\n\n## Installation\n\nAdd to `mix.exs`:\n\n```elixir\ndef deps do\n  [{:dala, \"~\u003e 0.1.0\"}]\nend\n```\n\nThe `dala_new` package (separate) provides project generation, deployment tooling, and will import `dala_dev` which is a live dashboard. Install it as a Mix archive:\n\n```bash\nmix archive.install hex dala_new\n```\n\n## A screen (Spark DSL - Recommended)\n\n```elixir\ndefmodule MyApp.CounterScreen do\n  use Dala.Spark.Dsl\n\n  attributes do\n    attribute :count, :integer, default: 0\n  end\n\n  screen name: :counter do\n    column do\n      gap :space_sm\n      text \"Count: @count\", text_size: :xl\n      button \"Increment\", on_tap: :increment\n    end\n  end\n\n  def handle_event(:increment, _params, socket) do\n    {:noreply, Dala.Socket.assign(socket, :count, socket.assigns.count + 1)}\n  end\nend\n```\n\n## A screen (Traditional - Alternative)\n\n```elixir\ndefmodule MyApp.CounterScreen do\n  use Dala.Screen\n\n  def mount(_params, _session, socket) do\n    {:ok, Dala.Socket.assign(socket, :count, 0)}\n  end\n\n  def render(assigns) do\n    %{\n      type: :column,\n      props: %{padding: :space_md, gap: :space_md, background: :background},\n      children: [\n        %{type: :text,   props: %{text: \"Count: #{assigns.count}\", text_size: :xl, text_color: :on_background}, children: []},\n        %{type: :button, props: %{text: \"Increment\", on_tap: {self(), :increment}}, children: []}\n      ]\n    }\n  end\n\n  def handle_event(\"tap\", %{\"tag\" =\u003e \"increment\"}, socket) do\n    {:noreply, Dala.Socket.assign(socket, :count, socket.assigns.count + 1)}\n  end\nend\n```\n\n## App entry point\n\n```elixir\ndefmodule MyApp do\n  use Dala.App, theme: Dala.Theme.Obsidian\n\n  def navigation(_platform) do\n    screens([MyApp.CounterScreen])\n    stack(:home, root: MyApp.CounterScreen)\n  end\n\n  def on_start do\n    {:ok, _pid} = Dala.Screen.start_root(MyApp.CounterScreen)\n    cookie = Dala.Connectivity.Dist.cookie_from_env(\"MY_APP_DIST_COOKIE\", \"my_app\")\n    Dala.Connectivity.Dist.ensure_started(node: :\"my_app@127.0.0.1\", cookie: cookie)\n  end\nend\n```\n\n## Navigation\n\n```elixir\n# Push a new screen\nDala.Socket.push_screen(socket, MyApp.DetailScreen, %{id: 42})\n\n# Pop back\nDala.Socket.pop_screen(socket)\n\n# Tab bar layout\ntab_bar([\n  stack(:home,    root: MyApp.HomeScreen,    title: \"Home\"),\n  stack(:profile, root: MyApp.ProfileScreen, title: \"Profile\")\n])\n```\n\n## Theming\n\n```elixir\n# Named theme\nuse Dala.App, theme: Dala.Theme.Obsidian\n\n# Override individual tokens\nuse Dala.App, theme: {Dala.Theme.Obsidian, primary: :rose_500}\n\n# From scratch\nuse Dala.App, theme: [primary: :emerald_500, background: :gray_950]\n\n# Runtime switch (accessibility, user preference)\nDala.Theme.set(Dala.Theme.Citrus)\n```\n\nBuilt-in themes: `Dala.Theme.Obsidian` (dark violet), `Dala.Theme.Citrus` (warm charcoal + lime), `Dala.Theme.Birch` (warm parchment).\n\n## Device APIs\n\nAll async — call the function, handle the result in `handle_info/2`:\n\n```elixir\n# Haptic feedback (synchronous — no handle_info needed)\nDala.Hardware.Haptic.trigger(socket, :success)\n\n# Camera\nDala.Media.Camera.capture_photo(socket)\ndef handle_info({:camera, :photo, %{path: path}}, socket), do: ...\n\n# Location\nDala.Platform.Location.start(socket, accuracy: :high)\ndef handle_info({:location, %{lat: lat, lon: lon}}, socket), do: ...\n\n# Push notifications\nDala.Platform.Notify.register_push(socket)\ndef handle_info({:push_token, :ios, token}, socket), do: ...\n```\n\nAlso: `Dala.Platform.Clipboard`, `Dala.Platform.Share`, `Dala.Media.Photos`,\n`Dala.Storage.Files`, `Dala.Media.Audio`, `Dala.Ui.Sensor.Motion`,\n`Dala.Hardware.Biometric`, `Dala.Hardware.Scanner`, `Dala.Hardware.NFC`,\n`Dala.Ui.Scan`, `Dala.Permissions`.\n\nAdditional APIs: `Dala.Hardware.Bluetooth` (BLE), `Dala.Connectivity.Wifi`, `Dala.Wakelock`,\n`Dala.Storage.Storage`, `Dala.Storage.Blob`, `Dala.Platform.Settings`, `Dala.Platform.State`,\n`Dala.Platform.Linking`, `Dala.Platform.Background`, `Dala.Ui.Feedback.Alert`, `Dala.Ui.Embedded.Webview`.\n\n## Live development\n\n```bash\nmix dala.connect          # tunnel + connect IEx to running device\nnl(MyApp.SomeScreen)     # hot-push new bytecode, no restart\n\n# In IEx:\nDala.Test.screen(:\"my_app_ios@127.0.0.1\")  #=\u003e MyApp.CounterScreen\nDala.Test.assigns(:\"my_app_ios@127.0.0.1\") #=\u003e %{count: 3, ...}\nDala.Test.tap(:\"my_app_ios@127.0.0.1\", :increment)\n```\n\n## Testing\n\n```elixir\ntest \"increments count\" do\n  {:ok, pid} = Dala.Screen.start_link(MyApp.CounterScreen, %{})\n  :ok = Dala.Screen.Screen.dispatch(pid, \"tap\", %{\"tag\" =\u003e \"increment\"})\n  assert Dala.Screen.Screen.get_socket(pid).assigns.count == 1\nend\n```\n\n## Related packages\n\n| Package | Purpose |\n|---------|---------|\n| [`dala_dev`](https://hex.pm/packages/dala_dev) | Dev tooling: `mix dala.new`, `mix dala.deploy`, `mix dala.connect`, live dashboard |\n| [`dala_new`](https://hex.pm/packages/dala_new) | Generator project tool |\n| [`dala_runtime`](https://github.com/manhvu/dala_runtime) | AOT compiler \u0026 runtime for BEAM, fix limitations of JIT  |\n\n\n\n## Documentation\n\nFull documentation at [hexdocs.pm/dala](https://hexdocs.pm/dala), including:\n\n- [Getting Started](https://hexdocs.pm/dala/getting_started.html)\n- [Architecture \u0026 Prior Art](https://hexdocs.pm/dala/architecture.html)\n- [Screen Lifecycle](https://hexdocs.pm/dala/screen_lifecycle.html)\n- [Components](https://hexdocs.pm/dala/components.html)\n- [Theming](https://hexdocs.pm/dala/theming.html)\n- [Navigation](https://hexdocs.pm/dala/navigation.html)\n- [Device Capabilities](https://hexdocs.pm/dala/device_capabilities.html)\n- [Testing](https://hexdocs.pm/dala/testing.html)\n\n## License\n\nMPL-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fohhi-vn%2Fdala","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fohhi-vn%2Fdala","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fohhi-vn%2Fdala/lists"}