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).bash
npm install -g @ionic/cli
ionic start <name> <template> --type=<framework> --capacitor --package-id=<id>
--type valueFrameworkangularAngular (NgModules)angular-standaloneAngular (Standalone Components)reactReactvueVueTemplateDescriptionblankEmpty project, single pagetabsTab-based layoutsidemenuSide menu layout
For details, see ionic-app-creation.
Run ionic --help for the full and always up-to-date command list.
CommandDescriptionionic startScaffold a new Ionic project.ionic serveStart a local dev server with live reload (port 8100).ionic buildBuild the web app for production.ionic generateGenerate pages, components, services (framework-dependent).ionic infoPrint system/environment info.ionic repairRemove 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:
html
<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).html
<ion-input label="Email" labelPlacement="floating" fill="outline"
type="email" placeholder="you@example.com"
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):
html
<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:
html
<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:
css
: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>:
css
.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.
BreakpointMin WidthProperty Suffixxs0Xs``sm576pxSm``md768pxMd``lg992pxLg``xl1200pxXl
.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.
HookFires WhenUse ForionViewWillEnterPage about to enter (pre-animation)Refresh data on every visitionViewDidEnterPage fully entered (post-animation)Start animations, focus inputsionViewWillLeavePage about to leave (pre-animation)Save state, pause subscriptionsionViewDidLeavePage 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).
AspectStandaloneNgModuleIonic setupprovideIonicAngular({}) in app.config.ts``IonicModule.forRoot() in app.module.tsComponent importsEach from @ionic/angular/standalone``IonicModule provides all globallyLazy loadingloadComponent in routesloadChildren in routesIconsaddIcons() from ionicons requiredAutomatic
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:
typescript
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:
typescript
import { useIonRouter } from '@ionic/react';
const router = useIonRouter();
router.push('/detail/123', 'forward', 'push');
router.goBack();
Lifecycle hooks (from @ionic/react):
typescript
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:
vue
<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):
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:
bash
npm run build
npx cap sync
npx cap run android
npx cap run ios
For live reload on a device:
bash
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.