---
title: How to Wrap an Angular App with Capacitor and Firebase
description: Step-by-step guide to wrap an existing Angular web app into a native iOS and Android app using Capacitor, Ionic, and Firebase.
date:
  created: 2026-04-27
  updated: 2026-07-17
authors:
  - djabif
categories:
  - Capacitor
  - Firebase
  - Guides
links:
  - Capacitor File Picker: sdks/capacitor/file-picker.md
  - Capacitor File Compressor: sdks/capacitor/file-compressor.md
  - Capacitor Firebase Cloud Firestore: sdks/capacitor/firebase/cloud-firestore.md
  - Capacitor Firebase Cloud Storage: sdks/capacitor/firebase/cloud-storage.md
search:
  boost: 2
faq: true
---

# How to Wrap an Angular App with Capacitor and Firebase

If you already have an Angular web app, you can wrap it into a native iOS and Android app without rewriting your entire codebase.
In this guide, we use a real demo app called **Trip Expenses** to walk through the full process with Capacitor, Ionic, Firebase, and a handful of native plugins.

<!-- more -->

???+ tip "Get the code"

    The complete source code is available on [GitHub](https://github.com/capawesome-team/capacitor-angular-starter-guide){:target="_blank"}, free to clone and adapt for your own project.

The demo covers the parts most production apps need: trip and expense management, receipt attachments as images or PDFs, image compression before upload, profile pictures via the device camera, and custom icons and splash screens for both platforms. The stack is Angular 21 with Ionic 8 for the UI, Capacitor 8 for the native runtime, and Firebase (Cloud Firestore and Cloud Storage) for data and files. 

On the Capacitor side, we rely on the [Camera](https://capacitorjs.com/docs/apis/camera){:target="_blank"} and [Splash Screen](https://capacitorjs.com/docs/apis/splash-screen){:target="_blank"} plugins from the Capacitor team, together with the [Capacitor File Picker plugin](../../sdks/capacitor/file-picker.md), [Capacitor File Compressor plugin](../../sdks/capacitor/file-compressor.md), [Capacitor Firebase Cloud Firestore plugin](../../sdks/capacitor/firebase/cloud-firestore.md), and [Capacitor Firebase Cloud Storage plugin](../../sdks/capacitor/firebase/cloud-storage.md) plugins from Capawesome.

???+ note

    The example uses Angular, but the same concepts apply to any web project — Capacitor is framework-agnostic.

## Important Definitions for Your First Capacitor App

Before jumping into the code, let's clarify a few concepts and answer some common questions, especially if this is your first time working with Capacitor.

### What Is Capacitor?

Capacitor is an open-source runtime developed by the Ionic team that lets you run your web app as a native iOS and Android app.
It wraps your built web assets in a native shell, so your Angular code still powers the UI and business logic. You keep a single codebase for most features, access native device APIs through plugins as you need them, and ship updates through the standard app store workflow — adding native capabilities progressively over time.

### Angular Web vs Mobile Runtime: Key Differences

Before you start, it helps to know what changes when your Angular app runs inside Capacitor. The app runs inside a native `WebView` rather than a browser tab, which means iOS and Android permission models now apply (`Info.plist` and `AndroidManifest.xml`). File handling looks different too: native paths like `file://` and `content://` enter the picture, and memory constraints matter more than they do on the web. And instead of a web deploy, releases involve native binaries and the regular app store workflow.

Your Angular code still drives most of the product, but the quality of the native integration directly affects reliability, UX, and performance.

### What Is a Capacitor Plugin?

A Capacitor plugin is the bridge between your TypeScript code and native iOS and Android APIs. It typically ships a TypeScript API along with native iOS and Android implementations, plus an optional web implementation so the same code path works in the browser. In this project, that means using native integrations where they matter most — camera, file picking, Firebase on device — while keeping a single Angular codebase.

### Is Ionic Required?

No, Ionic is optional. It's a [mobile UI toolkit](https://ionicframework.com/docs/components){:target="_blank"} that gives you production-ready components and app-like UX patterns out of the box, but if your team already has a design system, you can use Capacitor with plain Angular.

## Add Capacitor to Your Angular Project

Install the Capacitor core and CLI packages, then initialize the project:

```bash
npm install @capacitor/core@latest
npm install -D @capacitor/cli@latest
npx cap init
```

The CLI will prompt you for your app name (e.g. `Trip Expenses`), app ID (e.g. `io.tripexpenses.app`), and web output directory (`www` or your Angular `dist/` directory) — use your own values here.

Next, add the iOS and Android platforms:

```bash
npm install @capacitor/ios@latest @capacitor/android@latest
npx cap add ios
npx cap add android
```

That's it. Your Angular web app is now wrapped in a native shell and ready to run on both platforms.

### Build, Sync, and Run

The Capacitor development workflow takes a couple of tries to get used to, but the loop is short. Whenever you change web code, rebuild and sync the changes into the native projects:

```bash
npm run build
npx cap sync
```

To open the native projects in Xcode or Android Studio:

```bash
npx cap open ios
npx cap open android
```

Or run directly on a simulator or device:

```bash
npx cap run ios
npx cap run android
```

### Generate App Icons and Splash Screens

You can generate icons and splash screens for both platforms with the [@capacitor/assets](https://github.com/ionic-team/capacitor-assets){:target="_blank"} tool. Install it as a dev dependency, drop your own `icon-only.png` and `splash.png` into the `resources/` folder, and let the CLI do the rest:

```bash
npm install -D @capacitor/assets@latest
npx capacitor-assets generate --ios
npx capacitor-assets generate --android
```

This produces all the required platform assets. The tool has more configuration options if you need finer control — check its README.

## Set Up Your Own Firebase Project

If you clone the [demo app](https://github.com/capawesome-team/capacitor-angular-starter-guide){:target="_blank"}, you'll need to create your own Firebase project before running it.

### 1) Create Firebase Resources

In the [Firebase Console](https://console.firebase.google.com/){:target="_blank"}, create a new project and enable both **Cloud Firestore** and **Cloud Storage**.

### 2) Register App Clients

Under the same Firebase project, register a Web app for the Angular runtime, an Android app with package name `io.tripexpenses.app`, and an iOS app with bundle ID `io.tripexpenses.app`. Replace those identifiers with your own.

### 3) Configure Web Firebase Values

Add your Web SDK config to `src/environments/environment.ts` and `src/environments/environment.prod.ts`.

### 4) Configure Native Firebase Files

When you registered the Android and iOS apps in step 2, you had the option to download the native config files. Place `google-services.json` at `android/app/google-services.json` and `GoogleService-Info.plist` at `ios/App/App/GoogleService-Info.plist`, then run:

```bash
npx cap sync
```

## Integrate Firebase with Capacitor

With your Firebase project ready, the next step is wiring it into the app. We use native Firebase plugins rather than the web SDKs, which gives us better reliability inside the WebView, native file upload paths, and noticeably better performance with large files.

To install them, see the [Installation](../../sdks/capacitor/firebase/cloud-firestore.md#installation) section of the Firebase Cloud Firestore plugin and the [Installation](../../sdks/capacitor/firebase/cloud-storage.md#installation) section of the Firebase Cloud Storage plugin.

## Adding Native Features

The demo app includes a couple of native feature touchpoints to make the migration realistic.

### Profile Picture Upload

On the profile screen, users can update their profile picture by taking a photo or picking one from the gallery. The Angular UI stays exactly the same — the [Camera](https://capacitorjs.com/docs/apis/camera){:target="_blank"} plugin from the Capacitor team takes care of calling the native camera on iOS and Android, and ships a web fallback so the same code path works in the browser too.

<figure markdown>
  ![Capacitor Camera Plugin Example](../../assets/images/screenshots/capacitor-camera-plugin.png){ width="300" }
  <figcaption>Upload Profile Picture</figcaption>
</figure>

### Expense Attachment Flow

When creating an expense, users can attach a receipt image or PDF. Three plugins work together for this flow: the [Capacitor File Picker plugin](../../sdks/capacitor/file-picker.md) handles native file selection, the [Capacitor File Compressor plugin](../../sdks/capacitor/file-compressor.md) shrinks images before upload, and the [Capacitor Firebase Cloud Storage plugin](../../sdks/capacitor/firebase/cloud-storage.md) uploads the result on device. All of the related code lives in `src/app/core/services/storage.service.ts`.

<figure markdown>
  ![Capacitor File Picker Example](../../assets/images/screenshots/capacitor-file-picker.png){ width="300" }
  <figcaption>File Picker</figcaption>
</figure>

For a deeper look at file handling on Capacitor — including memory pitfalls and best practices — see [Capacitor File Handling: The Complete Guide](./capacitor-file-handling-guide.md). For everything the Cloud Storage plugin itself can do — upload progress, security rules, pagination — see [Upload & Manage Files with Firebase Storage in Capacitor](./capacitor-firebase-cloud-storage-guide.md).

That covers everything needed to bring your Angular app to mobile. The rest is just Angular and Ionic UI to build out your product.

## Production Delivery with Capawesome Cloud

Once the app runs reliably on real devices, the next step is automating delivery. Capawesome Cloud handles the parts that would otherwise eat your time: [Native Builds](../../cloud/native-builds/setup.md) produces reproducible iOS and Android binaries in a consistent environment, [Live Updates](../../cloud/live-updates/setup.md) ships fixes and improvements to the web layer without going through app store review every time, and [App Store Publishing](../../cloud/app-store-publishing/index.md) delivers builds straight to TestFlight or Google Play.

A pattern that works well in practice is combining the two release tracks — ship stable native builds through the stores, and use Live Updates for fast iteration on the web layer in between. Wire it all into your repo with the [GitHub integration](../../cloud/integrations/github.md) and your pipeline triggers builds and deployments automatically on commit, branch, or tag.

<div class="capawesome-z29o10a">
  <a href="https://capawesome.io/" target="_blank">
    <img alt="Build and deploy your Capacitor app with Capawesome Cloud" src="https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
  </a>
</div>

See the [Capawesome Cloud documentation](../../cloud/index.md){:target="_blank"} for setup details, or browse the [video walkthroughs](https://www.youtube.com/@capawesomeio){:target="_blank"} for each step.

## FAQ

### Do I need Ionic to wrap an Angular app with Capacitor?

No — Ionic is entirely optional. Capacitor itself only wraps your web build into a native shell; Ionic just adds a mobile UI component library and app-like UX patterns on top. If your Angular app already has its own design system, you can add Capacitor directly without introducing Ionic at all.

### Why use native Firebase plugins instead of the Firebase Web SDK, since the app already runs Angular?

For reliability and performance inside the WebView, not just convenience. The native Firebase plugins give more reliable behavior than the Firebase JS SDK running inside a mobile WebView, native file upload paths, and noticeably better performance with large files — the trade-off is installing platform-specific plugins instead of a single web-only SDK.

### After wrapping my app, do web deploys still work the same way?

No — releases now go through the native app store workflow instead of a simple web deploy. Your Angular code still powers the UI, but shipping a change to users means either a native build submission (for native-layer changes) or a Live Update (for web-layer-only changes), rather than just deploying updated static assets to a web server.

### Does wrapping the app change how file paths work in my Angular code?

Yes — this is one of the more common surprises. Once running inside a native WebView, native path schemes like `file://` and `content://` enter the picture, which web-only Angular code typically never has to handle. Memory constraints also matter more on-device than in a desktop browser tab, so file-heavy flows (like the receipt attachment feature in this guide) need to account for both.

### Can I add native plugins gradually, or do I have to wire up every capability before shipping?

Gradually — that's the intended workflow, not a limitation. Since your Angular code keeps driving the UI and business logic, you can ship an initial wrapped version with minimal native touchpoints and add plugins (camera, file picker, push notifications, biometrics) over time as you need them, rather than front-loading every native integration before your first release.

## Related Posts

- [Capacitor Firestore: Real-Time Data & Offline Sync](./capacitor-firebase-cloud-firestore-guide.md)
- [What's New in Capacitor Firebase 8.3.0](./capacitor-firebase-8-3-0-release.md)

## Try Capawesome Cloud

Stop fighting with manual builds and slow release cycles. Capawesome Cloud handles native builds, live updates, and app store publishing for your Capacitor apps in one place.

[Try Capawesome Cloud Free](https://capawesome.io){ .md-button .md-button--primary }

## Conclusion

Wrapping an Angular app for iOS and Android with Capacitor isn't a rewrite — it's an extension of what you already have. Your Angular code keeps powering the UI and business logic; you just add native capabilities where they matter and ship through the regular app store workflow.

This means your team can move faster, reduce duplication, and ship features consistently across web, iOS, and Android without the overhead of maintaining separate apps.

Once you have this setup in place, you can start extending your app with more advanced features, such as adding [push notifications](./capacitor-push-notifications-guide.md) to keep users engaged, implementing [in-app purchases](./tips-for-setting-up-in-app-purchases-with-capacitor.md) to monetize your app, or building secure authentication flows using [OAuth](../../sdks/capacitor/oauth.md) and [biometrics](./exploring-the-capacitor-biometrics-api.md).


For a deeper look at how to roll out updates safely once you're in production, see [Capacitor App Updates: The Complete Guide](./capacitor-app-update-guide.md).

Your app is wrapped — but getting it into the stores involves a few more steps. For a complete walkthrough covering developer accounts, certificates, builds, store listing, and Live Updates setup, see [From Web App to App Store: The Complete Guide](./11-steps-to-get-your-web-app-on-the-app-store.md). If you're coming from an AI app builder rather than a hand-written codebase, the beginner-friendly [Convert Your Lovable App to iOS & Android Apps](./convert-lovable-app-to-mobile-app.md) follows the same path end to end.

If you have questions, join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW){:target="_blank"} and connect with the community. To stay up to date on the latest news, subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/){:target="_blank"}.
