Setup Ionic App

This documentation was generated with the assistance of AI. Please report any inaccuracies.

Scaffold a new Ionic (Angular or React) hybrid mobile app at the repository root using the real @ionic/cli start schematic, then layer on this catalog’s house test/lint/e2e/Sonar conventions on top of the stock starter.

Purpose

iru-setup-ionic-app bootstraps a new Ionic 9 + Capacitor 8 app — no Cordova, no Ionic Appflow — using the Ionic CLI’s own scaffold instead of a hand-rolled reimplementation of it, then wires in Vitest with v8 coverage (the Angular flavor’s @angular/build:unit-test runner, or Vite’s own runner for React), the starter’s existing ESLint flat config plus Prettier, a Playwright web-build smoke test, a Maestro on-device flow skeleton, and sonar-project.properties when opted in. Following the catalog’s UI contract (see Building user interfaces), the Playwright setup also gets a screen spec that captures HomePage across left-to-right/right-to-left × light/dark into .ui-screenshots/ with an @axe-core/playwright check at the level of a root .ui-quality.yml, and the stock starter is patched so it passes its own accessibility check. Every command and quirk documented in its SKILL.md was confirmed by actually running the exact sequence against both flavors (@ionic/cli 7.2.1, @ionic/angular/@ionic/react 9.0.4, Capacitor 8.5.2) rather than assumed from the tools' documentation alone.

Plugin

Shipped by the iru-typescript plugin of the ai-catalog marketplace (install with /plugin install iru-typescript@ai-catalog; see Plugins).

Invocation

/iru-setup-ionic-app

Inputs

Argument Required Description Default

args

No

Pre-resolved parameters passed by an orchestrating skill (e.g. a future iru-setup-ionic-app-repository or iru-setup-repository) as newline-separated key: value lines, parsed in Step 0 so this skill doesn’t ask about any field already resolved this way.

None — if absent or unrecognized, every field is asked interactively.

framework

Yes (unless supplied via args)

Which flavor to scaffold: angular or react.

None — user must choose

app-name

Yes (unless supplied via args)

Kebab-case project/directory name, used as ionic.config.json’s `name and capacitor.config.ts’s `appName.

None

app-id

Yes (unless supplied via args)

Reverse-DNS application id, e.g. com.example.myapp; overwrites the starter’s hardcoded io.ionic.starter via a cap init re-run.

None

description

No

One-line project description written into package.json’s `description field.

None

license

Yes (unless supplied via args)

Resolved via AskUserQuestion: MIT License, Apache License 2.0, No license (sets "private": true), or Other (asked for a SPDX id directly).

None — user must choose

developer-name / developer-email / organization-url

Yes (unless supplied via args)

Populate package.json’s `author field, which the starter’s template omits.

None

open-source

No

Whether the repository is open source (yes/no); drives the recommended defaults for distribution and sonar (the latter together with visibility).

None — asked first when unresolved

distribution

No

How the app reaches real devices: none, internal, or store. Recorded only, for a later iru-setup-typescript-github-workflows run — this skill never touches store/signing config.

store when open source; otherwise asked with internal recommended

sonar (+ sonar-organization/sonar-project-key/sonar-host-url)

No

Whether/how to wire up sonar-project.properties in Step 10: cloud, self-hosted, or none. cloud is recommended only for a repository that is both public and open source (SonarCloud is free only for public open-source projects, per its current pricing); otherwise none is recommended, with self-hosted SonarQube as the alternative.

cloud when public and open source; otherwise asked with none recommended

add-android

No

Whether to run npx cap add android in Step 5. Notes the Android SDK requirement if undetected.

Asked with Yes recommended

add-ios

No

Whether to run npx cap add ios in Step 5. Only offered on macOS; silently skipped elsewhere.

Asked with Yes recommended (macOS only)

visibility

No

public, private, or internal — the GitHub repository’s visibility, used only to key the sonar recommendation. internal counts as private. If open-source: yes but visibility is private/internal, the skill warns and asks which is right.

Resolved only when the sonar question is asked: gh repo view --json visibility -q .visibility, else asked (Public recommended when open source)

ci

No

yes/no — whether the run invoking this skill generates GitHub Actions workflows at all; consulted only by the sonar question. With ci: no, none is recommended for Sonar since no CI would send reports (sonar-project.properties is still written if the user picks cloud/self-hosted, and the report says so).

yes implied

accessibility

No

enforce/report/off/none — the UI tests' automated accessibility level, written to .ui-quality.yml in Step 8: enforce fails the tests on axe violations, report lists them without failing, off does not run the check; none opts out entirely: no accessibility tooling is installed and the generated templates omit accessibility attributes (asked as "None — opt out entirely"). In mode: existing a prior level is never silently flipped.

enforce (asked when unset)

on-existing

No

ask/keep/update/replace — how Step 1 treats each pre-existing artifact. keep/update/replace is applied to every one without asking (the warning is still printed); meant for scripted runs.

ask

mode

No

new or existing. existing marks the run as an update of an established repository, but never means "update silently" — Step 1 still warns and asks per pre-existing artifact unless on-existing says otherwise.

new

Outputs

  • A scaffolded Ionic app at the repository root (package.json, capacitor.config.ts, src/, framework config), moved up from a temporary sibling directory when the root wasn’t empty.

  • capacitor.config.ts re-initialized with the real app-id in place of the starter’s io.ionic.starter.

  • Vitest coverage wired into angular.json (Angular) or vite.config.ts (React), plus non-interactive test/coverage package.json scripts.

  • eslint.config.js extended with build/coverage ignores and eslint-config-prettier; .prettierrc.json and format/format:fix scripts added.

  • playwright.config.ts and e2e/smoke.spec.ts (optionally replacing the React starter’s Cypress setup), plus an e2e script.

  • UI contract files: .ui-quality.yml at the repository root (accessibility, directions, themes), e2e/support/ui-screenshots.ts (copied from the skill’s reference/ui-screenshots.ts, with @axe-core/playwright installed), and a HomePage matrix test in e2e/smoke.spec.ts that writes .ui-screenshots/screen/HomePage/default--<ltr|rtl>--<light|dark>.png. The starter’s index.html viewport, link underline, paragraph colour contrast and right-to-left inset-inline are fixed so it passes at enforce. .ui-screenshots/ must be gitignored (Setup TypeScript Gitignore adds it).

  • .maestro/smoke.yaml, an unverified on-device smoke-flow skeleton.

  • sonar-project.properties at the repository root, only when sonar is cloud or self-hosted.

  • android/ and/or ios/ native platform folders, for whichever of add-android/add-ios was Yes.

  • A report that opens by repeating the announced mode (from scratch or updating an existing setup), lists per owned artifact the action taken (created / updated / replaced / kept as is / removed) and each mismatch a kept artifact leaves with this run’s choices, the visibility used for Sonar and where it came from, every resolved value, what was included versus omitted and why, and explicit warnings to review generated files and provision Sonar/store credentials before relying on CI.

Execution flow

flowchart TD A[Start /iru-setup-ionic-app] --> B{"Step 0: args supplied?"} B -- yes --> C[Parse key: value pairs from args] B -- no --> D[Treat every field as unset] C --> E{"Step 1: Ionic project\nalready exists at root?"} D --> E E -- no --> F[Announce: scaffolding from scratch] E -- "yes or mode: existing" --> G["Announce: updating an existing Ionic project;\ndetect framework from package.json;\nSteps 4-5 skipped"] G --> H{"on-existing keep/update/replace?"} H -- yes --> I[Apply it to every existing artifact] H -- no --> J["AskUserQuestion per artifact:\nUpdate / Keep as is / Replace / Stop"] J -- Stop --> K[Report nothing changed; end] J -- other --> L I --> L F --> L["Step 2: Collect inputs (framework, app-name/id,\ndescription, developer info, license, open-source,\ndistribution, visibility, sonar, accessibility, add-android/ios)"] L --> M["Step 3: Look up dependency versions\n(npm view, Capacitor/Vitest\nversion-matching caveats)"] M --> N["Step 4: Scaffold via ionic start\n(temp-dir workaround if root non-empty);\ncap init with real app-id;\nupdate package.json"] N --> O{"Step 5: add-android /\nadd-ios resolved Yes?"} O -- android --> P["npm install @capacitor/android;\nnpx cap add android"] O -- ios --> Q["npm install @capacitor/ios;\nnpx cap add ios (macOS only)"] O -- neither --> R[Note both can be added later] P --> S Q --> S R --> S["Step 6: Wire Vitest + v8 coverage\nper flavor"] S --> T["Step 7: Extend ESLint ignores;\ninstall Prettier + config"] T --> U{"Step 8: React + Cypress present?"} U -- yes --> V["AskUserQuestion:\nreplace Cypress with Playwright\nor keep both"] U -- no --> W[Install Playwright + http-server;\nwrite config, smoke test,\nUI contract: .ui-quality.yml, capture helper,\nHomePage matrix test, starter a11y fixes] V --> W W --> X["Step 9: Write .maestro/smoke.yaml\nskeleton"] X --> Y{"Step 10: sonar resolved\ncloud or self-hosted?"} Y -- yes --> Z[Write sonar-project.properties\nwith per-flavor lcov path] Y -- none --> AA[Skip, or remove/flag an existing file] Z --> AB["Step 11: Report per-artifact actions,\nmismatches, and warnings"] AA --> AB

Dependencies

Invokes

None — iru-setup-ionic-app is a leaf skill; it does not call any other skill in this catalog. It mentions Check License, Setup TypeScript Gitignore, and Setup TypeScript GitHub Workflows in its report/warnings only, as pointers for the user to run afterward — it never calls them itself.

Invoked by

None.

Source

SKILL.md on GitHub — the file this page was generated from.