Skip to main content

CLI Reference

The nebra binary is the only tool you need: compiler, runner, REPL, test runner, package manager, language server, docs generator, and standalone-binary bundler - all behind subcommands.

nebra <command> [args]

Run nebra help for a one-screen summary. The sections below are the complete reference.


nebra init

Scaffolds a new Nebra project in the current directory. Creates:

  • nebra.toml with sensible defaults (target = "5.4", source = "src", output = "out")
  • src/ and out/ directories
  • .gitignore with out/ and nebra_modules/ pre-listed

Refuses to overwrite an existing nebra.toml.

mkdir my-app && cd my-app
nebra init

nebra create <spec> [dir]

Scaffolds a project from a template. The spec can be:

  • A git URL: https://github.com/owner/template.git, git@github.com:owner/template.git
  • A GitHub shortcut: gh:owner/template, github:owner/template@v1
  • A direct URL to a setup.neb file that handles prompting and file generation
FlagDescription
--skip-setupClone the template but don't run its setup.neb
--offlineUse only the cached registry; don't fetch from network
--no-cacheBypass the local git cache for this run
nebra create gh:DasDarki/nebra-app-template my-game
nebra create https://example.com/setup.neb

nebra build [files...]

Compiles the project (no args) or specific .neb files (with args).

Project mode - reads nebra.toml, scans <source>/**/*.neb, writes <output>/**/*.lua. The configured entry, target, code section, mangle section, and rules section all apply.

File mode - compile the given files plus an optional nebra.toml (auto-detected). Output lands in the project's <output> dir (or out/ if no config). Useful for one-off compilation.

nebra build # project mode
nebra build src/foo.neb src/bar.neb # file mode
nebra build nebra.toml src/main.neb # explicit config

Pre/post-build scripts from [scripts] run before/after compilation.


nebra watch

Watches <source>/ recursively and recompiles the whole project whenever a *.neb file is created, changed, deleted, or renamed. File-system events are debounced so a burst of saves triggers a single rebuild. Compile errors are printed and the watcher keeps running; press Ctrl+C (or send SIGTERM) to stop.

Unlike nebra build, the watch loop does not run [scripts] pre/post-build hooks - it only recompiles, so side-effecting hooks don't fire on every save. Each rebuild reloads nebra.toml, so changes to the output path or compiler options are picked up live.

nebra watch # rebuild on every change
nebra watch --debounce 150 # shorten the debounce window (ms, default 300)

nebra run [files...] [-- args...]

Compiles and executes via the embedded Lua 5.4 interpreter (KeraLua). State on the target machine is irrelevant - the binary brings its own Lua.

Same file vs project mode as nebra build. Everything after -- is passed to the running Lua script as the global arg table.

nebra run # project mode, entry from nebra.toml
nebra run -- --verbose foo bar # forward args to script

nebra run src/script.neb # one-off file

The package.path is augmented with the compiled output dir and nebra_modules/, so cross-module requires Just Work. Exit code mirrors the Lua chunk's success.


nebra test [filter]

Discovers and runs unit / integration tests.

Discovery: a file is a test iff

  • It lives under any directory listed in [test].dirs (default: tests/, test/), recursively; or
  • Its filename ends with one of [test].patterns (default: _test.neb, .test.neb).

The optional [filter] argument matches against the full test name (substring; case-sensitive). Only matching tests run; the others are skipped silently.

FlagDescription
--quiet, -qSuppress per-test tick output; show summary only
nebra test # run every discovered test
nebra test "match" # only tests whose name contains "match"
nebra test --quiet

Exit code is 0 on all-pass, 1 on any failure or compile error. See Testing for the assertion API and describe/test semantics.


nebra repl

Starts an interactive Nebra session.

nebra> 2 + 2
4
nebra> function greet(n: string): string
...> return "hi " .. n
...> end
nebra> greet("world")
hi world

The runtime persists across inputs - globals and top-level functions survive. Top-level locals do not (Lua semantics; use name = ... without local to get a global).

REPL commands (start with :):

CommandEffect
:help, :hShow inline help
:quit, :qExit (also Ctrl+D)
:clearClear the screen
:resetDrop all globals (fresh runtime)
:load <path>Read a .neb file and evaluate it in-session

Multi-line input is detected automatically - the REPL keeps prompting (...>) until brackets and blocks balance. See REPL for details.


nebra compile

Bundles the project into a single self-contained native executable. Embeds all compiled Lua, the Lua 5.4 interpreter, and the Nebra stdlib bindings. The result runs on a machine with no Lua and no .NET.

FlagDefaultDescription
--out <path>./<name> (.exe on Windows)Output binary path
--name <s>config.Name or entry basenameApplication name (also the AssemblyName)
--target <rid>current RID.NET RID, e.g. linux-arm64, win-x64, osx-arm64
--aotoffUse Native AOT (experimental - smaller binary, faster start; needs clang/lld on Linux, MSVC on Windows)
--keep-buildoffDon't delete the temporary launcher project on success

Bundle process (5 steps, all logged to stdout):

  1. Compile the project (same pipeline as nebra build).
  2. Scan nebra_modules/ for native libraries (.so, .dylib, .dll) - fail if any are found (current Nebra can't ship them inside the binary).
  3. Generate a temporary Launcher.csproj that references Nebra.Runtime.dll (the embedded Lua wrapper), with every compiled .lua plus every pre-built .lua from nebra_modules/ as embedded resources.
  4. Run dotnet publish -c Release -r <rid> with single-file self-contained settings.
  5. Copy the published binary to --out, chmod +x on Unix.
nebra compile # → ./my-app (~70 MB)
nebra compile --out dist/server # custom path
nebra compile --aot # smaller binary (~15 MB), needs native toolchain

See Standalone Binaries for tuning and troubleshooting.


nebra docs [args]

Generates documentation for the project's exported APIs from inline doc comments.

FlagDefaultDescription
--out <dir>docsOutput directory for generated files
--no-htmloffSkip the HTML site, keep only Markdown
--no-mdoffSkip Markdown, keep only the HTML site

The generator reads LuaCATS-style triple-dash comments (--- summary, ---@param, ---@return) on exported declarations and produces one Markdown file per module + an HTML site index. See Doc Comments for the comment syntax.

nebra docs # → docs/index.html + per-module .md
nebra docs --out public/api # custom dir
nebra docs --no-html # plain Markdown only

nebra install

Installs declared dependencies from nebra.toml into nebra_modules/. Reads nebra.lock if present, otherwise resolves fresh from git.

FlagDescription
--frozenRequire an up-to-date nebra.lock; error on drift
--offlineOnly use the local git cache; never fetch
--no-dev, --productionSkip [dev-dependencies]
--no-cacheBypass the registry cache for alias resolution
--allow-scriptsAllow [scripts] install / postinstall to run
--allow-scripts=pkg1,pkg2Allow scripts only for the named packages
nebra install # install everything
nebra install --frozen --no-dev # CI mode
nebra install --allow-scripts=lua-protobuf # allow specific package's scripts

nebra add <spec>

Adds a dependency to nebra.toml (preserving formatting + comments via TOML round-trip) and installs it.

Spec formats:

  • name@version (alias registry): nebra-strings@1.2.0
  • github:owner/repo[@ref]: github:DasDarki/nebra-strings@v1.2.0
  • gh:owner/repo[@ref]: shorthand for the above
  • https://...: any git URL, optional #ref suffix
  • file:../local-path: link a local checkout
FlagDescription
--devAdd to [dev-dependencies] instead of [dependencies]
--peerAdd to [peer-dependencies]
--no-cacheBypass the registry cache
--allow-scripts[=names]Allow lifecycle scripts (all, or comma-separated names)
nebra add github:owner/cool-lib@v1
nebra add nebra-strings@1.2.0 --dev
nebra add file:../my-utils

nebra remove <name>

Removes a dependency from nebra.toml and deletes it from nebra_modules/. Also unlinks transitive deps that no other package references.

nebra remove cool-lib

nebra pm prune [<spec>]

Wipe the on-disk package caches so the next install / create re-fetches from origin. Use when a package was republished under the same ref (force-pushed tag, mutable branch) and the cached snapshot is now stale.

nebra pm prune # wipe ALL caches
nebra pm prune github:nebra-lang/nanos-world-types # wipe one repo's bare clone + snapshots

nebra pm prune (no args) removes ~/.neb/cache/git, ~/.neb/store and ~/.neb/tmp. With a git spec it removes only that repo's bare clone and every commit snapshot of it.

nebra pm update [<name>]

Re-resolves dependencies against origin and rewrites the lockfile. The bare clone is git fetch'd on every invocation, so any floating ref (default branch, semver range, mutable tag) picks up new commits. Pinned exact-commit specs end up at the same SHA.

nebra pm update # re-resolve every dep
nebra pm update nanos-world-types # re-resolve just one

pm update (no args) wipes the entire lockfile and re-resolves; pm update <name> drops only the named entry. Either way the install step that follows re-extracts snapshots and re-links nebra_modules/. For cache-corruption scenarios (mis-named ref, force-pushed branch overwriting the bare clone), reach for nebra pm prune instead.

nebra pm refresh-registry

Re-downloads the alias registry index so name → git-URL lookups (nebra add cool-lib@v1) see the latest published packages.

nebra pm refresh-registry

nebra registry refresh still works as a deprecated alias and prints a one-line migration notice.


nebra lps

Starts the Language Server Protocol server over stdio. Editors invoke this transparently; you should not need to call it directly.

nebra lps # blocks reading from stdin / writing to stdout

The server provides diagnostics, hover, go-to-definition, completion, signature help, rename, find-references, document symbols, semantic tokens, and code actions ("Implement interface", "Auto-import", "Compile current file"). It reuses the compiler's CheckPipeline (full pipeline minus mangle/codegen) for fast incremental feedback.


nebra version

Prints the Nebra compiler version (semver, three components).

nebra version # → nebra 0.X.Y

nebra help

Prints a one-screen summary of every command + the most common flags. Detailed flags live in this document.


Exit codes

CodeMeaning
0Success
1Any failure: compile error, test failure, missing file, install failure, etc.

For nebra run and nebra compile'd binaries, the exit code propagates from the user's Lua script (os.exit(N) works as expected).