Cada vez es más común tener una web hecha en Angular, React o Vue y querer llevarla tal cual al móvil sin reescribir nada en Swift, Kotlin o Java. Ahí es donde entran Capacitor e Ionic: una combinación que permite crear apps para iOS y Android reutilizando casi todo tu código web.
La idea es sencilla:
- Angular se encarga de la parte web (componentes, routing, servicios…).
- Ionic pone los componentes UI orientados a móvil.
- Capacitor actúa como “puente” entre esa web y las APIs nativas del dispositivo (cámara, ficheros, geolocalización, etc.).

Qué vas as ver en esta entrada
La combinación Angular + Ionic + Capacitor permite
- Mantener una sola base de código en TypeScript.
- Construir la interfaz con componentes pensados para móvil.
- Empaquetar todo como aplicación nativa para App Store y Google Play.
¿Qué es Capacitor?
Capacitor es el runtime nativo de Ionic. Por debajo hace básicamente tres cosas:
- Abre tu app web en un WebView dentro de una app nativa.
- Expone una API JavaScript con plugins para acceder a cámara, archivos, geolocalización, notificaciones, etc.
- Genera proyectos nativos estándar (Android/ y iOS) que puedes abrir en Android Studio y Xcode como cualquier proyecto nativo más.
Lo mejor es que no está casado con Angular. Mientras exista un index.htmly una carpeta con el build (por ejemplo dist/tu-app/browser), Capacitor puede trabajar encima de eso: Angular, React, Vue, Svelte o una web clásica.
A nivel de configuración, Capacitor se controla con un archivo de config (normalmente capacitor.config.ts o capacitor.config.json) donde indicas:
appId: identificador del paquete (com.empresa.app).appName: cómo se verá el nombre de la app en el dispositivo.webDir: carpeta donde vive el build de tu app web.- Opcionalmente, cosas como el servidor de desarrollo o preferencias de plugins.
Ionic: la capa de UI orientada a móvil
Ionic aporta la parte visual, componentes listos para móvil que se integran perfectamente con Angular:
- Botones, listas, tarjetas, pestañas, modales, menús laterales…
- Estilos adaptados a iOS y Android (cambia automáticamente detalles como la posición de las tabs, la tipografía o los bordes).
- Utilidades de layout (ion-grid, ion-content, etc.) pensadas para pantallas táctiles.
Podrías usar solo Web App + Capacitor, pero la interfaz se vería “web” a menos que ajustemos mucho el CSS (lo que podría tomar mucho tiempo). Con Ionic esos componentes ya vienen listos para verse bien en móvil casi sin esfuerzo.
Funcionamiento de Angular + Ionic + Capacitor
En este caso, veremos el ejemplo utilizando Angular, un framework muy popular de Google:
- Un código, tres salidas: web normal, PWA y app nativa.
- Mismo stack que ya conoces: Angular, RxJS, TypeScript.
- Plugins nativos cuando los necesitas, sin tocar Swift/Kotlin.
- Ciclo de desarrollo razonable:
ng serveen navegador,build + npx cap synccuando quieras probar en móvil.
Crear una app híbrida y ejecutarla en dispositivos Apple y Android
Inicializar un proyecto Angular estándar:
ng new contador-hibrido --routing=false --style=scss
cd contador-hibrido
ng serve
Abre http://localhost:4200 y comprueba que la aplicación base de Angular se ve bien.
Añadir Ionic sobre Angular
Para usar los componentes de Ionic debemos agregar las dependencias a nuestro proyecto:
ng add @ionic/angular
Este comando agrega las dependencias de Ionic, ajusta el AppModule y te deja listo para usar etiquetas como <ion-app>, <ion-header>, <ion-content>, etc.
<!-- app.component.html --> <ion-app> <ion-header> <ion-toolbar> <ion-title>Contador híbrido</ion-title> </ion-toolbar> </ion-header> <ion-content class="ion-padding"> <app-counter></app-counter> </ion-content> </ion-app>
La etiqueta<app-counter> será el componente que vamos a crear ahora.
Componente contador “- 0 +”
Genera el componente Angular:
ng generate component counter src/app/counter/counter.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.scss'],
})
export class CounterComponent {
value = 0;
increment() {
this.value = this.value + 1;
}
decrement() {
this.value = this.value - 1;
}
}
src/app/counter/counter.component.html
<div class="counter-wrapper">
<ion-button
color="medium"
fill="outline"
(click)="decrement()"
>
-
</ion-button>
<span class="counter-value">
{{ value }}
</span>
<ion-button
color="primary"
fill="solid" (
click)="increment()"
>
+
</ion-button>
</div>
src/app/counter/counter.component.scss
.counter-wrapper {
display: flex;
align-items: center;
justify-content: center;
gap: 1.5rem;
margin-top: 2rem;
}
.counter-value {
font-size: 2.5rem;
font-weight: 600;
}
Con «ng serve» deberías ver la pantalla con los botones «-» y «+» y el número en medio actualizándose.
Instalar Capacitor en el proyecto
La opción cómoda con Angular es: ng add @capacitor/angular
Esto instala @capacitor/core y @capacitor/cli y te genera el archivo de configuración de Capacitor.
Sin embargo, se puede instalar de forma manual:
npm install @capacitor/core npm install --save-dev @capacitor/cli npx cap init
El init pide: App name (por ejemplo Contador híbrido) y App ID (por ejemplo com.everit.contador).
Configurando capacitor.config
Según la versión de Capacitor/Angular, verás algo como capacitor.config.ts o capacitor.config.json en la raíz del proyecto.
Ejemplo con capacitor.config.ts:
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.everit.contador',
appName: 'Contador híbrido',
webDir: 'dist/contador-hibrido/browser',
bundledWebRuntime: false,
server: {
// Útil para live-reload en desarrollo móvil
// url: 'http://192.168.1.100:4200',
// cleartext: true,
},
};
export default config;
Si usas capacitor.config.json, la estructura sería:
{
"appId": "com.everit.contador",
"appName": "Contador híbrido",
"webDir": "dist/contador-hibrido/browser",
"bundledWebRuntime": false
}
Si se cambia el nombre del proyecto o la carpeta de salida del build, hay que recordar actualizar webDir.
Build de Angular y sincronización
Antes de crear los proyectos nativos, la app Angular tiene que estar construida: ng build --configuration production. Cuando ya hemos construido el build, añadir las plataformas nativas:
npm install @capacitor/android @capacitor/ios npx cap add android npx cap add ios
Cada vez que se cambie el código de Angular y se quiera que esos cambios lleguen a las apps nativas, el ciclo típico es:
ng build --configuration production npx cap sync
sync copia los archivos de webDir a cada proyecto nativo y actualiza plugins y configuración.
Abrir el proyecto en Android Studio
Con la carpeta android/ creada, abrir el proyecto:
npx cap open android
Esto lanza Android Studio apuntando al proyecto generado. Desde ahí eliges dispositivo (emulador o físico) y pulsar Run para instalar la app y ver la pantalla del contador.
Abrir el proyecto en Xcode
En macOS, con Xcode instalado: npx cap open ios
Esto abre el workspace de iOS en Xcode. Elige simulador o dispositivo, selecciona el target de la app y pulsar Run para ver el contador corriendo en iOS.
Opcional: live reload en dispositivo
Para evitar hacer build cada vez mientras desarrollas, se puede usar el servidor de desarrollo de Angular:
ng serve --host 0.0.0.0 --port 4200
En capacitor.config.ts, configurar el servidor:
server: {
url: 'http://192.168.1.50:4200',
cleartext: true
}
Después de npx cap sync, la app nativa cargará directamente desde ese servidor de desarrollo y tendrás recarga automática también en el dispositivo. Para builds de producción, vuelve a servir desde webDir.
Conclusiones
Con Capacitor e Ionic no hace falta elegir entre web o móvil: puedes partir de una app Angular (o cualquier framework web moderno) y terminar con un binario listo para instalar en Android e iOS usando el mismo código base.
A nivel práctico, esta combinación aporta:
- Un único proyecto para web, PWA y app nativa.
- UI pensada para móvil gracias a los componentes de Ionic.
- Acceso sencillo a APIs nativas (cámara, ficheros, geolocalización, etc.) a través de plugins de Capacitor.
- Un flujo de trabajo claro: desarrollas en navegador, haces build, sincronizas con npx cap sync y pruebas en dispositivo o emulador.
El contador «- 0 +» es un ejemplo mínimo, pero ya recorre el camino completo: desde ng new hasta abrir el proyecto en Android Studio y Xcode. A partir de aquí, el siguiente paso natural es empezar a añadir pantallas, navegación, almacenamiento local y plugins nativos más avanzados, manteniendo siempre la ventaja de seguir trabajando en TypeScript y en tu entorno Angular de siempre.
Si te interesa estar al día en desarrollo web, arquitectura y buenas prácticas en programación, síguenos en nuestras redes sociales y Canal de YouTube.