Skip to content

CLI Reference

Global Options

These options apply to all subcommands.

-v, --verbose

Increase Nix log verbosity. Repeatable up to three times:

Flag Nix log level Description
(none) 0 (lvlError) Errors only
-v 3 (lvlInfo) Informational
-vv 5 (lvlChatty) Chatty output
-vvv 7 (lvlVomit) Everything

The value can also be read from the JUNIX_VERBOSE env var (an integer 07). The CLI value wins over the env var.

--color MODE

Control when ANSI colors are emitted in the terminal summary. This is a global switch on the parent command, so it must be placed before the subcommand:

junix --color yes check
junix --color no translate < build.log

Accepted values:

Value Behaviour
auto Color when stderr is a TTY, otherwise no color. Default.
yes Always emit color codes, even when stderr is piped.
no Never emit color codes, even when stderr is a TTY.

Resolution order (highest priority first):

  1. --color MODE on the command line, when the user passes it explicitly. The flag always wins — even over the environment.
  2. JUNIX_COLOR env var, set to one of auto/yes/no. Empty or unset is ignored.
  3. Fallback auto — color when stderr is a TTY, otherwise no color.

--help-all

Show the full help for all subcommands.

--version

Print the program version and exit.

With -v / --verbose, the version switch also prints diagnostic paths:

$ junix -v --version
junix 2.0.0
junix path: /home/yajo/.local/bin/junix
nix version: nix (Nix) 2.34.7
nix path: /nix/store/.../bin/nix

The junix path and nix path are resolved from the running interpreter / PATH, falling back to the bare command name when the executable cannot be located. Symlinks are resolved to their real targets. The verbose extras go to stderr; the first line stays on stdout so plain junix --version remains machine-friendly.

translate

Pipe Nix build output into JUnit XML.

junix translate [OPTIONS]

Reads @nix JSON protocol lines from stdin, parses them, and produces a JUnit XML report on stdout (or to a file with -o).

While reading, junix translate immediately forwards lines to its own stderr:

  • Non-@nix lines are passed through unchanged at any verbosity level.
  • @nix log messages are rendered in human-readable form (not raw JSON) when the message level is at or below the current verbosity threshold. Error messages (level 0) are always forwarded.

This lets you watch a long build live while still capturing the JUnit report.

Options

Option Description
-o, --output FILE Write XML to FILE instead of stdout
-v, --verbose Increase Nix log verbosity (repeatable)

Example

nix build --log-format internal-json -v --print-build-logs --no-link .#pkg1 2>&1 | junix translate -o result.xml

build

Run nix build and produce JUnit XML with a colorful terminal summary.

junix build [OPTIONS] [ATTRS]... [-- EXTRA_NIX_FLAGS]

Runs nix build --log-format internal-json --keep-going for the given attribute paths, parses the output, and produces a JUnit XML report.

A colorful summary is printed to stderr showing downloaded, cached, passed and failed builds. The final line is PASSED (N/M) or FAILED (N/M builds).

The <testcase> name in the JUnit report is the exact command you would run to reproduce the build: nix build <attr>.

Use -- to forward extra flags to nix build:

junix build nixpkgs#hello -- --no-link --rebuild

Options

Option Description
ATTRS Flake attribute paths to build
-o, --output FILE Write XML to FILE instead of stdout
-s, --store URL Remote store URL (e.g. ssh-ng://builder)
-v, --verbose Increase Nix log verbosity (repeatable)

check

Discover, evaluate, and build all flake checks, producing a JUnit report and a colorful terminal summary.

junix check [OPTIONS] [PATH] [-- EXTRA_NIX_FLAGS]

Runs nix eval --json "path#checks" --apply to discover checks, then builds each one with nix build --log-format internal-json --keep-going --no-link. Each check becomes a test case in the JUnit report.

The report contains one <testsuite> per architecture and per phase:

  • nix-eval.{arch} — one testcase per check, with the derivation path in <system-out> on success, or <failure> if the check failed to evaluate.
  • nix-build.{arch} — one testcase per check, with build logs in <system-out> on success, <failure> on build failure, or <skipped> when the build was cached.

The <testcase> name in the JUnit report is the exact command you would run to reproduce the work: nix eval <path>#checks.<arch>.<name> for eval suites and nix build <path>#checks.<arch>.<name> for build suites.

A colorful summary is printed to stderr with separate sections for eval and build phases, per architecture. The final line is PASSED (...) or FAILED (...) with separate counts of evals and builds — e.g. FAILED (0/4 evals, 1/2 builds).

Path must be a Nix-compatible flake reference

Junix does not rewrite the path you pass — what you give junix check is what gets passed to nix eval and nix build. Like Nix itself, relative paths must start with ./ or be an absolute path. For example:

junix check .                       # OK
junix check ./path/to/flake         # OK
junix check /absolute/path/to/flake # OK
junix check path/to/flake           # ERROR: Nix rejects bare relative paths

Options

Option Description
PATH Flake path (default: .)
-o, --output FILE Write XML to FILE instead of stdout
-e, --eval-arch ARCH Architecture to evaluate (default: all; repeatable)
-b, --build-arch ARCH Architecture to build (default: local; repeatable)
--eval-individually Evaluate each check in its own nix eval (slower, but better for low RAM scenarios)
-v, --verbose Increase Nix log verbosity (repeatable)

The -e and -b flags are independent. Passing -e aarch64-linux does not change the default of -b (still local). Passing -b aarch64-linux does not change the default of -e (still all).

--eval-individually is orthogonal to -e and -b. It only changes how each check is evaluated (one nix eval per check instead of one bulk nix eval --apply per flake), not which arches are evaluated. Use it when the default bulk evaluation OOMs on large flakes — see Memory-constrained flakes for details.

Example

# Run all checks
junix check -o check-report.xml

# Evaluate all arches, build only aarch64-linux
junix check -b aarch64-linux -o report.xml

# Evaluate only x86_64-linux, build only x86_64-linux
junix check -e x86_64-linux -b x86_64-linux -o report.xml

# Per-check eval (lower RAM peak, slower wall-clock)
junix check --eval-individually -o report.xml

# Pass extra flags to nix build
junix check -- --no-link --rebuild

Environment variables

Every CLI flag accepts its value from a JUNIX_* env var. Precedence is CLI > env > hard-coded default: passing the flag on the command line always overrides the env var, and the env var overrides the built-in default.

This means CI runners can configure junix globally by exporting the variables, without having to wrap every invocation in a script that re-passes the same flags.

Naming convention

  • Global flags (defined on the parent junix command) use JUNIX_<FLAG>: JUNIX_VERBOSE, JUNIX_COLOR.
  • Subcommand flags use JUNIX_<SUBCOMMAND>_<FLAG>, in upper snake case. Examples: JUNIX_CHECK_OUTPUT, JUNIX_BUILD_STORE, JUNIX_CHECK_BUILD_ARCH.
  • Hyphens become underscores, and case is ignored (upper snake case is the convention).

Mapping

Flag Environment variable
-v, --verbose JUNIX_VERBOSE
--color JUNIX_COLOR
translate -o, --output JUNIX_TRANSLATE_OUTPUT
build -o, --output JUNIX_BUILD_OUTPUT
build -s, --store JUNIX_BUILD_STORE
check -o, --output JUNIX_CHECK_OUTPUT
check -e, --eval-arch JUNIX_CHECK_EVAL_ARCH
check -b, --build-arch JUNIX_CHECK_BUILD_ARCH
check --eval-individually JUNIX_CHECK_EVAL_INDIVIDUALLY

Value parsing

  • String flags (--output, --store, --color): the env value is used as-is. Empty values are treated as unset.
  • Counter flags (--verbose): the env value must be an integer 07. Invalid values are ignored and the default is used.
  • Repeatable flags (--eval-arch, --build-arch): the env value is split on commas and whitespace, so JUNIX_CHECK_BUILD_ARCH="aarch64-linux,x86_64-linux" is equivalent to passing -b aarch64-linux -b x86_64-linux.
  • Boolean flags (--eval-individually): the env value follows the same rules as the rest of the CLI (1, true, yes, on are truthy; 0, false, no, off, and empty are falsy).

Example

# CI: always run per-check eval, force color, write to a fixed path
export JUNIX_CHECK_EVAL_INDIVIDUALLY=1
export JUNIX_COLOR=yes
export JUNIX_CHECK_OUTPUT=junix-report.xml
junix check ./my-flake