# Environment variables

> Every environment variable Brine, Brine programs and the Brine installers read, with its values and effect.

Source: https://docs.brinelang.org/tooling/environment-variables/

Brine needs no environment variables: everything has a default. The ones below change how programs run (threads, the GPU, multi-process runs), how the compiler builds (backend, C compiler, WebAssembly, timing), and how the installers install. This is the complete list for Brine 0.4.0, plus the two [WebAssembly](#webassembly) variables, which come with WebAssembly support after 0.4.0.

## Summary

[Section titled “Summary”](#summary)

| Variable                                                       | Read by            | Values              | Effect                                                                                   |
| -------------------------------------------------------------- | ------------------ | ------------------- | ---------------------------------------------------------------------------------------- |
| [`BRINE_THREADS`](#brine_threads)                              | programs           | a number            | worker threads for `par` (default: all hardware threads)                                 |
| [`BRINE_GPU`](#brine_gpu)                                      | programs           | `auto`, `on`, `off` | when `par` constructs may run on a GPU                                                   |
| [`BRINE_GPU_LOG`](#brine_gpu_log)                              | programs           | `1`                 | print where each `par` construct ran, and why                                            |
| [`BRINE_LEAKCHECK`](#brine_leakcheck)                          | programs           | any                 | print the number of live strings and arrays at exit                                      |
| [`BRINE_RANK`](#brine_rank-brine_world_size-brine_peers)       | programs           | `0` to size − 1     | this process’s rank in a `world` run                                                     |
| [`BRINE_WORLD_SIZE`](#brine_rank-brine_world_size-brine_peers) | programs           | a number            | how many ranks there are                                                                 |
| [`BRINE_PEERS`](#brine_rank-brine_world_size-brine_peers)      | programs           | `host:port,...`     | where every rank listens                                                                 |
| [`BRINE`](#brine)                                              | tests              | a path              | set by `brine test`: the `brine` running the tests                                       |
| [`BRINE_BACKEND`](#brine_backend)                              | compiler           | `c`, `native`       | force the C or the native backend                                                        |
| [`BRINE_CC`](#brine_cc-and-cc)                                 | compiler           | a command           | the C compiler (checked first)                                                           |
| [`CC`](#brine_cc-and-cc)                                       | compiler           | a command           | the C compiler, if `BRINE_CC` isn’t set                                                  |
| [`BRINE_TIMES`](#brine_times)                                  | compiler           | `1`, `2`            | print how long each compiler phase takes                                                 |
| [`BRINE_DUMP_PTX`](#brine_dump_ptx)                            | compiler           | a file path         | write the program’s GPU module to this file                                              |
| [`WASI_SDK_PATH`](#wasi_sdk_path)                              | compiler           | a path              | the wasi-sdk folder, for WebAssembly builds                                              |
| [`BRINE_WASM_RUNNER`](#brine_wasm_runner)                      | compiler           | a command           | the WASI runtime `brine run` and `brine test` use for `--target wasm` (default: Node.js) |
| [`NO_COLOR`](#no_color)                                        | compiler           | any                 | no colors in `--color auto` mode                                                         |
| [`TMPDIR`](#tmpdir)                                            | compiler, programs | a path              | the temp directory on Linux and macOS                                                    |
| [`BRINE_VERSION`](#installer-variables)                        | installers         | `0.4.0`             | the version to install                                                                   |
| [`BRINE_INSTALL`](#installer-variables)                        | installers         | a path              | where to install                                                                         |
| [`BRINE_NO_MODIFY_PATH`](#installer-variables)                 | installers         | `1`                 | don’t add Brine to `PATH`                                                                |
| [`BRINE_DOWNLOAD_URL`](#installer-variables)                   | installers         | a URL               | where to download releases from                                                          |

“Programs” means every executable Brine builds: the variables are read by the runtime when the program runs, not when it’s compiled. The `brine` compiler is itself a Brine program, so the program variables also apply to it (see the [note below](#programs-and-the-compiler)).

## Running programs

[Section titled “Running programs”](#running-programs)

### BRINE_THREADS

[Section titled “BRINE_THREADS”](#brine_threads)

The number of worker threads for `par` constructs. Unset, `0`, a negative number or something that isn’t a number means one thread per hardware thread; the most is 1024.

```sh
BRINE_THREADS=4 target/release/sim
brine run --release --threads 4      # the same: brine sets BRINE_THREADS for the program
```

Results don’t depend on it: [reductions](/parallelism/deterministic-reductions/) combine in an order fixed by the number of elements, so `BRINE_THREADS=1` and `BRINE_THREADS=32` print the same bits. `brine test` runs each test with `BRINE_THREADS=2`. [WebAssembly](/tooling/webassembly/#one-thread) builds always use one thread and ignore it.

### BRINE_GPU

[Section titled “BRINE_GPU”](#brine_gpu)

Whether `par for`, `par [...]` and `par` reductions may run on a GPU. See [GPUs](/parallelism/gpu/).

| Value                                      | Effect                                                                                                               |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `auto` (default; also any value not below) | the runtime measures each construct and uses the GPU when it expects that to be at least 25% faster, copies included |
| `on`, `1`                                  | use the GPU for every construct that can run there                                                                   |
| `off`, `0`                                 | never use a GPU                                                                                                      |

The results are the same bits whichever side runs a construct.

### BRINE_GPU_LOG

[Section titled “BRINE_GPU_LOG”](#brine_gpu_log)

Any value other than empty or `0` prints a line to stderr each time a `par for`, `par [...]` or `par` reduction runs: its location, kind, size, where it ran, how long it took, and why.

```sh
brine build --release gpu.br
BRINE_GPU_LOG=1 ./gpu
```

```text
brine gpu: gpu.br:3:14 par map n=10000000 -> cpu 5.035 ms (faster on the CPU)
brine gpu: gpu.br:4:17 par reduction n=10000000 -> cpu 1.218 ms (faster on the CPU)
8.333332083333376e+19
```

With `BRINE_GPU=off` the reason reads `(BRINE_GPU=off)`; a body that can’t run on a GPU says why (`not GPU-eligible: ...`).

### BRINE_LEAKCHECK

[Section titled “BRINE_LEAKCHECK”](#brine_leakcheck)

When set (to any value, even `0`), the program prints the number of strings and arrays still allocated when it exits. It should always be 0. See [Debugging](/tooling/debugging/#leak-checking).

```text
brine: 0 live objects at exit
```

### BRINE_RANK, BRINE_WORLD_SIZE, BRINE_PEERS

[Section titled “BRINE_RANK, BRINE_WORLD_SIZE, BRINE_PEERS”](#brine_rank-brine_world_size-brine_peers)

These make a program one rank of a multi-process [`world`](/parallelism/world/) run. `brine run --ranks N` sets all three for each process it starts, with every rank on `127.0.0.1`. To run across machines, start the same executable on each machine and set them yourself:

| Variable           | Value                                                                                              |
| ------------------ | -------------------------------------------------------------------------------------------------- |
| `BRINE_RANK`       | this process’s rank, from `0` to `BRINE_WORLD_SIZE - 1`                                            |
| `BRINE_WORLD_SIZE` | the number of ranks                                                                                |
| `BRINE_PEERS`      | `host:port` for every rank, in rank order, separated by commas; each rank listens on its own entry |

```sh
# on host a
BRINE_RANK=0 BRINE_WORLD_SIZE=2 BRINE_PEERS=10.0.0.1:7000,10.0.0.2:7000 ./sim
# on host b
BRINE_RANK=1 BRINE_WORLD_SIZE=2 BRINE_PEERS=10.0.0.1:7000,10.0.0.2:7000 ./sim
```

All three must be set; otherwise, or when `BRINE_WORLD_SIZE` is 1 or less, the program runs as a single rank (`world.size() == 1`). An entry without a `:` stops the program with `brine: invalid BRINE_PEERS entry '...'`. A [WebAssembly](/tooling/webassembly/#one-world-rank) build runs as one rank: with `BRINE_WORLD_SIZE` above 1 it stops with ``brine: `world` programs can't run with more than one rank on WebAssembly``. When every peer is `127.x.x.x` or `localhost`, ranks listen on loopback only; otherwise they listen on every interface. A `brine launch --hosts` command that does this for you is on the [roadmap](/reference/roadmap/).

### BRINE

[Section titled “BRINE”](#brine)

`brine test` sets `BRINE` to the path of the `brine` executable running the tests, so a test can run the compiler (for example with `run([getenv("BRINE").unwrap(), "check", "x.br"])`).

## Building

[Section titled “Building”](#building)

### BRINE_BACKEND

[Section titled “BRINE_BACKEND”](#brine_backend)

Picks the code generator, overriding the [default for the profile and platform](/tooling/builds-and-backends/#backends).

| Value    | Effect                                                                                                                |
| -------- | --------------------------------------------------------------------------------------------------------------------- |
| `c`      | generate C and compile it with the system C compiler, for every profile                                               |
| `native` | use the native backend (x86-64 or AArch64) for every profile, `--release` included, where there is one; elsewhere C   |
| unset    | native for dev and debug builds on x86-64 Windows/Linux and AArch64 Linux; C for `--release` and every other platform |

A build with `BRINE_BACKEND` set goes to its own folder (`target/dev-c/`, `target/release-native/`, …), so it never replaces a default build’s executable:

```sh
BRINE_BACKEND=c brine build
```

```text
     Built hello v0.1.0 [dev] in 0.27s
    Output target/dev-c/hello.exe
```

It’s meant for comparing backends and for debugging the compiler. `BRINE_BACKEND=native` with `--release` gives unoptimized native code, not a faster build.

### BRINE_CC and CC

[Section titled “BRINE_CC and CC”](#brine_cc-and-cc)

The C compiler Brine uses to compile the runtime, to link, and for every C build. Brine checks `BRINE_CC`, then `CC`, then tries `clang`, `gcc` and `cc` on your `PATH`, in that order, and takes the first that runs. Empty values are skipped.

```sh
BRINE_CC=clang brine build --release
```

The value is one program (a name on `PATH` or a full path), not a command line: extra flags in it aren’t split off. `brine doctor` shows which compiler was found. Without one, builds fail with [E0702](/reference/errors/#e0702) (`brine check` doesn’t need one).

### BRINE_TIMES

[Section titled “BRINE_TIMES”](#brine_times)

Prints how long each phase of the compiler takes, to stderr.

```sh
BRINE_TIMES=1 brine build sum.br
```

```text
  parse      0.000s
  check      0.000s
  uniform    0.000s
  verify     0.001s
  lower      0.000s
  x86-64     0.000s
  link       0.084s
     Built sum [dev] in 0.10s
    Output sum.exe
```

C builds show `emit C` and `cc (compiled/total units)` instead of `x86-64`. With `BRINE_TIMES=2`, Brine also names every function the prover spends more than 20 ms on, which tells you where a `requires` or `invariant` would speed up checking. The end of that output when checking the compiler’s own source:

```text
  verify alloc_regs: 0.050s
  verify forward: 0.027s
  verify write_elf: 0.027s
  verify     0.158s
   Checked main in 0.38s — 1003 runtime checks proven unnecessary, 1633 remain (see --report)
```

### BRINE_DUMP_PTX

[Section titled “BRINE_DUMP_PTX”](#brine_dump_ptx)

`BRINE_DUMP_PTX=file` writes the program’s GPU module to `file` while building: PTX for NVIDIA GPUs, or Metal Shading Language source on macOS.

```sh
BRINE_DUMP_PTX=kernels.ptx brine build --release
```

kernels.ptx

```text
// generated by brine
.version 6.0
.target sm_50
.address_size 64
```

### WebAssembly

[Section titled “WebAssembly”](#webassembly)

These two are read when you build or run with [`--target wasm` or `--target web`](/tooling/webassembly/).

#### WASI_SDK_PATH

[Section titled “WASI_SDK_PATH”](#wasi_sdk_path)

The folder of [wasi-sdk](https://github.com/WebAssembly/wasi-sdk/releases), whose clang and C library Brine uses for WebAssembly builds. Brine looks for `$WASI_SDK_PATH/bin/clang`, then `/opt/wasi-sdk/bin/clang`. An empty value is skipped.

```sh
WASI_SDK_PATH=~/tools/wasi-sdk-34.0-x86_64-linux brine build --target web
```

Without it, WebAssembly builds fail with [E0702](/reference/errors/#e0702) (`no WebAssembly C toolchain found`). Native builds don’t use it. `brine doctor` shows the clang it found.

#### BRINE_WASM_RUNNER

[Section titled “BRINE_WASM_RUNNER”](#brine_wasm_runner)

The command `brine run --target wasm` and `brine test --target wasm` run a module with. Brine splits the value at spaces, then adds the module’s path and the program’s arguments. Unset or empty, Brine uses Node.js with a small `node:wasi` script.

```sh
BRINE_WASM_RUNNER="wasmtime run --dir=." brine run --target wasm
```

Give the runtime access to the current folder (`--dir=.` for wasmtime) if the program uses files. A command that can’t start fails with `error: could not start <command>: program not found`.

### NO_COLOR

[Section titled “NO_COLOR”](#no_color)

When `NO_COLOR` is set, `--color auto` (the default) prints no colors. `--color always` still does.

### TMPDIR

[Section titled “TMPDIR”](#tmpdir)

On Linux and macOS, the temp directory for single-file builds (`$TMPDIR/brine-cache`, else `/tmp/brine-cache`) and for `os.temp_dir()` in programs. On Windows, Brine uses the system temp folder (`GetTempPath2W`, usually `%TEMP%`).

## Installer variables

[Section titled “Installer variables”](#installer-variables)

The one-line installers (`install.sh` and `install.ps1`) read:

| Variable               | Default            | Effect                                                                                         |
| ---------------------- | ------------------ | ---------------------------------------------------------------------------------------------- |
| `BRINE_VERSION`        | the latest release | the version to install, like `0.4.0`                                                           |
| `BRINE_INSTALL`        | `~/.brine`         | where to install; the binary goes in `$BRINE_INSTALL/bin`                                      |
| `BRINE_NO_MODIFY_PATH` | unset              | when set, don’t add Brine to `PATH` (in your shell’s startup file, or the Windows user `PATH`) |
| `BRINE_DOWNLOAD_URL`   | GitHub releases    | where the release archives and `SHA256SUMS` are, for mirrors                                   |

```sh
curl -fsSL https://raw.githubusercontent.com/brinelang/brine/main/install.sh | BRINE_VERSION=0.4.0 sh
```

```powershell
$env:BRINE_VERSION = '0.4.0'; irm https://raw.githubusercontent.com/brinelang/brine/main/install.ps1 | iex
```

## Programs and the compiler

[Section titled “Programs and the compiler”](#programs-and-the-compiler)

The `brine` compiler is written in Brine, so it’s a Brine program like any other, and the program variables apply to it too. `BRINE_THREADS` limits the threads the compiler uses for parsing and proving. `BRINE_LEAKCHECK` and `BRINE_GPU_LOG` make `brine run` print the compiler’s own lines as well as your program’s:

```sh
BRINE_LEAKCHECK=1 brine run en.br
```

```text
     Built en [dev] in 0.10s
   Running C:/Users/you/AppData/Local/Temp/brine-cache/7477652331a79471/dev/en.exe
Shape.Rect(w=2, h=3) Some(1) {"ann": 31, "bob": 27} (1, "two")
brine: 0 live objects at exit
brine: 0 live objects at exit
```

The first count is your program’s, the second the compiler’s. To see only your program’s, build it, then run the executable with the variable set.

## Related

[Section titled “Related”](#related)

* [The brine command](/tooling/cli/)
* [Builds, backends and performance](/tooling/builds-and-backends/)
* [WebAssembly](/tooling/webassembly/)
* [GPUs](/parallelism/gpu/)
* [Installation](/getting-started/installation/)
