Tutorial10 min read

Turn your Angular app into iOS and Android apps with Capacitor

Convert an existing Angular app into native iOS and Android apps with Capacitor — no rewrite — then push web-layer changes over the air with OtaKit live updates.

Angular is a natural fit for Capacitor. Your existing app — components, services, RxJS, the router — runs unchanged inside a native shell, and you ship the same codebase to the web, iOS, and Android. No NativeScript, no rewrite, no second framework to learn.

This guide takes a standard Angular app to installable native builds, then adds OtaKit so you can push updates to the web layer over the air instead of waiting on a store review for every change.

Mental model: Capacitor gives your Angular app a native container. OtaKit keeps that web layer current after it ships.

1. Point Angular at a static build

Capacitor ships a folder of static files. Angular's application builder outputs one at dist/<app-name>/browser. Build it with:

ng build --configuration production

One important change for a web view: routing. The default path-location strategy can break deep links inside the native file:// context. Switch to hash location so routes resolve reliably:

import { provideRouter, withHashLocation } from "@angular/router";

bootstrapApplication(AppComponent, {
  providers: [provideRouter(routes, withHashLocation())],
});

2. Add Capacitor

npm install @capacitor/core
npm install -D @capacitor/cli

npx cap init "My App" com.example.myapp

npm install @capacitor/ios @capacitor/android

Set webDir to Angular's browser output folder (adjust the app name):

// capacitor.config.ts
import type { CapacitorConfig } from "@capacitor/cli";

const config: CapacitorConfig = {
  appId: "com.example.myapp",
  appName: "My App",
  webDir: "dist/my-app/browser",
};

export default config;

3. Build the native projects

ng build --configuration production
npx cap add ios
npx cap add android
npx cap sync

Open a platform with npx cap open ios or npx cap open android and run it. A one-command loop keeps the sync step honest:

// package.json
"scripts": {
  "mobile": "ng build --configuration production && npx cap sync"
}

4. Reach device features

Device APIs are Capacitor plugins you inject like any Angular dependency:

npm install @capacitor/geolocation
npx cap sync
import { Geolocation } from "@capacitor/geolocation";

async function locate() {
  const { coords } = await Geolocation.getCurrentPosition();
  return { lat: coords.latitude, lng: coords.longitude };
}

5. Add live updates with OtaKit

Install the plugin and configure your OtaKit app id:

npm install @otakit/capacitor-updater
npx cap sync
// capacitor.config.ts
const config: CapacitorConfig = {
  appId: "com.example.myapp",
  appName: "My App",
  webDir: "dist/my-app/browser",
  plugins: {
    OtaKit: { appId: "YOUR_OTAKIT_APP_ID" },
  },
};

Confirm a successful boot from your root component so OtaKit can roll back a bad release automatically:

import { Component, OnInit } from "@angular/core";
import { Capacitor } from "@capacitor/core";
import { OtaKit } from "@otakit/capacitor-updater";

@Component({ selector: "app-root", template: "<router-outlet />" })
export class AppComponent implements OnInit {
  ngOnInit() {
    if (Capacitor.isNativePlatform()) OtaKit.notifyAppReady();
  }
}

Install the CLI and ship:

npm install -g @otakit/cli
otakit login

ng build --configuration production
otakit upload --release

After your first store release with the plugin configured, every otakit upload --release reaches installed devices on their next launch. Native changes still go through the store; your Angular bundle ships over the air — signed, hash-verified, and CDN-delivered with no per-user or bandwidth metering.

Building an Ionic Angular app specifically? See live updates for Ionic apps — the OtaKit setup is the same, and it's a cheaper Appflow alternative.

Where to go next

The setup guide covers the full flow. Then automate releases in CI and read staged rollouts to ship safely.

Related docs