MM2-0/fdroid: The App Store That Runs on GitHub Artifacts
A self-hosted F-Droid pipeline that turns release assets and GitHub Actions builds into a browsable Android repo, with no database, no build farm, and no manual packaging loop.
- MM2-0/fdroid treats GitHub artifacts as durable distribution inputs, not disposable build leftovers.
- The repository replaces a traditional F-Droid build farm with a stateless pipeline that gathers, signs, and indexes APKs from GitHub.
- The frontend is not decoration, because `index-v2.json` becomes the whole storefront without a database or app server.
- The sharp trade-off is trust: you gain speed and control by relying on upstream binaries instead of source rebuild purity.
Most app-store projects begin with a backend. This one begins with a trust decision. MM2-0/fdroid treats GitHub as the source of packaged truth, then wraps those binaries in the plumbing F-Droid needs to look like a real repository.
The strange part is the premise
The repo does not try to be a general Android build farm. It pulls APKs from GitHub Releases or GitHub Actions artifacts, validates them, extracts metadata, signs the result, and publishes an index that F-Droid clients can read. In practice, that means temporary CI outputs are promoted into a durable catalog instead of being treated as disposable leftovers.
That is the whole trick. The configuration lives in `/config`, the ingestion logic lives in `/repo`, and the storefront lives in `/frontend`. The pipeline is narrow on purpose, which is why it feels so clean.
Why someone would want this
If you run a small Android app catalog, you may not want the full F-Droid source-rebuild model. You may already trust your GitHub releases, or you may want nightly builds without maintaining a separate build server. This project gives you a middle path: more control than a download page, far less infrastructure than a traditional F-Droid build farm.
The repo also appears tuned to a specific ecosystem, especially the Kvaesitso launcher world. That matters because the best distribution tools are usually boring to everyone except the people who need them, and this one solves a real operational edge case.
The pipeline: from artifact to repo entry
The build sequence is deliberately split into small stages. GitHub Actions prepares the machine, the repo ingests APKs, F-Droid tools generate the index, and the frontend consumes the finished JSON. There is no database in the middle, just files moving through a controlled chain.
The implementation details reinforce the same idea. `gh-release-source.ts` pulls release APKs, while `gh-action-source.ts` turns successful workflow artifacts into first-class inputs and can synthesize changelogs from commit ranges. `node-apk` extracts package metadata from the binary itself, and `fdroidserver` turns the result into the repository index.
scripts/setup.sh
scripts/populate.sh
scripts/build.sh
frontend/scripts/build.sh
The cleverest trick: nightly builds without a build farm
`gh-action-source.ts` is the most interesting file in the repo because it treats CI output as a distribution channel. Instead of waiting for a source build, it can publish the artifact that already exists, then label it as a stable or nightly track depending on the source and metadata. That is a practical answer to the question most app maintainers eventually ask: how do we ship fast without adding another server?
The clever bit is not only speed. The source can also derive a changelog by comparing commit SHAs between runs, which means the nightly track is still legible to humans. The result is a repo that feels current without turning into a manual packaging treadmill.
Why the frontend matters
The SvelteKit frontend is doing real work, not cosmetic work. It reads `index-v2.json`, flattens the F-Droid data model into something browseable, and serves the whole experience from static hosting. That keeps the system cheap to run and easy to deploy, because the UI is just another generated artifact.
This is why the architecture feels unusually tight. The backend produces files, the frontend consumes files, and GitHub Pages can host the result. There is nowhere for state to accumulate except the repository itself.
What this replaces
| Dimension | Standard F-Droid model | MM2-0/fdroid |
|---|---|---|
| Source of truth | Upstream source code and F-Droid recipes | GitHub releases, Actions artifacts, and YAML config |
| APK provenance | Rebuilt from source by the F-Droid build system | Imported from upstream binaries |
| Build responsibility | Central F-Droid infrastructure compiles and signs | This repo's workflow assembles, signs, and indexes |
| Update cadence | Bound to recipe maintenance and build queue timing | Bound to upstream releases and CI output |
| Trust model | Trust the source rebuild path | Trust the upstream binary and GitHub artifact integrity |
| Infra required | Build servers, metadata upkeep, and storage | Static hosting plus GitHub Actions, with no database |
| Frontend delivery | Client apps browse repository data | SvelteKit storefront reads `index-v2.json` |
| Best for | Canonical FOSS distribution with source rebuild discipline | Private, semi-public, or CI-led app catalogs |
The real trade-off
This repository is compelling because it makes its trade-offs explicit. You get control, speed, and a clean static deployment model, but you also accept the risks of upstream binaries, GitHub availability, and the maintenance cost of a custom pipeline. That is not a flaw. It is the point.
In other words, MM2-0/fdroid is less a toy repo than a distribution thesis. It says GitHub can be more than source control, and that a carefully designed file pipeline can stand in for a much heavier app-store backend when the problem is narrow enough.





