patchhub.json: downloads
patchhub.json at the root of a project tells PatchHub what people can download.
Nothing is stored ahead of time. When someone downloads, PatchHub applies the patches they picked to the version they picked, then builds it in a sandbox.
No patchhub.json yet? PatchHub's AI suggests one as a patch when a project first gets code. The maintainer can also ask for one in the project's Settings tab.
Example
{
"version": 1,
"setup": "ph-install go",
"artifacts": [
{
"id": "app",
"name": "Tasks",
"kind": "download",
"targets": [
{"id": "macos-arm64", "name": "macOS (Apple Silicon)", "build": "GOOS=darwin GOARCH=arm64 go build -o dist/tasks .", "output": "dist/tasks"},
{"id": "windows-x64", "name": "Windows (64-bit)", "build": "GOOS=windows GOARCH=amd64 go build -o dist/tasks.exe .", "output": "dist/tasks.exe"},
{"id": "linux-x64", "name": "Linux (x64)", "build": "GOOS=linux GOARCH=amd64 go build -o dist/tasks .", "output": "dist/tasks"}
]
},
{"id": "manual", "name": "Manual", "kind": "download", "output": "MANUAL.pdf"}
]
}
Fields
| Field | Where | Meaning |
|---|---|---|
version | top level | Required. The file format version: 1. |
image | top level, artifact or target | Optional Docker image to build in, e.g. golang:1.27 or node:22-slim. |
setup | top level, artifact or target | Shell command run before the build. All levels run, in that order. |
artifacts | top level | What the project offers. |
id | artifact, target | Lowercase letters, digits, dots and dashes. |
name | artifact, target | Shown to people. |
kind | artifact | download (the default, and the only kind for now). |
targets | download artifact | One entry per system or format. Leave it out for a single file. |
build | artifact or target | Shell command, run at the project root. Optional for files that are already in the code. |
output | artifact or target | The file to download. A folder ending in / is zipped. |
Download ids are artifact/target (e.g. app/macos-arm64). A project with a single artifact uses the bare target id (e.g. macos-arm64). source (the code as a .zip) always exists.
The build sandbox
- Linux x86-64, with Node, Bun, Python, git, curl and jq. There is no C compiler.
- No internet, except package registries:
proxy.golang.org,sum.golang.org,go.dev,dl.google.com,registry.npmjs.org,registry.yarnpkg.com,pypi.org,files.pythonhosted.org,index.crates.io,static.crates.io,static.rust-lang.org. ph-install go(orph-install go@1.27) installs Go from go.dev and verifies the official checksum. It's a convenience, not a requirement:setupcan be any shell command.- Each step can take up to about 5 minutes. Downloads can be up to 500 MB.
- Build commands come from the chosen version's
patchhub.json, never from a patch, so a patch can't change how things are built.
Custom images
Set image to build inside a Docker container instead of the default sandbox:
{"version": 1, "image": "golang:1.27-alpine", "artifacts": [
{"id": "app", "name": "Tasks", "targets": [
{"id": "linux-x64", "name": "Linux", "build": "GOOS=linux CGO_ENABLED=0 go build -o dist/tasks .", "output": "dist/tasks"}]}]}
- The project is mounted at
/work(the working directory).setupandbuildrun there withsh -c. - Images come from Docker Hub or GitHub's registry (
ghcr.io/...). Pin a tag or digest so builds are repeatable. - Without
image, builds run directly in the sandbox, andph-installis available.
Problems
The project's Settings tab lists problems with its patchhub.json, e.g. a missing version or an output outside the project. Entries with problems are skipped; the rest still work.