Thanks to visit codestin.com
Credit goes to buildonce.dev

Getting Started

This guide installs Once, runs one cacheable script, and shows how to choose the next path for your repository.

Installation#

Install the current release with mise:

bash
mise use -g "github:tuist/once@$(mise latest github:tuist/once)"
mise exec -- once --version

Use mise use github:tuist/once@... without -g when a repository should pin its own Once version in mise.toml.

The remaining examples assume that mise is active in your shell. If it is not, prefix each once command with mise exec --.

Try an Existing Project#

If the repository already uses Cargo, Swift Package Manager, Xcode, or Bazel, try it before writing Once configuration:

bash
cd path/to/project
once query targets
once build
once test
once lint

Once recognizes the native workspace from its existing files. once build, once test, and once lint each default to the workspace's own targets: the build fans out over every workspace-owned target that exposes build, the test run selects first-party tests, and lint runs every workspace-owned target that exposes lint. No once.toml is created.

Pass --all to any of the three to include targets reached through resolved dependencies; once lint --all in particular will lint vendored third-party code, so pair it with --fail-on error when you want to keep the noise manageable. Pass --ui to once build or once test on one explicit target to follow the live graph in the Runs interface. See Graph guide for the full workspace-owned rule (and its current heuristic limitations) and the per-ecosystem behavior.

Continue with the matching guide for Rust, Swift Packages, Xcode Projects, or Bazel for prerequisites, native dependency behavior, and current boundaries.

Run a Cacheable Script#

Create scripts/greet.sh in a repository:

bash
#!/usr/bin/env -S once exec -- bash
# once input "../message.txt"
# once output "../build/greeting.txt"
# once cwd ".."
set -eu
mkdir -p build
cp message.txt build/greeting.txt
cat build/greeting.txt

Create message.txt, make the script executable, and run it:

bash
printf 'hello from Once\n' > message.txt
chmod +x scripts/greet.sh
./scripts/greet.sh
cat build/greeting.txt

The first invocation ends with a trailer containing cache miss. Run the same command again:

bash
./scripts/greet.sh

The second trailer contains cache hit. Once reused the recorded result and restored the declared output without running the script body again.

Change message.txt and run the command once more. The input changed, so Once reports another miss and records the new output.

What Once Learned#

The three # once lines form the action contract:

  • input tells Once which files affect the result.
  • output tells Once what to capture and restore.
  • cwd chooses the working directory for the script.

The script itself is also part of the cache key. Changing either the script or its declared input causes the work to run again.

Choose Your Next Path#

  • Continue with Scripted automation when you want to cache existing repository scripts with minimal changes.
  • Continue with the Graph guide when you want typed targets, dependencies, and capabilities that Once and coding agents can query. Its Linting guide turns analyzer reports into cacheable, normalized findings with an explicit failure policy.
  • Continue with the software development kit overview when an application needs direct access to Once cache primitives.
  • Read Infrastructure after the local flow works and you are ready to share cache entries or run actions remotely.