skills/ionic-expert/SKILL.md
A comprehensive starting point for AI agents to work with the Ionic Framework. Covers core concepts, components, CLI, theming, layout, lifecycle, navigation, and framework-specific patterns for Angular, React, and Vue. Pair with the other Ionic skills in this collection for deeper topic-specific guidance like app creation, framework integration, and upgrades.
npx skillsauth add capawesome-team/skills ionic-expertInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Comprehensive reference for Ionic Framework development — core concepts, components, theming, lifecycle, navigation, framework-specific patterns (Angular, React, Vue), upgrading, and Capawesome Cloud integration.
Ionic Framework is a UI toolkit for building cross-platform apps with web technologies. It provides 80+ pre-built UI components as Web Components prefixed with ion- (e.g., <ion-button>, <ion-content>).
ios mode; Android and all other platforms use md (Material Design). The <html> element receives a class (ios or md).capacitor-app-development skill for Capacitor guidance.@ionic/angular), React (@ionic/react), and Vue (@ionic/vue).npm install -g @ionic/cli
ionic start <name> <template> --type=<framework> --capacitor --package-id=<id>
| --type value | Framework |
| -------------------- | ------------------------------- |
| angular | Angular (NgModules) |
| angular-standalone | Angular (Standalone Components) |
| react | React |
| vue | Vue |
| Template | Description |
| ---------- | --------------------------- |
| blank | Empty project, single page |
| tabs | Tab-based layout |
| sidemenu | Side menu layout |
For details, see ionic-app-creation.
Run ionic --help for the full and always up-to-date command list.
| Command | Description |
| -------------------- | ------------------------------------------------------- |
| ionic start | Scaffold a new Ionic project. |
| ionic serve | Start a local dev server with live reload (port 8100). |
| ionic build | Build the web app for production. |
| ionic generate | Generate pages, components, services (framework-dependent). |
| ionic info | Print system/environment info. |
| ionic repair | Remove and recreate dependencies and platform files. |
Useful ionic serve flags: --external (all network interfaces), --port=<port>, --prod, --no-open.
Ionic provides 80+ UI components organized by category. For full API reference (properties, events, methods, slots, CSS custom properties), see the linked reference files.
ion-app (root container), ion-content (scrollable area), ion-header, ion-footer, ion-toolbar, ion-title, ion-buttons, ion-back-button, ion-grid/ion-row/ion-col, ion-split-pane.
Key usage:
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button defaultHref="/home"></ion-back-button>
</ion-buttons>
<ion-title>Page Title</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<!-- Scrollable content -->
</ion-content>
For details, see components-layout.md.
ion-tabs, ion-tab-bar, ion-tab-button, ion-menu, ion-menu-button, ion-menu-toggle, ion-router-outlet, ion-nav, ion-breadcrumbs.
For details, see components-navigation.md.
ion-input, ion-textarea, ion-select/ion-select-option, ion-checkbox, ion-toggle, ion-radio/ion-radio-group, ion-range, ion-datetime/ion-datetime-button, ion-searchbar, ion-segment/ion-segment-button, ion-input-otp.
Key properties shared by most form components: label, labelPlacement (floating, stacked, fixed, start), fill (outline, solid), errorText, helperText, disabled, value, placeholder.
Key events:
ionInput — fires on each keystroke (use for ion-input/ion-textarea).ionChange — fires when value is committed (use for ion-select, ion-toggle, ion-checkbox, ion-range).<ion-input label="Email" labelPlacement="floating" fill="outline"
type="email" placeholder="[email protected]"
errorText="Invalid email" helperText="Enter your email">
</ion-input>
<ion-select label="Country" labelPlacement="floating" fill="outline" interface="popover">
<ion-select-option value="us">United States</ion-select-option>
<ion-select-option value="de">Germany</ion-select-option>
</ion-select>
For details, see components-form.md.
ion-modal, ion-alert, ion-toast, ion-action-sheet, ion-loading, ion-popover.
All overlays share: isOpen prop for declarative control, trigger prop to open from a button ID, backdropDismiss, animated, and lifecycle events (didPresent, didDismiss, willPresent, willDismiss).
Sheet modal (bottom sheet):
<ion-modal [isOpen]="isOpen" [breakpoints]="[0, 0.5, 1]" [initialBreakpoint]="0.5" [handle]="true">
<ion-content>Sheet content</ion-content>
</ion-modal>
For details, see components-overlay.md.
ion-list, ion-item, ion-item-sliding/ion-item-options/ion-item-option, ion-card/ion-card-header/ion-card-content, ion-accordion/ion-accordion-group, ion-chip, ion-badge, ion-label, ion-note.
For details, see components-data-display.md.
ion-refresher/ion-refresher-content (pull-to-refresh), ion-infinite-scroll/ion-infinite-scroll-content, ion-reorder-group/ion-reorder.
For details, see components-scroll.md.
ion-button, ion-fab/ion-fab-button, ion-icon, ion-avatar, ion-thumbnail, ion-spinner, ion-skeleton-text, ion-progress-bar.
For details, see components-action.md and components-media.md.
Nine default colors: primary, secondary, tertiary, success, warning, danger, light, medium, dark. Apply via the color attribute:
<ion-button color="primary">Save</ion-button>
<ion-button color="danger">Delete</ion-button>
Customize a color by overriding all six CSS variables in :root:
:root {
--ion-color-primary: #3880ff;
--ion-color-primary-rgb: 56, 128, 255;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-contrast-rgb: 255, 255, 255;
--ion-color-primary-shade: #3171e0;
--ion-color-primary-tint: #4c8dff;
}
Key variables: --ion-background-color, --ion-text-color, --ion-font-family, --ion-safe-area-top/right/bottom/left, --ion-margin, --ion-padding.
Three approaches (import from @ionic/angular/css/, @ionic/react/css/, or @ionic/vue/css/):
@import '@ionic/<framework>/css/palettes/dark.system.css';@import '@ionic/<framework>/css/palettes/dark.always.css';@import '@ionic/<framework>/css/palettes/dark.class.css'; then add .ion-palette-dark to <html>.Target platform-specific styles in CSS using the mode class on <html>:
.ios ion-toolbar { --background: #f8f8f8; }
.md ion-toolbar { --background: #ffffff; }
Preview a specific mode in the browser: http://localhost:8100/?ionic:mode=ios
12-column flexbox grid: ion-grid, ion-row, ion-col. Columns expand evenly unless size (1-12) is specified.
| Breakpoint | Min Width | Property Suffix |
| ---------- | --------- | --------------- |
| xs | 0 | Xs |
| sm | 576px | Sm |
| md | 768px | Md |
| lg | 992px | Lg |
| xl | 1200px | Xl |
.ion-padding, .ion-padding-top/bottom/start/end, .ion-no-padding.ion-margin, .ion-margin-top/bottom/start/end, .ion-no-margin.ion-text-center, .ion-text-start, .ion-text-end, .ion-text-wrap, .ion-text-nowrap.ion-display-none, .ion-display-block, .ion-display-flex.ion-justify-content-center, .ion-align-items-center, .ion-flex-row, .ion-flex-columnAll utility classes support responsive suffixes: .ion-text-md-center (applies at 768px+).
Ionic provides four lifecycle hooks that fire during page transitions. These exist because ion-router-outlet caches pages in the DOM — framework-native lifecycle hooks (ngOnInit, useEffect, onMounted) only fire once on first creation, not on every page visit.
| Hook | Fires When | Use For |
| -------------------- | -------------------------------- | -------------------------------------- |
| ionViewWillEnter | Page about to enter (pre-animation) | Refresh data on every visit |
| ionViewDidEnter | Page fully entered (post-animation) | Start animations, focus inputs |
| ionViewWillLeave | Page about to leave (pre-animation) | Save state, pause subscriptions |
| ionViewDidLeave | Page fully left (post-animation) | Clean up off-screen resources |
Critical rules:
ion-router-outlet.For full details, see ionic-angular.
Detect architecture: Check src/main.ts for bootstrapApplication (standalone) vs platformBrowserDynamic().bootstrapModule (NgModule).
| Aspect | Standalone | NgModule |
| ----------------- | ---------------------------------------------- | ------------------------------------------ |
| Ionic setup | provideIonicAngular({}) in app.config.ts | IonicModule.forRoot() in app.module.ts |
| Component imports | Each from @ionic/angular/standalone | IonicModule provides all globally |
| Lazy loading | loadComponent in routes | loadChildren in routes |
| Icons | addIcons() from ionicons required | Automatic |
Navigation: Use NavController from @ionic/angular for animated navigation (navigateForward, navigateBack, navigateRoot, back). Use routerLink with routerDirection in templates.
Lifecycle: Implement interfaces ViewWillEnter, ViewDidEnter, ViewWillLeave, ViewDidLeave from @ionic/angular:
import { ViewWillEnter } from '@ionic/angular';
@Component({ /* ... */ })
export class HomePage implements ViewWillEnter {
ionViewWillEnter() {
this.loadData(); // Runs on every page visit
}
}
For navigation details, see angular/navigation.md. For lifecycle details, see angular/lifecycle.md.
For full details, see ionic-react.
Key setup differences:
setupIonicReact() before rendering in src/main.tsx.IonReactRouter (from @ionic/react-router) instead of BrowserRouter.IonRouterOutlet to contain routes with the component prop (not render or children).IonPage as root — required for transitions and lifecycle hooks.Navigation: Use useIonRouter hook for programmatic navigation:
import { useIonRouter } from '@ionic/react';
const router = useIonRouter();
router.push('/detail/123', 'forward', 'push');
router.goBack();
Lifecycle hooks (from @ionic/react):
import { useIonViewWillEnter } from '@ionic/react';
useIonViewWillEnter(() => {
fetchData(); // Runs on every page visit
});
Overlay hooks: useIonAlert, useIonToast, useIonActionSheet, useIonLoading, useIonModal, useIonPopover, useIonPicker.
Form events: Use onIonInput for IonInput/IonTextarea, onIonChange for IonSelect/IonToggle/IonCheckbox/IonRange. Access values via e.detail.value.
For routing details, see react/routing.md. For hooks, see react/hooks.md.
For full details, see ionic-vue.
Key setup differences:
IonicVue plugin in src/main.ts: createApp(App).use(IonicVue).use(router).createRouter from @ionic/vue-router (not from vue-router).IonPage as root template element — without it, transitions and lifecycle hooks silently fail.@ionic/vue.@ion-change, @ion-input).ionicons/icons — never as strings.Navigation: Use useIonRouter composable:
<script setup lang="ts">
import { useIonRouter } from '@ionic/vue';
const ionRouter = useIonRouter();
ionRouter.push('/detail/123');
ionRouter.back();
</script>
Declarative: <ion-button router-link="/detail" router-direction="forward">Go</ion-button>
Lifecycle hooks (from @ionic/vue):
<script setup lang="ts">
import { onIonViewWillEnter } from '@ionic/vue';
onIonViewWillEnter(() => {
fetchData(); // Runs on every page visit
});
</script>
Composables: useIonRouter(), useBackButton(priority, handler), useKeyboard(), isPlatform(name), getPlatforms().
Access Web Component methods via $el: contentRef.value.$el.scrollToBottom(300).
For navigation details, see vue/navigation.md. For composables, see vue/composables.md.
Each framework uses ion-tabs with ion-tab-bar and child routes per tab. Each tab maintains its own navigation stack.
Rules:
tab attribute on ion-tab-button must match the child route path.ion-modal instead of cross-tab routing.Use ion-menu with contentId matching the id on ion-router-outlet. Wrap menu items in ion-menu-toggle to auto-close after selection. Use routerDirection="root" for top-level menu navigation.
Use non-linear routing for tabs or split-pane layouts. Use linear routing for simple page flows.
Ionic supports upgrades from version 4 through 8. Each major version jump must be applied sequentially — do not skip intermediate versions.
For full upgrade guides, see ionic-app-upgrades.
Ionic apps use Capacitor for native device features (camera, filesystem, push notifications, etc.). The standard workflow:
npm run build
npx cap sync
npx cap run android
npx cap run ios
For live reload on a device:
ionic cap run android --livereload --external
ionic cap run ios --livereload --external
For Capacitor guidance, see the capacitor-app-development skill.
Capawesome Cloud provides CI/CD services for Ionic/Capacitor apps:
Visit capawesome.io for the full Capawesome ecosystem. For setup, see the capawesome-cloud skill.
ionic: command not found: Run npm install -g @ionic/cli.@ionic/angular/standalone.ionViewWillEnter not firing: The component must be directly routed via ion-router-outlet. Child components do not receive lifecycle events. For React/Vue, verify IonPage is the root element.ionViewWillEnter) instead of framework-native lifecycle hooks (ngOnInit, useEffect, onMounted). Ionic caches pages in the DOM.NavController for Angular, IonReactRouter for React, createRouter from @ionic/vue-router for Vue). Standard framework routers do not trigger Ionic animations.--background, --color) instead of targeting internal elements.addIcons() from ionicons with the required icons and import IonIcon from @ionic/angular/standalone.Failed to resolve component: ion-* (Vue): The Ionic component is not imported. Add the import from @ionic/vue.IonRouterOutlet within IonTabs.onIonInput for IonInput/IonTextarea, not onChange. Access values via e.detail.value.'vue/no-deprecated-slot-attribute': 'off'.ionic-app-creation — Create a new Ionic app from scratch.ionic-app-development — General Ionic development, full component API reference.ionic-angular — Angular-specific patterns (standalone vs NgModule, navigation, forms, testing).ionic-react — React-specific patterns (IonReactRouter, hooks, state management).ionic-vue — Vue-specific patterns (composables, navigation, IonPage requirement).ionic-app-upgrades — Upgrade Ionic to a newer major version.capacitor-app-development — General Capacitor development.capawesome-cloud — Live updates, native builds, and app store publishing.tools
Guides the agent through setting up and using Capawesome Cloud for Capacitor and Cordova apps. Covers three core workflows: (1) Native Builds — cloud builds for iOS and Android (Capacitor, Cordova, or native projects), signing certificates, environments, Trapeze configuration, and build artifacts; (2) Live Updates — OTA updates via the @capawesome/capacitor-live-update or @capawesome/cordova-live-update plugin, channels, versioning, rollbacks, and code signing; (3) App Store Publishing — automated submissions to Apple App Store (TestFlight) and Google Play Store. Includes CI/CD integration for all workflows. Do not use for non-Capacitor, non-Cordova mobile frameworks such as React Native or Flutter.
tools
Guides the agent through installing, authenticating, configuring, and using the Capawesome CLI (@capawesome/cli). Covers installation, interactive and token-based authentication, project linking via capawesome.config.json, the full command reference (app management, native builds, live updates, certificates, environments, channels, deployments, destinations, devices), CI/CD integration with token auth and JSON output, and diagnostics via the doctor command. Do not use for Capawesome Cloud feature setup (native builds workflow, live updates workflow, app store publishing) — use the capawesome-cloud skill instead.
tools
A comprehensive starting point for AI agents to work with Capacitor. Covers core concepts, CLI, app creation, plugins, framework integration, best practices, storage, security, testing, troubleshooting, upgrading, and Capawesome Cloud (live updates, native builds, app store publishing). Pair with the other Capacitor skills in this collection for deeper topic-specific guidance.
tools
Guides the agent through migrating Capacitor apps from discontinued Ionic Enterprise SDK plugins (Auth Connect, Identity Vault, Secure Storage) to their Capawesome alternatives (OAuth, Vault, Biometrics, Secure Preferences, SQLite). Covers dependency detection, side-by-side API mapping, code replacement, and platform-specific configuration for each plugin pair. Do not use for migrating Capacitor apps or plugins to a newer version, setting up Capawesome Cloud, or non-Capacitor mobile frameworks.