You're in dala_new, the project generator. Read
~/code/dala/AGENTS.md first for the system view, the
three-repo topology, and the cross-cutting pre-empt-failure rules. The
notes below are dala_new-specific.
A Mix archive (mix archive.install hex dala_new) that installs a global
mix dala.new task. Generates either:
- Native Dala projects —
mix dala.new my_app— Elixir-driven SwiftUI/Compose UI. - LiveView wrappers —
mix dala.new my_app --liveview— Phoenix LiveView running on-device, served to a WKWebView/WebView.
Templates live at priv/templates/dala.new/, rendered with EEx by
DalaNew.ProjectGenerator. The LiveView path additionally runs mix phx.new
as a subprocess and patches the result via DalaNew.LiveViewPatcher.
cd ~/code/dala_new
mix archive.build # produces dala_new-<version>.ez
mix archive.install dala_new-0.0.3.ez --force
mix archive # verify installTo publish a new version: bump version: in mix.exs, then
mix hex.publish archive.
-
The LV path skips Phoenix-owned files. When generating a LiveView project, the native template's
mix.exs,config/,lib/<app>/, etc. must NOT clobber whatmix phx.newproduced. The blocklist is inliveview_phoenix_owned?/3(public for testing). If you add a new path to the native template and don't update the blocklist, LV projects ship with a broken (overwritten) Phoenix config. -
Template defaults eagerly evaluate.
System.get_env("ROOTDIR", Path.expand("~/..."))inside a template raises on Android (noHOME). The fix usedcase/||for laziness — seehome_screen.ex.eexrootdir/0helper. Don't reintroduce eager defaults in templates. -
Bundle ID / app name affect Apple App ID validation. Apple rejects auto-generated App ID display names that exceed ~30 chars or contain characters their validator dislikes (underscores have been flagged). Long snake_case app names (
another_political_name_app) hit this.dala.provisionnow rewrites the error to a hint, but the generator itself doesn't enforce length — that's a deliberate trade-off so users can still pick descriptive names; we surface the issue at provision time. -
Port 4200 is hardcoded for LiveView projects. All LV templates set the Phoenix endpoint to 127.0.0.1:4200. Two installed apps collide; only one runs at a time. Tracked in
dala/issues.md#4 — fix involves hashing the bundle id. -
Dala.Ui.Widgets.*prop names must match the API exactly. TheDala.Ui.Widgets.*functions useMap.take(props, allowed)which silently drops unknown props. Common mismatches:weight(not in UI API, only in Spark DSL entities),align(not in UI API, only native-side),keyboard→keyboard_type,min/max→min_value/max_value,content_mode→resize_mode,src→source(for image). Always checkDala.Ui.Widgets.*function definitions before adding props to template code. -
apply_liveview_patchesis the orchestration spine. New LV-specific generated files / config patches go through it. The order matters (Phoenix files generated byphx.new, then patches, then native boilerplate, then LV-specific configs). Document any reordering. -
Screen templates use
render/1withDala.Ui.Widgets.*functions. Complex screens with helper functions can't use the Spark DSL'sscreen do...endblock (which only accepts registered UI entities). Instead, they definemount/3andrender/1explicitly usingDala.Ui.Widgets.*functions. Simple screens (like WebViewScreen) can use the Spark DSL withscreen name: :atom do ... end. See examples inpriv/templates/dala.new/lib/app_name/*_screen.ex.eex. -
Module name changes to track. The dala repo has renamed several modules:
Dala.Ui.Socket→Dala.Socket,Dala.Dist→Dala.Connectivity.Dist,Dala.State→Dala.Platform.State,Dala.UI.*→Dala.Ui.Widgets.*,Dala.Ui.List→Dala.Ui.List(NOTDala.List),Dala.Storage.*→Dala.Storage.Storage.*,Dala.WebView→Dala.Ui.Embedded.Webview,Dala.Audio→Dala.Media.Audio,Dala.Camera→Dala.Media.Camera,Dala.Haptic→Dala.Hardware.Haptic,Dala.Location→Dala.Platform.Location,Dala.Motion→Dala.Ui.Sensor.Motion,Dala.Notify→Dala.Platform.Notify,Dala.Biometric→Dala.Hardware.Biometric,Dala.Scanner→Dala.Hardware.Scanner,Dala.Clipboard→Dala.Platform.Clipboard,Dala.Share→Dala.Platform.Share,Dala.Photos→Dala.Media.Photos,Dala.Files→Dala.Storage.Files,Dala.NativeLogger→Dala.Platform.NativeLogger,Dala.ComponentRegistry→Dala.Ui.NativeView.Registry. Always verify against the current dala repo before editing templates.New in dala v0.8.0:
Dala.Distis now a convenience shorthand that delegates toDala.Connectivity.Dist(useDala.Dist.cookie_from_env/2andDala.Dist.ensure_started/1in templates).Dala.Appnow delegates toDala.App.AppandDala.Screendelegates toDala.Screen.Screen. Theuse Dala.Appanduse Dala.Screenmacros remain the correct API.Dala.Platform.Nativeis the Rustler NIF module (replaces olddala_nif.erl).Dala.Previewhas been replaced byDala.Designer(dev only) — drag-and-drop UI designer and preview tool. New modules:Dala.Gpu.Compute,Dala.ML,Dala.ML.Burn,Dala.ML.CoreML,Dala.ML.ONNX,Dala.ML.Gpu.Inference,Dala.Hardware.Bluetooth,Dala.Connectivity.Wifi,Dala.Wakelock,Dala.Platform.Settings,Dala.Platform.Linking,Dala.Platform.Background,Dala.Storage.Blob,Dala.Ui.Feedback.Alert,Dala.Ui.Scan,Dala.Hardware.NFC,Dala.Theme.AdaptiveWatcher,Dala.Theme.Adaptive.Custom,Dala.Device.{Ios,Android,Device},Dala.Screen.Manager,Dala.Node,Dala.Ui.Diff,Dala.Renderer(binary protocol),Dala.Designer(dev only),Dala.Event,Dala.Event.Bridge,Dala.Event.Throttle,Dala.Event.Trace,Dala.PubSub,Dala.List,Dala.Ui.NativeView,Dala.Ui.NativeView.Registry,Dala.Ui.NativeView.Server,Dala.Nav.Registry,Dala.Media.Gpu.Processor.Dala.verify_dsl/1validates DSL definitions of a screen module. -
DSL syntax:
dala dowrapsattributes doandscreen name: :atom do. The top-level block isdala do ... end, which containsattributes do ... endandscreen name: :atom do ... end. Container props use keyword args (gap :space_sm), not function calls (gap(:space_sm)). Simple screens can usescreen name: :atom do ... enddirectly without thedala dowrapper.New in v0.8: DSL supports conditional rendering (
if @loading do ... else ... end,unless @show do ... end), list rendering (for item <- @items do ... end), text variants (variant: :headingfor presets like:display,:heading,:title,:body,:caption,:label,:overline), and text selectable (selectable: true). All components now accept:accessibility_label,:accessibility_hint,:accessibility_role,:accessibility_value,:accessibility_hiddenprops. -
Dala.Socket.push_screen/3takes(socket, dest, params \\ %{})— params is optional. New navigation functions:pop_to/2,pop_to_root/1,reset_to/3.Dala.Socket.changed?/2andclear_changed/1track assign changes.Dala.Permissions.request/2takes(pid, permission)not(socket, permission). Permission results arrive as{:permission_result, permission, result}(not{:permission, ...}). -
Dala.Ui.Widgetshas many new components:icon/1,toggle/1,tab_bar/1,video/1,switch/1,activity_indicator/1,modal/2,refresh_control/1,pressable/2,safe_area/1,status_bar/1,checkbox/1,radio/1,card/2,badge/2,chip/1,snackbar/1,bottom_sheet/2,tooltip/2,fab/1,icon_button/1,segmented_button/1,app_bar/1,nav_bar/1,nav_drawer/1,nav_rail/1,menu/1,date_picker/1,time_picker/1,search_bar/1,carousel/1,native_view/2,empty_state/1,avatar/1,stepper/1,skeleton/1,grid/2. -
Dala.Testhas expanded significantly with native UI inspection (view_tree/1,find_view/2,ui_tree/1), accessibility actions (ax_action/3,ax_action_at_xy/4),toggle/2,dismiss_alert/2,adjust_slider/4,tap_xy/3,type_text/2,screen_info/1,wait_for/2,wait_for_text/2, and WebView helpers (webview_eval/2,webview_post_message/2,webview_navigate/2, etc.). -
New
Dala.Pluginsystem for self-describing component plugins with schema, protocol, and manifest generation.Dala.Componentfor native view components.Dala.Rendererfor component tree serialization.
mix test # unit tests (fast)
mix test --include integration # also runs `mix phx.new` subprocesses (~minute)The integration tests generate real LV projects in tmp dirs to verify the end-to-end output. Worth running locally before publishing a new version.
When you add a new template path, change the LV phx-owned blocklist, or hit a new generator gotcha — update this file in the same commit.