Skip to content
Draft

Mobile Development

Draft supports cross-platform mobile development for iOS and Android.

Write once, deploy to both iOS and Android. Draft compiles to native code with platform bindings.

Terminal window
draft target add aarch64-apple-ios
draft target add aarch64-linux-android
draft target add armv7-linux-androideabi
Terminal window
draft new my-app --template mobile
cd my-app

Project structure:

my-app/
├── draft.toml
├── src/
│ ├── main.draft
│ ├── ui.draft
│ └── api.draft
├── ios/
│ ├── Info.plist
│ └── AppDelegate.swift
├── android/
│ ├── AndroidManifest.xml
│ └── MainActivity.kt
└── shared/
└── models.draft
import ui
action main()
@app = @ui#App::new("My App")
@app#view(fn() =>
@ui#Column::new()
#child(@ui#Text::new("Hello, World!"))
#child(@ui#Button::new("Click Me", fn() =>
@ui#alert("Button clicked!")
fin action.))
#child(@ui#List::new(@items, fn(@item) =>
@ui#Row::new()
#child(@ui#Text::new(@item#title))
#child(@ui#Text::new(@item#subtitle))
fin action.))
fin action.)
@app#run()
fin action.
import ui
@ui#Column::new()
#padding(16)
#spacing(8)
#child(@ui#Text::new("Title"))
#child(@ui#Row::new()
#spacing(8)
#child(@ui#Button::new("Cancel", @on_cancel))
#child(@ui#Button::new("OK", @on_ok))
fin action.)
import ui
@ui#Text::new("Hello")
#font_size(24)
#color(@ui#rgb(0, 122, 255))
#font_weight(@ui#BOLD)
#padding(16)
#background(@ui#rgb(240, 240, 240))
#border_radius(8)
import ui
action main()
@nav = @ui#Navigator::new()
@nav#route("/", fn() => home_view())
@nav#route("/profile", fn() => profile_view())
@nav#route("/settings", fn() => settings_view())
@nav#navigate("/profile")
fin action.
import ui
record AppState
count: Int
user: User?
fin record.
action main()
@state = @ui#state(AppState { count: 0, user: nil })
@ui#view(fn() =>
@ui#Column::new()
#child(@ui#Text::new(string(@state#count)))
#child(@ui#Button::new("Increment", fn() =>
@state#update(fn(@s) => AppState { count: @s#count + 1, user: @s#user })
fin action.))
fin action.)
fin action.
import http
import json
action load_users() -> Result<Array<User>, Error>
@response = @http#get("https://api.example.com/users")?
@data = @response#json()?
return ok(@data)
fin action.
import camera
action take_photo()
@image = @camera#capture()
@image#save("photo.jpg")
fin action.
import location
action get_location()
@loc = @location#current()
@lat = @loc#latitude
@lng = @loc#longitude
fin action.
import notifications
action schedule_notification()
@notifications#schedule(
title: "Reminder",
body: "Don't forget!",
time: @time#now() + @time#minutes(30)
)
fin action.
import storage
action save_data()
@storage#set("username", "alice")
@username = @storage#get("username")
fin action.
import biometrics
action authenticate()
@result = @biometrics#authenticate("Unlock with Face ID")
if @result#success
@nav#navigate("/home")
fin if.
fin action.
import permissions
action main()
@permissions#request([
@permissions#CAMERA,
@permissions#LOCATION,
@permissions#NOTIFICATIONS
])
fin action.
import ui
@ui#view(fn() =>
@ui#Text::new("Swipe me")
#on_swipe_left(fn() => @nav#back())
#on_swipe_right(fn() => @nav#next())
#on_pinch(fn(@scale) => @zoom(@scale))
#on_long_press(fn() => @show_menu())
)
import ui
@ui#view(fn() =>
@ui#Text::new("Animated")
#animate(@ui#fade_in(duration: 300))
#animate(@ui#slide_up(duration: 500))
#animate(@ui#scale(from: 0.5, to: 1.0))
)
import ui
@ui#List::new(@items, fn(@item) =>
@ui#Row::new()
#child(@ui#Image::new(@item#icon))
#child(@ui#Column::new()
#child(@ui#Text::new(@item#title))
#child(@ui#Text::new(@item#subtitle))
fin action.)
#on_press(fn() => @nav#navigate("/detail/" + @item#id))
)
import ui
action main()
@form = @ui#Form::new()
@form#text("name", label: "Name", required: true)
@form#email("email", label: "Email", required: true)
#form#password("password", label: "Password")
@form#submit(fn(@data) =>
@result = create_user(@data)
fin action.)
@form#show()
fin action.
import ui
action get_theme()
if @platform#is_ios()
return @ui#ios_theme()
else if @platform#is_android()
return @ui#android_theme()
fin if.
fin action.
Terminal window
draft build --target aarch64-apple-ios --release
Terminal window
draft build --target aarch64-linux-android --release
Terminal window
draft build --target mobile --release
Terminal window
@// Unit tests
draft test
@// iOS simulator
draft run --target ios-simulator
@// Android emulator
draft run --target android-emulator
Terminal window
draft deploy --target ios
Terminal window
draft deploy --target android

Mobile apps built with Draft:

Metric Value
App size ~5-15 MB
Startup time < 100ms
Memory usage ~20-50 MB
Frame rate 60 FPS