Tooling#
One executable holds the checker, formatter, build system, documentation generator, language server, profiler, and C importer. They share a parse, a type checker, and an incremental engine, so the editor and the build agree about what your code means.
Command What it does More
──────────── ────────────────────────────────────── ─────────────────────
check Type-check the project cli.md
build Compile to Lua, incrementally build.md
run Compile and run; profile behind a flag profiling.md
test Build, then run the configured suite testing.md
fmt Format; fixed style fmt.md
doc Generate an API site from the parse doc.md
lsp Language server, and CLI equivalents lsp.md
explain Describe a diagnostic code ../diagnostics.md
lints List the lints and their levels ../lints.md
import-c Turn a C header into declarations ../c-interop.md
rock Create and package typed Lua rocks luarocks.md
tasks List or inspect manifest targets build.md
clean Remove configured build outputs build.md
fixpoint Verify the self-hosting rebuild ../distribution.md
ast Dump a parsed syntax tree cli.mdEvery command takes -h, and nupp help <command> prints the same reference.
Checking#
nupp check # the whole configured project
nupp check --strict # hold every file to the strict floor, .g.nupp included
nupp check src/app.nupp # one fileCheck the whole project rather than the file you changed. That is what lets Nupp verify module boundaries, ownership contracts, and project lint settings together.
Machine-readable output#
Every command that produces data takes --format json (spelled --json), and each one also takes --schema, which prints the JSON Schema of that output. A test runs each command for real and validates its output against its own schema, so the two cannot drift.
nupp check --json
nupp check --schema
nupp build --json # diagnostics, the target, and every path written
nupp test --json # a record per test: name, status, duration, failureColour is off whenever output is not a terminal, so a pipe never carries escape codes. --color=always forces it back on; NO_COLOR, CLICOLOR_FORCE, and TERM=dumb are honoured.
Diagnostics you can act on#
Every diagnostic has a stable code, a source span, and often a machine-applicable fix. nupp explain turns the code into the rule, a program that reports it, and the same program corrected:
nupp explain NUPP2119Diagnostics describes the format and the JSON shape. Lints covers the ones a project can configure or suppress.
Editors#
nupp lsp serve speaks LSP over stdio. It provides diagnostics, hover, completion, signature help, go-to-definition, references, rename, document and workspace symbols, semantic tokens, folding, selection ranges, formatting, and the checker's code-action quick fixes.
The same operations are available without an editor, which is what makes them usable from a script or an agent:
nupp lsp inspect --json FILE LINE COLUMN
nupp lsp definition --json FILE LINE COLUMN
nupp lsp references --json --include-declaration FILE LINE COLUMN
nupp lsp symbols --json [--file FILE] [PATTERN]
nupp lsp rename FILE LINE COLUMN NEW_NAME # previews; --write applies
nupp lsp actions --json --only quickfix FILE LINE COLUMNPositions are 1-based byte line and column numbers, matching the compiler's diagnostics.
A VS Code extension and a Claude Code plugin live in editors/. See editors.
Formatting#
nupp fmt # list what is unformatted, project-wide
nupp fmt --write # rewrite in place
nupp fmt --check # report only; exits 1 if anything is unformatted
nupp fmt src/x.nupp # format one file to stdoutThere is nothing to configure. The formatter guarantees the output re-lexes to an identical token sequence, so it cannot change a quote style, a numeric literal, or a trailing comma even if it wanted to.
Building#
nupp build # the default manifest target
nupp build --target docs # a named target
nupp build -O2 # optimize
nupp tasks # what targets exist
nupp clean --dry-run # what clean would removeBuilds are incremental across processes. A source edit rechecks and regenerates that module; dependents are only invalidated when its exported interface changes. Build system covers the manifest, targets, caching, and native dependencies.
Profiling#
nupp run --profile app.nupp # where the time went -> profile.out
nupp run --jit-aborts app.nupp # what the JIT refused -> jit-aborts.csvThe second answers a question a sampling profiler structurally cannot: whether the hot code was compiled at all. Profiling explains both channels, and optimization covers -O levels and remarks.
Documentation#
nupp doc site -o build/docs src
nupp doc markdown -o docs/api.md srcnupp doc reads the parser's lossless CST and skips the checker entirely, so a documentation build costs parsing and rendering alone. This site is built by it. See the documentation generator.