Or: How I Learned to Stop Worrying and Embrace 47 Dependencies
TL;DR: I had a perfectly functional HTML file. It worked in every browser. It was beautiful. Then I decided to turn it into an Android app.
Chapter 1: The Innocence
It started so simply. I had a web page. Just HTML, CSS, and JavaScript. It worked. It was fast. It was elegant. It embodied the KISS principle – Keep It Simple, Stupid.
“I should turn this into an Android app,” I thought, with the blissful ignorance of someone who’s never done this before.
“Apache Cordova makes it easy!” the internet promised. “Just wrap your web app in a native container!”
Narrator: It would not be easy.
Chapter 2: The Descent Begins
First, I needed to install some software. Just a few things:
- Node.js (but not just any Node.js – the LTS version via nvm)
- npm (comes with Node, but you need to know that)
- Java JDK (OpenJDK 17 specifically, not 16, not 18)
- Android SDK Command Line Tools (11,076,708 bytes of “simplicity”)
- Android Platform Tools
- Android Build Tools (version 34.0.0, or wait, maybe 35.0.0?)
- Gradle (the build system that builds build systems)
- Apache Cordova itself
Each of these requires setting environment variables. ANDROID_HOME, JAVA_HOME, PATH modifications. Your .bashrc file, once a pristine 10 lines, is now a novel.
Installation time: 45 minutes
Lines of bash script to automate this: 200+
Times I questioned my life choices: 7
Chapter 3: Version Hell
“Let’s create a Cordova project!” I said, still optimistic.
cordova create myapp com.example.myapp MyApp
This worked! Hope surged through my veins.
cordova platform add android
This also worked! I was unstoppable!
cordova build android
FAILURE: Build failed with an exception.
* What went wrong:
No usable Android build tools found. Highest 35.x installed version is 34.0.0;
Recommended version is 35.0.0.
Ah yes. Version incompatibility. The universal language of software development.
But wait, there’s more:
- Cordova Android 14.0.1? Doesn’t work.
- Cordova Android 13.0.0? Still has issues.
- Cordova Android 12.0.1? NOW we’re talking!
Time spent googling error messages: 1.5 hours
Number of Stack Overflow tabs open: 23
Faith in humanity: Declining
Chapter 4: The Mystery of the Missing gradlew
In the Java/Android world, there’s a magical file called gradlew. It’s the Gradle Wrapper. It’s supposed to be automatically generated when you add the Android platform.
Mine was not.
Was it user error? A cosmic alignment issue? Mercury in retrograde? Nobody knows.
I tried:
- Removing and re-adding the platform (3 times)
- Manually downloading gradle wrapper jars
- Creating gradlew by hand (spoiler: I corrupted it)
- Questioning the fundamental nature of reality
Eventually, we just used the system Gradle directly. Why have a wrapper when you can have… no wrapper?
Philosophical crises experienced: 2
Files manually created that should have been automatic: 4
Gradle daemon restarts: Too many to count
Chapter 5: The Config File Chronicles
Every Cordova project has a config.xml. This file is supposed to configure your app. Simple, right?
Wrong.
My automatically generated config.xml referenced:
- Splash screens that don’t exist
- Icons that were never created
- A network security config file that was definitely not included
- Preferences that were deprecated two versions ago
Each missing file produced a warning. Or an error. Sometimes both! Russian roulette for your build process.
The solution? Manually create every missing file, or delete every reference to them. Choose your own adventure!
<icon src="www/res/icon/android/drawable-hdpi-icon.png" density="hdpi" />
File not found.
<resource-file src="resources/android/xml/network_security_config.xml" ... />
File not found.
The "<splash>" tags were detected and are no longer supported.
Then why are they IN THE DEFAULT CONFIG FILE?
Time spent editing XML: 30 minutes
Nostalgia for simpler times (like yesterday): Intense
Urge to just email the APK to myself: Growing
Chapter 6: Build Tools: A Version Odyssey
Let’s play a game called “Which Build Tools Version Do You Actually Need?”
- The error said version 35.0.0
- I had version 34.0.0
- The config wanted version 34
- Cordova defaulted to version 35
- The internet suggested version 33
The solution? Edit cdv-gradle-config.json to use version 34. Because manually specifying versions in a configuration file is EXACTLY what “easy cross-platform development” means.
{
"BUILD_TOOLS_VERSION": "34.0.0"
}
Then the build still failed because of an “ambiguous method overloading” error in Cordova’s own code. The fix? Downgrade Cordova Android from 14.0.1 to 13.0.0. Then to 12.0.1 when 13 also had issues.
Versions tried: 4
Versions that worked: 1
Sense of accomplishment: Replaced by exhaustion
Chapter 7: The Network Security Config That Time Forgot
Finally, a real error with a real solution:
ERROR: resource xml/network_security_config not found
This file is supposed to tell Android that your app can make network requests. A reasonable thing for a web app to need. But Cordova doesn’t create it by default.
The solution? Manually create the file:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
Put it in: platforms/android/app/src/main/res/xml/
A path so intuitive, so obvious, that only someone who’s memorized the entire Android project structure would know it.
Time to find the solution: 15 minutes
Time to implement it: 30 seconds
Ratio of searching to doing: 30:1
Chapter 8: Victory (?)
After installing seven pieces of software, resolving four version conflicts, creating three missing files, and downgrading two packages, I ran:
gradle assembleDebug
And it worked.
BUILD SUCCESSFUL.
My HTML file, which was 50 lines of perfectly functional code, was now wrapped in:
- 501 directories
- 2,978 files
- Several hundred megabytes of dependencies
- A build process that takes 2 minutes
The APK installed on my phone. The app launched. It displayed my HTML file.
Exactly as it had in the browser 3 hours ago.
Epilogue: Lessons Learned
What the KISS Principle Says: “Keep it simple, stupid. Use the simplest solution that works.”
What I Actually Did:
- Installed a JavaScript runtime to run a build tool
- Installed a Java runtime to run another build tool
- Installed an SDK to compile Android apps
- Installed a framework to wrap web apps
- Installed a package manager to manage the framework
- Installed a version manager to manage the package manager
- Spent 3 hours debugging version conflicts
- Manually created files that should have been automatic
- Downgraded software because newer isn’t always better
The Punchline: I could have just:
- Added a
manifest.jsonto my HTML file (5 minutes) - Made it a Progressive Web App
- Had Android prompt users to “Add to Home Screen”
- Called it a day
But where’s the adventure in that?
Appendix A: The REAL KISS Solution
Want to turn your web app into an Android app the KISS way?
Option 1: PWA (Progressive Web App)
- Create a
manifest.json:
{
"name": "My App",
"short_name": "App",
"start_url": "/",
"display": "standalone",
"icons": [{"src": "icon.png", "sizes": "192x192"}]
}
- Add to your HTML:
<link rel="manifest" href="manifest.json">
- Done. Users can “Add to Home Screen” from their browser.
Time required: 5 minutes
Dependencies installed: 0
Version conflicts resolved: 0
Sanity preserved: 100%
Option 2: Just Use the Browser Your HTML file already works in every mobile browser. Maybe just… use that?
Appendix B: What I Actually Learned
- Cordova is powerful – When it works, it gives you access to native device features
- Cordova is complex – The toolchain is fragile and version-sensitive
- Documentation is optimistic – “Easy!” means “Easy if everything goes perfectly”
- The KISS principle exists for a reason – Complexity is exponential
- Sometimes the simple solution is the right solution – A PWA would have been fine
Conclusión
I now have an Android app. It works. It’s installed on my phone. Mission accomplished.
Was it worth it? That depends. Do you measure worth in:
- Time spent? No.
- Lines of code written? Definitely no.
- Software dependencies added? Please no.
- Character building through adversity? …Maybe?
Would I do it again?
Ask me after I’ve recovered from this trauma.
Final Stats:
- Total time: 3+ hours
- Coffee consumed: 2 cups
- Software packages installed: 7 major, 50+ dependencies
- Error messages encountered: 15+
- Successful builds: 1
- Lines of HTML that needed to become an app: 50
- Times I considered just using the browser: 12
- KISS principle violations: All of them
This blog post was written in Markdown, compiled to HTML, and viewed in a browser – a process that took 30 seconds and required zero dependencies. The irony is not lost on me.
After thoughts
I had another web site I wanted to turn into an app and the second time around was much easier, but still had some issues. I created a folder with a “www” subfolder with the files in it. But when you create a cordova project it overwrites those. So you have to first create the project and then move your html into the www folder. But overall it was pretty painless the second time around.
