The complete step-by-step guide to converting any web app into a signed, production-ready Android APK using Capacitor 6 and Android Studio.
Your web app should be a self-contained folder with an index.html. Capacitor wraps your built output, so make sure your app works in a browser first.
# Your project structure my-app/ ├── index.html # entry point ├── css/ │ └── style.css ├── js/ │ └── main.js └── assets/ # images, icons
./css/style.css not /css/style.css.Install the Capacitor CLI and core library in your project.
# Install Node.js from nodejs.org (LTS version) # Then in your project folder: npm init -y npm install @capacitor/core npm install -D @capacitor/cli
node -v to check your version.Run the Capacitor init command to configure your app's name, ID, and web directory.
npx cap init # You will be prompted for: ? App name: My App ? App ID: com.example.myapp ? Web directory: . (or 'dist', 'www', 'build')
This creates capacitor.config.json in your project root:
{
"appId": "com.example.myapp",
"appName": "My App",
"webDir": ".",
"server": {
"androidScheme": "https"
}
}Install the Capacitor Android package and run the add android command to generate the native Android project.
npm install @capacitor/android npx cap add android
This creates an android/ folder in your project — a full native Android Studio project wrapping your web app.
android/
├── app/
│ ├── src/main/
│ │ ├── assets/ # your web files go here
│ │ └── AndroidManifest.xml
│ └── build.gradle
├── build.gradle
└── gradle.propertiesCopy your web files into the Android project and open it in Android Studio.
# Copy web files + sync plugins npx cap copy android npx cap sync android # Open in Android Studio npx cap open android
npx cap sync android before rebuilding.A keystore is required to sign your APK for release. Generate one with the Java keytool command (included with Android Studio's JDK).
keytool -genkey -v \ -keystore release.jks \ -alias myapp \ -keyalg RSA \ -keysize 2048 \ -validity 10000 # You'll be prompted for: Enter keystore password: xxxxxxxx Re-enter new password: xxxxxxxx What is your first and last name? John Doe What is your organization? MyCompany What is your country code? US
release.jks and the password securely. If you lose the keystore you cannot update the app on the Play Store. Never commit it to git.Edit android/app/build.gradle to configure the release signing config.
android {
signingConfigs {
release {
storeFile file("../../release.jks")
storePassword "your_keystore_password"
keyAlias "myapp"
keyPassword "your_key_password"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
}
}
}local.properties (which is git-ignored) instead of hardcoding them in build.gradle. Use def props = new Properties(); props.load(file("../local.properties").newInputStream()) to read them.Build the release APK from the command line or via Android Studio's Build menu.
# From your project root — sync first npx cap sync android # Navigate into the android folder and build cd android ./gradlew assembleRelease # builds APK ./gradlew bundleRelease # builds AAB (Play Store)
Output files:
# APK (for direct installation): android/app/build/outputs/apk/release/app-release.apk # AAB (for Google Play Store): android/app/build/outputs/bundle/release/app-release.aab
You now have a signed APK ready for distribution.
.aab bundle fileCreate android/local.properties with sdk.dir=C:\\Users\\YourName\\AppData\\Local\\Android\\Sdk
All file paths must be relative. Also check capacitor.config.json — the webDir must point to the folder containing your index.html.
Uninstall the previous version of the app from the device before installing the new APK (especially if signed with a different keystore).
Add <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> to AndroidManifest.xml and request permission at runtime.
All apps in our collection were built with this exact Capacitor workflow. Download one and try it on your device.