Phase 2
Add Capacitor
Wrap the web app in a native project
This is the mechanical part: install Capacitor, name the app, generate the Android project, and get it running on an emulator and a real phone. Fill in your app details once below and every command on this page uses them.
Configuration generator
Saved in this browser and substituted into every command and snippet in the guide.
import type { CapacitorConfig } from "@capacitor/cli";
const config: CapacitorConfig = {
appId: "com.example.myapp",
appName: "My App",
webDir: "dist",
android: {
allowMixedContent: false,
},
ios: {
contentInset: "always",
},
plugins: {
SplashScreen: {
launchAutoHide: false,
backgroundColor: "#ffffff",
androidScaleType: "CENTER_CROP",
showSpinner: false,
},
Keyboard: {
resize: "body",
resizeOnFullScreen: true,
},
},
};
export default config;
npm install @capacitor/core
npm install -D @capacitor/cli
npx cap init "My App" "com.example.myapp" --web-dir "dist"This writes capacitor.config.ts at the project root. Replace its contents with the generated version from Your app details above so the settings are explicit and reviewable.
npm install @capacitor/android
npm run build
npx cap add android
npx cap sync androidcap add scaffolds the native project once. cap sync is what you run from then on: it copies your latest web build into the native project and installs/updates native plugin code.
| Command | Does |
|---|---|
npx cap copy | Copies web assets only — fast, use after a pure UI change |
npx cap update | Updates native plugin dependencies only |
npx cap sync | Both — use this by default |
npx cap open android | Opens the project in Android Studio |
{
"scripts": {
"native:sync": "npm run build && npx cap sync",
"native:android": "npm run build && npx cap sync android && npx cap open android",
"native:ios": "npm run build && npx cap sync ios && npx cap open ios"
}
}Commit android/ (and later ios/) to git. They contain your icons, permissions, signing configuration and version numbers — regenerating them loses all of it. What you must never commit is your keystore or any password.
# Never commit signing material
*.keystore
*.jks
key.properties
android/keystore.properties
# Build output
android/app/build/
android/build/
android/.gradle/
ios/App/build/
ios/App/Pods/- Run
npx cap open androidto open Android Studio. - Wait for the Gradle sync in the status bar to finish — the first one downloads a lot and can take several minutes.
- Open Device Manager and create a virtual device (Pixel 7, latest system image).
- Press Run. Your app should appear full screen.
- On the phone: Settings → About phone → tap Build number seven times to unlock Developer options.
- In Developer options enable USB debugging.
- Connect by USB and accept the debugging prompt on the phone.
- Confirm the device is visible, then run from Android Studio.
adb devices # your phone should be listed as "device"Always test the real device before release. Emulators hide performance problems, keyboard behaviour, gesture navigation and camera/permission flows.
For fast iteration you can point the shell at your dev server instead of the bundled files. Both machines must be on the same network.
server: {
url: "http://192.168.1.50:8080", // your machine's LAN IP
cleartext: true,
},