Skip to content

Guide

Quick start

From an empty directory to an Angular app running on native views, on the platform of your choice.

Xcode with the simulator runtime for the platform you want. tvOS and visionOS ship theirs separately: xcodebuild -downloadPlatform tvOS.

tvOS, visionOS and watchOS also need a nightly Rust toolchain — their Rust targets are tier 3 and ship no prebuilt std:

Terminal window
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
  1. Clone this repository and put an on your PATH:

    Terminal window
    git clone https://github.com/nesgarbo/angular-native
    cd angular-native
    cargo install --path crates/an-cli
  2. Create an Angular project, or use one you already have:

    Terminal window
    npx @angular/cli@latest new my-app
    cd my-app
  3. Set it up:

    Terminal window
    an init

    This adds a manifest, a native tsconfig, the two framework packages and a native entry point. It touches neither src/main.ts nor angular.json, so ng build and ng serve keep working exactly as before.

  4. Add a platform and run it:

    Terminal window
    an add ios && an ios
    an add tvos && an tvos .
    an add visionos && an visionos .
Terminal window
an dev # iPhone simulator
an dev --android # Android emulator
an dev --tvos # Apple TV simulator
an dev --visionos # Vision Pro simulator
an dev --watchos # Apple Watch simulator
an dev --wearos # Wear OS emulator
an dev --macos # a window on this Mac

--macos is the odd one out: there is no simulator, so the app opens on the machine that is compiling it and the server it talks to is on that same machine.

Saving a component swaps its definition in the running app. You stay on the same screen, with whatever you had typed and the timers still running.

<an-view [style.padding]="'16'" [style.gap]="'12'">
<an-text [fontSize]="28" [fontWeight]="'bold'">Settings</an-text>
<an-view [style.flexDirection]="'row'" [style.justifyContent]="'space-between'">
<an-text>Notifications</an-text>
<an-switch [on]="notify()" (onChange)="notify.set($event)" />
</an-view>
<an-button
[title]="'Save'"
[variant]="'filled'"
[accessibilityHint]="'saves without leaving the screen'"
(press)="save()" />
</an-view>

That an-switch is a UISwitch on iOS and a MaterialSwitch on Android. Layout is flexbox, computed once in the core and handed to every platform as absolute frames.