Ship an OpenWrt package without building it 35 times
Two Go binaries. One develops and tests your package on throwaway routers; the
other signs it and turns a directory into a feed users can apk add. They work on
both release lines — apk on 25.12 and later, opkg on 24.10 and earlier.
Which of these are you?
A router owner
You want to install something from a feed. One command.
A package author
You wrote a LuCI app or theme and want people to install it.
Running a feed
You need the commands, the config fields and the terms.
The two tools
| Tool | Answers | Holds keys |
|---|---|---|
owlab | Does the package work? Starts real OpenWrt routers in Docker, installs your package, checks the page loads. | Never |
owfeed | Can anyone trust these bytes? Signs packages, builds a signed index, checks the result before it goes out. | Yes |
Neither depends on the other. They agree on one thing: a directory called dist/
with one subdirectory per architecture. Anything that fills it correctly works with everything
downstream — including a plain OpenWrt SDK build.
Install
go install owfeed.org/owlab/cmd/owlab@latest go install owfeed.org/owfeed/cmd/owfeed@latest
Or download a release binary and check it against the attestation GitHub produced for it:
gh release download v0.5.1 -R owfeed/owfeed -p 'owfeed-linux-amd64' gh attestation verify owfeed-linux-amd64 -R owfeed/owfeed \ --signer-workflow owfeed/owfeed/.github/workflows/release.yml chmod +x owfeed-linux-amd64 && sudo mv owfeed-linux-amd64 /usr/local/bin/owfeed
In GitHub Actions, owfeed/owfeed/setup@v0.5.1 and
owfeed/owlab/setup@v0.6.0 do that check for you.
What you need
| For | Requirement |
|---|---|
owlab, anything | Docker, Podman, OrbStack, Colima or Rancher Desktop, with Compose v2 |
owlab with fidelity: vm | QEMU as well — brew install qemu |
owfeed build/sign/index/publish | Nothing. The apk toolchain is fetched from the OpenWrt SDK and verified against a pinned key |
owfeed smoke, and owfeed build on macOS | Docker |
Do you need a feed at all?
Probably not, and it is worth deciding before you build one.
A key in /etc/apk/keys is a trust anchor for every package name,
not just yours. A feed whose key leaks can offer a higher version of dropbear and
win, and apk has no revocation.
| Your situation | What to do |
|---|---|
| One package people install occasionally | Publish signed release artifacts. owfeed release does that, and your users check one signature. |
Several packages, or you want apk upgrade to work | A feed. It is the only thing that upgrades, because apk upgrades from an index. |
| You want the second without running one | Ask owfeed-packages to carry your package. |
Why not the OpenWrt SDK action?
openwrt/gh-action-sdk compiles a package from source. owfeed packages one that is
already built. Most third-party packages — themes, LuCI apps, scripts, static binaries — do not
need compiling at all, and for those the SDK is 35 builds to produce something a single pass
could have made.
| gh-action-sdk | owfeed | |
|---|---|---|
| Noarch across 35 architectures | 35 SDK builds | one pass, ~25 seconds |
| Signed index | — | apk and opkg |
| Signing key | written into the build tree | never enters the build job |
| Proof it installs | — | owfeed smoke, on a real image |
If your package is compiled C, use the SDK — then hand its output to owfeed.
Read next
- Ship your package — build, test, sign, publish, step by step
- Commands and config — every command, the config fields, a glossary
schema/v1.json— theowfeed.ymlschema, generated from the code- ECOSYSTEM.md — where the boundary between the tools runs, and why
- apk-behaviour.md — what apk and opkg actually do, with reproductions