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
--no-input State that the run must never prompt (Netsuke has no interactive mode)
--config Use an explicit configuration file instead of automatic discovery
--color, --emoji Policy: auto | always | never (colour rendering is not yet implemented)
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

help targets

Discovery

Prints the target and action catalogue for the selected manifest — actions first, then targets — with a [★ default] marker on manifest defaults and each entry's description metadata. The manifest is loaded and validated through the same stages as a build, but no recipes run and no outputs are created; rendering uses a restricted, side-effect-free Jinja surface that rejects env(), glob(), and other host-observing helpers, and skips command and script bodies entirely, so build-only helpers in recipes never make discovery fail. An entry whose when expression needs a disabled helper is kept and marked [◇ conditional] ([? conditional] in ASCII output; a boolean conditional field in JSON) rather than resolved. Honours --file, -C, and the usual colour, accessibility, locale, and --json conventions, and works without Ninja installed.

netsuke help targets

clean

Maintenance

Removes the file outputs Ninja tracks by running ninja -t clean against a temporary Ninja file. Phony targets and actions do not represent files and are not removed.

netsuke clean

Windows recipes run in PowerShell

On Windows, build and clean hand every command, command list, and script to Windows PowerShell (powershell.exe), whichever shell launched netsuke. Set NETSUKE_WINDOWS_SHELL=bash to keep POSIX recipes running through Git Bash or MSYS2; Netsuke checks that bash.exe --version works before executing and stops with install instructions otherwise. generate and help targets never execute recipes, so they need neither route. See the recipe shell contract.

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, accessible mode
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. Thirty-five locale catalogues ship, from Arabic (ar) to Traditional Chinese (zh-Hant). Catalogues are selected by exact locale tag with deliberate per-language fallback rules, so es-419 and es-ES, pt-BR and pt-PT, and zh-Hans and zh-Hant stay distinct; unsupported locales fall back to English (en-US), the source locale.

Locale selection

The first source that yields a valid BCP 47 tag wins:

  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 (en_GB.UTF-8 is read as en-GB), then en-US

Help text, usage, and command-line validation errors are rendered before any configuration file is read, so they skip step 3. Diagnostics, progress, and status output are rendered after the configuration merge and consult it.

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 Translating Netsuke guide for the workflow, and the upstream localization style guide and glossary for voice, tone, and terminology.

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.
  • Non-UTF-8 path: Manifest, --directory, and Ninja working-directory paths must be valid UTF-8. Netsuke rejects an invalid path while parsing the command line and names the affected option.
  • Surprising configuration: Run with --verbose to see whether --config, NETSUKE_CONFIG, or automatic discovery selected the configuration, and a bounded metrics snapshot after the command completes.

Need more help?

Check the full troubleshooting guide or join our community.

Debug guide coming soon Discord coming soon