Detection happens on the agent
Relay inspects the uploaded repo snapshot on the server. Plugins are applied there, so every deploy for that agent sees the same framework support.
Relay buildpack plugins are JSON definitions stored on the agent. They participate in framework detection before the built-in buildpacks, then render a Dockerfile template when they match. Operators can install them from local files, pasted JSON, catalog search, or verified HTTPS URLs.
relay plugin search astro
relay plugin install ./plugins/astro-static.json \
--url http://127.0.0.1:8080 \
--token YOUR_TOKEN
relay plugin install-url https://example.com/plugins/astro-static.json \
--sha256 <hex>
relay plugin list --url http://127.0.0.1:8080 --token YOUR_TOKENThis is deliberately smaller than a generic code plugin system. The agent needs enough information to decide whether the plugin matches a repo and how to build and run that repo if it does.
Relay inspects the uploaded repo snapshot on the server. Plugins are applied there, so every deploy for that agent sees the same framework support.
Plugins are prepended ahead of built-ins. Higher priority wins, so a plugin can override the default behavior for a specific framework shape.
A plugin does not bypass the rest of Relay. It still resolves to a build image, run image, service port, and rendered Dockerfile.
Remote plugin installs are owner-only, require HTTPS, and can be pinned with SHA256 so the server verifies the exact JSON before it writes anything under data/plugins/buildpacks.
A plugin install is an authenticated API write to the agent. In production, leave plugin mutation off unless you are actively curating framework support.
Set `RELAY_ENABLE_PLUGIN_MUTATIONS=true` only while administering plugins.
Install from a JSON file, paste JSON in the owner dashboard, use catalog search, or use `relay plugin install-url <https-url> --sha256 <hex>` for a verified remote source.
Use `relay plugin list`, the owner dashboard Plugins tab, or `GET /api/plugins/buildpacks` to inspect the live set.
Once the plugin is installed, the agent still loads it even after you disable further mutations.
GET /api/plugins/buildpacks
POST /api/plugins/buildpacks
POST /api/plugins/buildpacks/install-url
DELETE /api/plugins/buildpacks/:nameBuilt-ins cover the most common stacks. Plugins run first and can override detection for any of them. If detection lands on a built-in, the agent renders its Dockerfile and runs the build with no additional config.
Next.js apps detect next in package.json and build with next build.
Vite-based SPAs match vite in package.json and output a static dist/.
Expo web targets detect expo in package.json and run web builds.
Sprint UI apps detect Sprint UI signals and render the expected web build plan.
Bun apps detect bun.lock or Bun package usage and build with Bun-aware commands.
Any Node.js project with a start script and no framework-specific signal.
Go modules detect go.mod, cross-compile, and run the resulting binary.
ASP.NET Core apps detect .csproj and build with dotnet publish.
Python apps, including Flask and FastAPI, detect pyproject.toml or requirements.txt.
Rails and Rack apps detect Gemfile and run the Ruby build and boot path.
Maven or Gradle projects detect pom.xml or build.gradle and package a JAR.
Rust binaries detect Cargo.toml and build in release mode.
C and C++ projects detect a Makefile and compile with make.
WebAssembly targets compiled to static files detect wasm-pack or similar.
Pure static sites use any directory with an index.html and no build step.
An explicit repo-relative Dockerfile or an auto-detected nested Dockerfile under the selected app roots overrides all detection.
The current plugin model is deliberately narrow. Future types extend it without changing how existing buildpack plugins work.
relay ci test and relay ci lint would run typed check steps against the uploaded snapshot before the build starts. Plugins supply the command, image, and pass/fail rule.
The next missing layer is upgradeable plugin packages with version tracking, not basic discovery. Search already exists today, but there is still no plugin upgrade flow or signed release channel.
HTTPS and optional SHA256 cover transport and integrity, but Relay still lacks catalog signatures, allowlists, and richer trust policy for remote plugin sources.
relay build --target linux-amd64 would separate the build artifact from the image, enabling multi-arch deployments and pre-built binaries without re-running the full build for each target.