Reference

CLI Commands

Build targets, inspect the plan, and control output. Every command's status goes to stderr and its artefacts to stdout, so pipelines capture exactly what they need.

CLI Commands

build

Primary

Builds the specified targets and their dependencies. This is the default subcommand when none is given. Global flags such as those below are written before the subcommand.

--jobs, -j Number of parallel jobs (1–64)
--verbose, -v Verbose diagnostics and timing summaries
--file, -f Read a manifest from a custom path (default Netsukefile)
--directory, -C Run as if started in this directory
--progress Progress policy: auto | always | never
--accessibility Accessible output policy: auto | on | off
--locale Locale for messages, e.g. en-US or es-ES
--json Emit one machine-readable JSON result document
netsuke build app

generate

Inspect

Generates the Ninja manifest without invoking Ninja. The manifest streams to stdout by default; pass --output to write it to a file instead.

--output Write the generated Ninja manifest to FILE instead of stdout
--file, -f Read manifest from a custom path (global flag, before the subcommand)
netsuke generate --output build.ninja

graph

Analysis

Renders the build dependency graph in-process and outputs DOT to stdout, suitable for Graphviz. Pass --html for a self-contained HTML page, and --output FILE to write the artefact to a file (- for stdout).

netsuke graph > build.dot  ·  netsuke graph --html --output graph.html

clean

Maintenance

Removes build artefacts by running ninja -t clean. Requires rules and targets to be properly configured for cleaning.

netsuke clean
user@dev:~/netsuke-project
$ netsuke --verbose build app
Parsed Netsukefile and expanded 3 targets
Wrote build.ninja
[1/3] Compiling utils.c
[2/3] Compiling main.c
[3/3] Linking app
$ netsuke graph
digraph netsuke {
  "main.o" -> "app"
  "utils.o" -> "app"
}

Tip: Inspect the Ninja plan

Use netsuke generate to stream the generated Ninja file to stdout. Pipe it into grep or a pager to understand exactly what Netsuke handed to Ninja.

Output Streams

Netsuke separates its output into two streams so that scripts and pipelines can capture exactly what they need. stderr carries all status messages, progress indicators, stage summaries, warnings, and diagnostics. stdout carries subprocess output — for example, the DOT graph produced by netsuke graph or the Ninja file streamed by netsuke generate.

stderr

Status & diagnostics

  • Stage progress indicators
  • Build task progress ([1/3] Compiling…)
  • Warnings and error messages
  • Verbose timing summaries
  • Accessible mode stage labels
stdout

Subprocess output

  • DOT graph from netsuke graph
  • Ninja file from netsuke generate
  • Any output captured from build commands
Shell examples
# Capture build graph without status noise
$ netsuke graph > build.dot

# Capture progress log without build output
$ netsuke build 2> progress.log

# Suppress all progress rendering
$ netsuke --progress never build

# Inspect generated Ninja file inline
$ netsuke generate | grep 'rule '

CI and automation

When stderr is not a TTY (e.g. in CI pipelines), task progress automatically falls back to plain-text updates, keeping logs readable without interactive spinners. Use --progress never to suppress progress entirely in environments where clean log output matters most.

Accessible Output

Netsuke supports an accessible output mode that replaces animated spinners with static, labelled status lines. This mode is designed for screen readers, dumb terminals, and any environment where motion or colour-reliant output is a problem. Meaning is never conveyed by colour alone — all output uses semantic text prefixes such as Error:, Warning:, and Success:.

Auto-detection

Accessible mode is automatically enabled when either of these environment variables is set:

TERM=dumb

Terminal does not support cursor movement or ANSI sequences.

NO_COLOR (any value)

Standard signal to disable colour output across all tools.

Manual control

Force accessible mode on or off regardless of auto-detection. Any explicit setting disables auto-detection; if more than one is present, CLI flags override environment variables, which override config.

CLI: --accessibility on | off | auto
Env: NETSUKE_ACCESSIBILITY=on
Config: accessibility = "on"

Accessible mode output

In accessible mode each pipeline stage and each build task produces a labelled line on stderr. No spinners, no cursor movement — just plain, ordered text a screen reader can follow.

stderr with accessible mode enabled
Stage 1/6: Reading manifest file
Stage 2/6: Parsing YAML document
Stage 3/6: Expanding template directives
Stage 4/6: Deserializing and rendering manifest values
Stage 5/6: Building and validating dependency graph
Stage 6/6: Synthesizing Ninja plan and executing Build
Task 1/2: cc -c src/a.c
Task 2/2: cc -c src/b.c
Success: Build complete.

Emoji suppression

Emoji glyphs in output can be suppressed separately from accessible mode. This is useful for terminals where emoji render as boxes, or for users who prefer plain ASCII.

Env var:
NETSUKE_EMOJI=never
CLI flag:
--emoji never
Config file:
emoji = "never"

Localization

All user-facing text in Netsuke — help messages, status lines, error explanations, hints — is externalised into Fluent .ftl resource files. This means the entire CLI can be translated to a new language without changing a line of Rust. Spanish (es-ES) ships as a reference translation; unsupported locales fall back to English (en-US).

Locale selection

Locale is resolved in this order of precedence:

  1. 1 CLI flag: --locale es-ES
  2. 2 Environment: NETSUKE_LOCALE=es-ES
  3. 3 Config file: locale = "es-ES"
  4. 4 System default locale

What is localised

  • CLI help text and subcommand descriptions
  • Stage and task progress labels
  • Error messages and contextual hints
  • Manifest parse and schema errors
  • Template and intermediate representation (IR) validation errors

Fluent message format

Fluent messages handle pluralisation and variable interpolation natively. A translator only needs to edit the .ftl file for their locale — no code changes required.

# en-US.ftl
progress-target-count = Building { $count ->
    [one] { $count } target...
   *[other] { $count } targets...
}

error-file-not-found = Error: File "{ $path }" was not found.
    .hint = Check that the path exists and is readable.

See the Contributing guide for translation workflow details.

Troubleshooting

Common Issues

  • Rule mismatch: A target defined more than one of rule, command, or script. Keep the recipe singular.
  • Template failure: A variable or macro expanded unexpectedly. Check the rendered string fields and the vars precedence.

Need more help?

Check the full troubleshooting guide or join our community.

Debug guide coming soon Discord coming soon