> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sifr.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# sifr build and sifr run: Compile and Execute Sifr Programs

> Use sifr run to compile and execute in one step, or sifr build to produce a standalone native binary — with full flag reference and mode examples.

The two most common commands you'll reach for are `sifr run` and `sifr build`. Both compile your Sifr source to native code through the same pipeline — the difference is what happens after compilation. `sifr run` executes the result immediately; `sifr build` writes a binary to disk that you can distribute or invoke later.

## `sifr run` — compile and execute

`sifr run` compiles your program and runs the resulting binary in a single step. When the compiler has a cached binary from a previous run on the same source, it skips the build phase and jumps straight to execution.

```bash theme={null}
sifr run hello.sifr
```

Pass arguments to your program after `--`:

```bash theme={null}
sifr run hello.sifr -- Alice 42
```

### Flags

| Flag                             | Description                                                        |
| -------------------------------- | ------------------------------------------------------------------ |
| `--bin <NAME>`                   | Select a layout-discovered app target by name.                     |
| `--script <NAME>`                | Select a named package script.                                     |
| `--package <NAME>` / `-p <NAME>` | Select a workspace package by Cargo package name. May be repeated. |
| `--locked`                       | Require `Cargo.lock` to be unchanged before running.               |
| `--offline`                      | Disable network access during dependency resolution.               |
| `--frozen`                       | Combine `--locked` and `--offline`.                                |
| `--quiet`                        | Suppress build phase progress output. Cache hits are always quiet. |

### Examples

```bash theme={null}
# Run a single file
sifr run main.sifr

# Run and pass arguments to the program
sifr run main.sifr -- --port 8080

# Run a named binary target in a package
sifr run --bin server

# Run while requiring the lockfile stays unchanged
sifr run main.sifr --locked

# Run without any network access
sifr run main.sifr --offline
```

<Note>
  `sifr run` prints build progress to stderr only when the binary cache misses. A cache hit produces no build output — your program's stdout follows immediately. `--quiet` suppresses progress even on a cache miss.
</Note>

## `sifr build` — compile to a native binary

`sifr build` compiles your program and writes a native binary to the output directory. Use this when you want a standalone artifact you can run later, ship in a container, or benchmark.

```bash theme={null}
sifr build hello.sifr
```

Specify an output directory with `-o`:

```bash theme={null}
sifr build hello.sifr -o dist/
```

### Flags

| Flag                          | Description                                                                              |
| ----------------------------- | ---------------------------------------------------------------------------------------- |
| `-o <DIR>` / `--output <DIR>` | Write the binary to this directory. Defaults to `.` (current directory).                 |
| `--locked`                    | Require the package `Cargo.lock` and generated Rust resolution to remain unchanged.      |
| `--offline`                   | Disable network access while resolving and building package Rust dependencies.           |
| `--frozen`                    | Combine `--locked` and `--offline`.                                                      |
| `--quiet`                     | Suppress build phase details. Only the final `Finished` and `Binary:` lines are printed. |

### Build output

A successful build in the default `human` diagnostic format writes a phase-aware summary to stderr:

```text theme={null}
Compiling hello.sifr (single-file)
  Parsing      0.8ms
  Type-check   2.1ms
  Codegen      4.3ms
  Link         9.7ms
Finished release build in 16.9ms
Binary: ./hello
```

With `--quiet`, the summary is shortened to:

```text theme={null}
Finished release build in 16.9ms
Binary: ./hello
```

<Warning>
  Build progress and success banners appear only in the default `human` diagnostic format. When you use `--diagnostic-format json` or `--diagnostic-format compact`, no human-readable progress is emitted on stdout or stderr. Scripts should consume a machine-oriented format instead of parsing words like `Finished` or `Binary`.
</Warning>

### Examples

```bash theme={null}
# Build to the current directory
sifr build app.sifr

# Build to a specific output directory
sifr build app.sifr -o ./out

# Build a package without changing its Cargo resolution or using the network
sifr build src/main.sifr --frozen

# Build with minimal output
sifr build app.sifr --quiet

# Build and emit JSON diagnostics for a CI script
sifr --diagnostic-format json build app.sifr
```

The `check`, `build`, and `run` lock flags require package context and an
authoritative `Cargo.lock`; Sifr rejects every constrained manifestless command
instead of silently falling back to normal resolution. For Rust interop
packages, the selected mode also governs signature probes and the generated
Cargo build.

## Single-file mode vs project mode

Both `sifr run` and `sifr build` select the compilation mode from the nearest
ancestor `sifr.toml`. The mode determines how local imports are resolved.

**Single-file mode** is used for every explicit `.sifr` file outside a
workspace, regardless of its filename, imports, or neighboring files.

**Project mode** is used for every valid entrypoint inside the nearest valid
ancestor `sifr.toml` workspace, regardless of its filename or imports. A
malformed discovered manifest is a hard diagnostic.

<Tabs>
  <Tab title="Single-file mode">
    A manifest-less file compiles in isolation. Local sibling imports require a
    workspace manifest.

    ```bash theme={null}
    sifr run greet.sifr          # single-file — no ancestor sifr.toml
    sifr run main.sifr           # also single-file without sifr.toml
    ```

    ```python theme={null}
    # greet.sifr
    def main():
        print("Hello, world!")
    ```
  </Tab>

  <Tab title="Project mode">
    A `sifr.toml` workspace compiles the entrypoint with its reachable local
    modules.

    ```bash theme={null}
    sifr run main.sifr           # project mode — sifr.toml exists
    sifr build main.sifr -o out/ # project mode — same workspace applies
    ```

    ```
    my_project/
      sifr.toml
      main.sifr
      helper.sifr
    ```

    ```python theme={null}
    # main.sifr
    from helper import greet

    def main():
        greet("world")
    ```
  </Tab>
</Tabs>

<Tip>
  The compilation-mode resolver for `sifr run`, `build`, `check`, `emit`, and
  `trace` uses the same workspace boundary for an explicit input path.
</Tip>

<Warning>
  Known issue [#3128](https://github.com/sifr-lang/sifr/issues/3128) affects the
  package-session preflight. If the current directory contains a source-only
  `sifr.toml` without package metadata, this preflight can fail before mode
  resolution. Until the issue is fixed, invoke explicit-file `run`, `build`, and
  `check` from outside that directory. Alternatively, use a complete package
  manifest. `emit` and `trace` do not use this preflight.
</Warning>
