🧱 Build once. ♻️ Reuse everywhere.
Once turns repository automation into typed, cacheable actions that humans and coding agents can discover, run, and reuse. Give every action explicit inputs, outputs, and environment, and Once content-addresses the result so it only ever runs when something actually changed, locally or on a shared cache, across developers, coding agents, continuous integration, and machines.
- 🧱 Build once: declare inputs, outputs, and environment; results are content-addressed.
- ♻️ Reuse everywhere: restore outputs instantly from a local or shared cache.
- 🚀 Run anywhere: send only the declared inputs to a fresh local or hosted sandbox.
- 🤖 Agent-native: a built-in Model Context Protocol server lets coding agents discover and run actions.
- 🌍 Multi-ecosystem: native support for Apple, Android, Kotlin, Rust, Go, C/C++, Elixir, Ruby, JavaScript, Zig, and more.
Install the current release with mise:
mise use -g "github:tuist/once@$(mise latest github:tuist/once)"
mise exec -- once --versionUse mise use github:tuist/once@... inside a repository when the project
should pin Once in its own mise.toml.
Once includes a Model Context Protocol server. Add it to a coding harness that supports servers over standard input and output, and start it through mise so global installs and project pins both work:
{
"mcpServers": {
"once": {
"command": "mise",
"args": [
"-C",
"/absolute/path/to/your/project",
"exec",
"--",
"once",
"mcp",
"--workspace",
"/absolute/path/to/your/project",
"--allow-run"
]
}
}
}Remove --allow-run if the harness should not edit manifests, build, test,
run, or start runtime sessions.
Then ask the harness something like:
Use Once to initialize this directory as a Rust binary package. Discover the
available target kinds, fetch the Rust binary starter, create the files, and
build the target.
The harness discovers target kinds, fetches starter metadata, materializes it, validates the graph, and verifies the result, all through live discovery. The same loop supports a request such as "build an Android app with Once." See the coding harness guide for typed graphs, annotated scripts, result checks, and project memory.
Add a small contract to an existing script so Once knows the inputs, outputs, environment, and working directory that shape the action:
#!/usr/bin/env bash
# once input "../assets/**/*"
# once output "../dist/"
# once cwd ".."
npm run build-assetsRun it as a cached action, locally or on a remote sandbox:
once exec -- bash scripts/build-assets.sh
once exec --remote --compute microsandbox -- bash scripts/build-assets.shScripts can also run directly with a Once shebang:
#!/usr/bin/env -S once exec -- bashRead the full documentation at buildonce.dev/docs. A few good starting points:
Once is open source under the MIT License.
