Vibecoding — two repositories to start from
Let an agent start an Android app from nothing and it will spend its effort on Gradle wrappers, SDK versions, keystores and a CI workflow — and produce something that builds on one machine and nowhere else. None of that is the app. It is the same scaffolding every project needs, so it lives in a base repository instead, already working.
“Copy the example closest to what you want, rename the identity, run the build script.” — the whole workflow, both repositories
A generic Android build system where every APK is built inside a Docker or Podman image. The host machine never needs a JDK, Gradle or the Android SDK — the container carries all of it, so a fresh laptop builds the same bytes as CI does.
Apps live in parallel, fully self-contained directories under
apps/, sharing nothing but the builder image and the
Gradle cache. That means two apps can use different languages, SDK
levels or plugins without interfering — and both
build.sh and GitHub Actions discover them
automatically, so adding an app never means editing the workflow.
| Host needs | podman or docker, nothing else |
|---|---|
| Versioning | Derived from git, never hand-edited: versionCode is the commit count, versionName is git describe. Tag v1.2.0 and that commit builds as 1.2.0; three commits later it is 1.2.0-3-g<sha>. |
| Signing | One shared keystore generated on first run, so signatures never change between machines and adb install -r upgrades always work. Swap in a private key via repo secrets when it matters. |
| CI | Discovers apps/ into a build matrix, builds debug and release per app, verifies signatures with apksigner, and publishes a rolling latest pre-release plus permanent tagged releases. |
| Examples | hello-java, hello-kotlin, and hello-scala — the last one showing how to get a JVM language the Android plugin does not support into an APK. |
The reason it is on this page: the conventions are uniform enough that an
agent can add a working, signed, versioned, CI-built app without
touching the build system. The prompt is genuinely as short as
“copy apps/hello-kotlin to apps/tip-calc,
make it a tip calculator, verify with ./build.sh tip-calc”
— and the README spells out the ground rules an agent should follow,
which is the part most templates leave to guesswork.
A minimal Bevy starter game in Rust that already ships to Linux, Windows, Android and the browser from a single Linux development machine. The base game is a sphere you drive around a 3D arena — WASD to move, space and control to fly, drag to orbit the camera, and solid pillars that knock you back with a pitch-varied sound, which exists to prove the collision response and the audio pipeline work on every target.
All the game code lives in src/lib.rs; a tiny
src/main.rs wraps it for desktop and the same crate
compiles as a cdylib for Android and to WebAssembly
for the browser. One codebase, four artifacts, no per-platform
forks.
| Linux | Native cargo run |
|---|---|
| Windows | Cross-compiled from Linux with MinGW — no Windows machine required |
| Android | cargo apk builds the cdylib into an APK with no Java at all; a Gradle path exists as an alternative |
| Browser | wasm32 plus wasm-bindgen into a static site you can host anywhere |
| Releases | version.txt is the single source of truth; CI builds all platforms and publishes a tagged GitHub Release, and deploys the browser build to Pages as a live demo |
Cross-platform Rust games fail on details that are miserable to
rediscover, so GameBase writes them down and keeps them working: assets
are embedded into the binary because Android has no loose filesystem for
Bevy's asset server; Android audio needs a specific cpal
feature that links the right C++ runtime; the browser build needs a
random-number backend flag and a wasm-bindgen CLI matching the crate
version exactly. Each of those is an afternoon lost, once.
There is also a setup_env.sh --check that tells you what
your machine is missing before you build anything, and installs only the
missing pieces if you let it — because the worst part of trying a
new stack is discovering the requirements one error at a time.
The bases are the reason the software library
can be free. Nobody is paying for the hours a project would otherwise
burn on packaging and release plumbing, because those hours were spent
once and are now a git clone. What is left to do on a new
project is the part that is actually interesting, which is the part that
gets done for its own sake.
Both repositories are public, both are free, and neither wants anything from you. Fork them, strip the examples, keep the build system, and never tell us about it — see ideal number four.