Zornux docs
Get started Spec

Mobile

Mobile Capabilities

Zornux mobile apps access device features through built-in capability APIs. The toolchain detects which capabilities your code uses, generates the native runtime helpers, and wires the Android permissions automatically.

Permissions

Capabilities that require user consent — camera, location, notifications — must be declared with a permissions block. The semantic analyzer refuses to compile a capability call without a matching permission:

zornux
mobile app "PhotoApp"

permissions
    camera because "Take product photos"
    location while using app because "Tag photos with where they were taken"
    notifications because "Notify when uploads finish"
end
CapabilityPermission syntax
Cameracamera because "reason"
Locationlocation while using app because "reason"
Notificationsnotifications because "reason"
Permissions are enforced at compile time

If your code calls camera.take_photo() but the permissions block does not declare camera, zornux check reports a diagnostic and the build fails. The rationale string is shown to the user at runtime when Android requests consent.

The while using app access level applies only to location. Camera and notification permissions do not take an access modifier.

Camera

Take a photo with the device camera or pick one from the gallery:

zornux
screen PhotoScreen
    state photo = ""

    column
        button "Take photo"
            when tapped
                photo = camera.take_photo()
            end
        end
        button "Choose from gallery"
            when tapped
                photo = camera.choose_photo()
            end
        end
        if photo is not ""
            text "Photo captured!"
        end
    end
end

Check whether a camera is available before offering the button:

zornux
if camera.is_available()
    button "Take photo"
        when tapped
            photo = camera.take_photo()
        end
    end
end

Location

Read the device's current GPS coordinates:

zornux
screen LocationScreen
    state position = ""

    column
        button "Where am I?"
            when tapped
                position = location.get_current()
            end
        end
        text position
    end
end

Notifications

Send an immediate notification or schedule one for later:

zornux
button "Notify now"
    when tapped
        notifications.send("Reminder", "Time to check in!")
    end
end

button "Notify in 60 seconds"
    when tapped
        notifications.schedule("Reminder", "One minute has passed", 60)
    end
end

Secure storage

Store sensitive values (tokens, keys) in the platform's encrypted keystore. No permission declaration needed:

zornux
screen TokenScreen
    state token = ""

    when screen opens
        token = secure_storage.get("auth_token")
    end

    column
        text "Token: " + token
        button "Save new token"
            when tapped
                secure_storage.save("auth_token", "abc123")
                show "Token saved"
            end
        end
        button "Clear token"
            when tapped
                secure_storage.remove("auth_token")
                token = ""
            end
        end
    end
end
MethodPurpose
secure_storage.save(key, value)Encrypt and store a value.
secure_storage.get(key)Retrieve a stored value.
secure_storage.remove(key)Delete a stored value.

Biometrics

Prompt the user for fingerprint or face authentication. The result indicates whether authentication succeeded:

zornux
screen SecureScreen
    state authenticated = false

    column
        if authenticated
            text "Access granted"
        else
            button "Authenticate"
                when tapped
                    authenticated = biometrics.authenticate("Confirm your identity")
                end
            end
        end
    end
end

Check whether biometric hardware is available with biometrics.is_available():

zornux
if biometrics.is_available()
    button "Use fingerprint"
        when tapped
            authenticated = biometrics.authenticate("Unlock with fingerprint")
        end
    end
else
    text "Biometrics not available on this device"
end

HTTP

Make network requests with the http object. Requests run asynchronously and return the response body:

zornux
screen ApiScreen
    state data = ""

    when screen opens
        data = http.get("https://api.example.com/items")
    end

    column
        text data
    end
end

All standard HTTP methods are available:

MethodUsage
http.get(url)GET request.
http.post(url)POST request.
http.put(url)PUT request.
http.delete(url)DELETE request.
HTTPS by default

Cleartext HTTP is disabled by default. Set android.allow_cleartext = true in zornux.project for development against a local server — never ship with this enabled.

Local storage

Persist simple key-value data (preferences, drafts, settings) across app restarts. Unlike secure storage, this is not encrypted — use it for non-sensitive data:

zornux
screen NotesScreen
    state note = ""

    when screen opens
        note = store.load("saved_note")
    end

    column
        input note "Write a note..."
        button "Save"
            when tapped
                store.save("saved_note", note)
                show "Note saved"
            end
        end
    end
end
MethodPurpose
store.save(key, value)Write a value to local storage.
store.load(key)Read a value back.

Files

Let the user pick a file from their device:

zornux
button "Choose a file"
    when tapped
        create file = files.choose("application/pdf")
    end
end

Sharing

Share text or a file through the system share sheet:

zornux
button "Share text"
    when tapped
        share.text("Check out this app!")
    end
end

button "Share file"
    when tapped
        share.file(filePath)
    end
end

Connectivity

Check whether the device is online before making network calls:

zornux
if connectivity.is_online()
    data = http.get("https://api.example.com/sync")
else
    show "No internet connection"
end

Capability reference

Every built-in capability, whether it requires a permission declaration, and the generated Android runtime helper:

CapabilityMethodsPermission required
Cameratake_photo(), choose_photo(), is_available()Yes
Locationget_current()Yes
Notificationssend(title, msg), schedule(title, msg, delay)Yes
Secure storagesave(key, val), get(key), remove(key)No
Biometricsauthenticate(msg), is_available()No
HTTPget(url), post(url), put(url), delete(url)No
Local storagesave(key, val), load(key)No
Fileschoose(mimeType)No
Sharingtext(text), file(path)No
Connectivityis_online()No

Native extensions

When a built-in capability is not enough, native extensions let you call Kotlin code from Zornux. An extension is a directory under .zornux/extensions/ with a manifest and a Kotlin runtime file:

text
.zornux/extensions/
  barcode-scanner/
    mobile-extension.json
    BarcodeScanner.kt

Extension manifest

The mobile-extension.json declares the extension's name, version, operations, dependencies, and Android permissions:

text
{
  "name": "barcode-scanner",
  "version": "1.0.0",
  "platform": "android",
  "operations": [
    {
      "name": "scan",
      "returns": "Text",
      "async": true,
      "parameters": [],
      "description": "Scan a barcode and return its value"
    }
  ],
  "android": {
    "dependencies": [
      { "group": "com.google.mlkit", "artifact": "barcode-scanning", "version": "17.3.0" }
    ],
    "permissions": ["CAMERA"],
    "runtime": "BarcodeScanner.kt"
  }
}

Calling an extension

In Zornux code, call an extension by its alias and operation name:

zornux
screen ScanScreen
    state result = ""

    column
        button "Scan barcode"
            when tapped
                result = barcode_scanner.scan()
            end
        end
        text result
    end
end
Extension safety

Only google(), mavenCentral(), and mavenLocal() repositories are allowed. Release builds refuse dynamic dependency versions (SNAPSHOT, +, latest) — pin every version.

Managing extensions

bash
zornux mobile extension list          # list installed extensions
zornux mobile extension info scanner  # show details of one
zornux mobile extension check         # validate compatibility

What's next

  • Mobile Development — screens, layouts, widgets, state, and navigation.
  • Mobile Tooling — hot reload, debugging, testing, profiling, and Play Store publishing.