Skip to content

CLI

nx is the Numax command line interface. It has five commands:

  • nx run - load and execute a WASM module
  • nx serve - run a node without executing a WASM module
  • nx config - manage configuration files
  • nx migrate - migrate a datastore schema offline
  • nx completions - generate shell completion scripts

nx run

nx run <MODULE> [OPTIONS]

Loads <MODULE>, starts the runtime, calls run() once, then exits. If --listen is passed, sync is enabled and the runtime stays alive until --settle-for elapses, or until SIGINT/SIGTERM if no settle window is set.

Required

ArgumentDescription
<MODULE>Path to the .wasm file to execute

Storage

FlagEnvDescription
--datastore-path <PATH>NX_DATASTORE_PATHDirectory for the local sled datastore. Default: ./nx-data
--config <PATH>-Path to a Numax TOML config file

Networking

Sync is disabled by default. Pass --listen to enable it.

FlagEnvDescription
--listen <ADDR>NX_LISTENAddress to listen on (e.g. 0.0.0.0:9000). Required for sync
--peer <ADDR>NX_PEER / NX_PEERSPeer address to connect to. Can be repeated. Requires --listen
--discovery-mode <MODE>NX_DISCOVERY_MODEstatic, bootstrap, mdns, dns-srv, or file
--bootstrap-seed <URL>NX_DISCOVERY_SEEDSBootstrap endpoint. Can be repeated
--mdns-instance <NAME>NX_DISCOVERY_INSTANCE_NAMELocal mDNS instance name
--dns-srv-name <NAME>NX_DISCOVERY_SERVICE_NAMEFully qualified DNS-SRV service name
--peer-file <PATH>NX_DISCOVERY_FILEPeer file to watch

NX_PEERS accepts a comma-separated list: NX_PEERS=127.0.0.1:9001,127.0.0.1:9002 Dynamic discovery still requires --listen. Explicit --peer values remain an additional static source and are not treated as bootstrap seeds.

Timing

FlagDescription
--wait-before-run <DURATION>Wait after starting sync and before calling run(). Gives peers time to connect. Requires --listen
--settle-for <DURATION>Keep sync alive for this duration after run() returns, then shut down. Requires --listen
--shutdown-timeout <DURATION>Maximum time allowed for graceful shutdown before returning an error

Duration format: 500ms, 5s, 2m, or a plain number (interpreted as seconds).

Inspecting CRDT state

These flags print the final host-side value of a CRDT key after the settle window completes. All of them require --listen.

FlagCRDT typeOutput format
--print-gcounter <KEY>GCounterkey = 42
--print-pncounter <KEY>PNCounterkey = -3
--print-lww-register <KEY>LWW-Registerkey = value or key = <unset>
--print-lww-map <KEY>LWW-Mapkey = {field1=val1, field2=val2}
--print-orset <KEY>ORSetkey = [tag1, tag2]
--print-rga <KEY>RGAkey = [item1, item2]

Logging

FlagEnvValuesDescription
-v / --verbose--Sets log level to debug
--log-level <LEVEL>NX_LOG_LEVELtrace debug info warn errorExplicit log level. Overrides --verbose
--log-format <FORMAT>NX_LOG_FORMATtext jsonOutput format for runtime logs. Default: text

Observability

FlagEnvDescription
--observability-listen <ADDR>NX_OBSERVABILITY_LISTENExpose a local HTTP metrics endpoint (e.g. 127.0.0.1:9100)
--tokio-consoleExpose opt-in Tokio task diagnostics from an instrumented build

tokio-console support is excluded from normal builds. Build and run the CLI explicitly with Tokio’s experimental instrumentation enabled:

Terminal window
RUSTFLAGS="--cfg tokio_unstable" cargo run -p nx-cli \
--features tokio-console -- run module.wasm --tokio-console

Then connect from another terminal with tokio-console. The subscriber listens on 127.0.0.1:6669 by default; use TOKIO_CONSOLE_BIND to select another address. Keep this diagnostic endpoint bound to a trusted interface.

TLS / mTLS

TLS is optional. To enable it, provide --tls-cert and --tls-key together. For mTLS (mutual authentication), also provide --tls-ca.

FlagEnvDescription
--tls-cert <PATH>NX_TLS_CERTPath to this node’s TLS certificate (PEM)
--tls-key <PATH>NX_TLS_KEYPath to this node’s TLS private key (PEM)
--tls-ca <PATH>NX_TLS_CAPath to the CA certificate used to verify peers (PEM). Enables mTLS
--allowed-peers <ID1,ID2,...>NX_ALLOWED_PEERSComma-separated allowlist of peer NodeIds (hex). Requires --tls-ca
--tls-insecureNX_TLS_INSECURESkip TLS certificate verification. Development only. Never use in production.

Rules:

  • --tls-cert and --tls-key must always be provided together.
  • --tls-insecure is mutually exclusive with --tls-ca and --allowed-peers.
  • --allowed-peers requires --tls-ca.

Debug

FlagDescription
--debug-protocolUse JSON instead of bincode for the sync wire protocol. Useful for inspecting traffic with a packet capture tool. Requires --listen

Configuration precedence

When a flag has a corresponding environment variable and a TOML file entry, the resolution order is:

CLI flags > NX_* environment variables > TOML config file > runtime defaults

nx completions

nx completions <SHELL>

Generates shell completion scripts for the Numax CLI.

Arguments

ArgumentDescriptionValues
<SHELL>Target shell for completionsbash, elvish, fish, powershell, zsh

Example:

Terminal window
nx completions zsh > ~/.zfunc/_nx

nx migrate

nx migrate [OPTIONS]

Opens an existing local datastore, runs the registered schema migrations, flushes the store, and exits. Run this while no nx run process is using the same datastore.

FlagDefaultDescription
--datastore-path <PATH>./nx-dataExisting datastore directory to migrate
--max-records <COUNT>512Maximum records processed per migration batch
--max-bytes <BYTES>4MiBMaximum bytes processed per migration batch, including generated mutations

Example:

Terminal window
nx migrate --datastore-path ./node-a-data

nx config

nx config init

nx config init [--output <PATH>] [--force]

Generates a commented Numax TOML configuration file with all available fields and their defaults.

FlagDefaultDescription
--output <PATH>numax.tomlWhere to write the file
--force-Overwrite the file if it already exists

Example:

Terminal window
nx config init --output node-a.toml

The generated file looks like this:

# Numax configuration file.
# Precedence: CLI flags > NX_* environment variables > this file > defaults.
[storage]
datastore_path = "./nx-data"
[network]
listen = "0.0.0.0:9000"
peers = []
serialization_format = "bincode"
[tls]
# cert = "./certs/node.pem"
# key = "./certs/node-key.pem"
# ca = "./certs/ca.pem"
allowed_peers = []
insecure = false
[observability]
# listen = "127.0.0.1:9100"
log_level = "info"
log_format = "text"
request_timeout_secs = 5
[management]
# listen = "127.0.0.1:9102"
# token_file = "./management.token"
allow_non_loopback = false
request_timeout_secs = 10
[limits]
max_peers = 64
queued_ops_limit = 10000
op_log_limit = 10000
seen_ops_limit = 100000
max_message_size = "16MiB"
socket_timeout_secs = 30
reconnect_initial_delay = "500ms"
reconnect_max_delay = "30s"
peer_dead_after_failures = 3
anti_entropy_interval = "30s"
[discovery]
mode = "static"
# cluster_id = "default"
# advertised_endpoint = "127.0.0.1:9000"
# max_candidates = 1024
# Bootstrap: seeds, refresh_interval, retry_initial, retry_max, stale_after, max_seeds
# mDNS: instance_name, max_instances
# DNS-SRV: service_name, retry_interval, max_refresh_interval
# File: path, poll_interval, max_file_bytes

nx config validate

nx config validate [--config <PATH>]

Parses and validates a TOML config file without running a module. Exits with a non-zero code and an error message if the file is invalid.

FlagDefaultDescription
--config <PATH>numax.tomlPath to the config file to validate

Example:

Terminal window
nx config validate --config node-a.toml
# configuration is valid: node-a.toml

nx config show

nx config show --config <PATH> --effective

Resolves and prints the effective configuration after applying CLI flags, environment variables, the config file, and runtime defaults - in that order.

FlagDefaultDescription
--config <PATH>numax.tomlPath to the config file
--effective-Required. Prints the fully resolved config

Example:

Terminal window
nx config show --config node-a.toml --effective

nx serve

nx serve [OPTIONS]

Starts the datastore and any configured sync, observability or management services without requiring a WASM module. The node remains active until SIGINT, SIGTERM or SIGHUP, including when sync is disabled, and then performs a graceful shutdown.

nx serve accepts the storage, networking, logging, observability, TLS, debug protocol and shutdown options documented below for nx run. It rejects module-only options such as --settle-for, --wait-before-run and --print-*. Configuration precedence is identical for both commands.

Terminal window
nx serve --config numax.toml

The Management API starts on 127.0.0.1:9102 when [management].token_file or NX_MANAGEMENT_TOKEN is configured. It stops accepting requests and drains active connections before the runtime shuts down. Authenticated v1 endpoints register and run modules and inspect modules, peers, application keys, health and readiness. See the Management API guide.

If sync, observability and management are all disabled, the process still waits for a shutdown signal and logs a warning.


TOML config file reference

A config file can provide any subset of the following sections. All fields are optional. Unknown fields are rejected.

[storage]

[storage]
datastore_path = "./nx-data"
FieldTypeDescription
datastore_pathpathDirectory for the local sled datastore

[network]

[network]
listen = "0.0.0.0:9000"
peers = ["127.0.0.1:9001"]
serialization_format = "bincode"
FieldTypeValuesDescription
listenstringhost:portAddress to listen on. Required for sync
peersstring[]host:portPeer addresses to connect to
serialization_formatstringbincode jsonWire format. Default: bincode

[tls]

[tls]
cert = "./certs/node.pem"
key = "./certs/node-key.pem"
ca = "./certs/ca.pem"
allowed_peers = ["node-a", "node-b"]
insecure = false
FieldTypeDescription
certpathNode certificate (PEM)
keypathNode private key (PEM)
capathCA certificate for peer verification (PEM). Enables mTLS
allowed_peersstring[]Allowlist of peer NodeIds
insecureboolSkip verification. Development only

[observability]

[observability]
listen = "127.0.0.1:9100"
log_level = "info"
log_format = "text"
request_timeout_secs = 5
FieldTypeValuesDescription
listenstringhost:portHTTP metrics endpoint address
log_levelstringtrace debug info warn errorLog verbosity
log_formatstringtext jsonLog output format
request_timeout_secsinteger> 0Observability request timeout in seconds

[management]

[management]
listen = "127.0.0.1:9102"
token_file = "./management.token"
allow_non_loopback = false
request_timeout_secs = 10

The listener is disabled without a token. NX_MANAGEMENT_TOKEN overrides the token file and is never printed by nx config show. Non-loopback binds require allow_non_loopback = true; protect external traffic with TLS or a TLS-terminating reverse proxy.

[limits]

[limits]
max_peers = 64
queued_ops_limit = 10000
op_log_limit = 10000
seen_ops_limit = 100000
max_message_size = "16MiB"
socket_timeout_secs = 30
reconnect_initial_delay = "500ms"
reconnect_max_delay = "30s"
peer_dead_after_failures = 3
anti_entropy_interval = "30s"
FieldTypeDescription
max_peersintegerMaximum number of connected peers
queued_ops_limitintegerMaximum ops queued for broadcast
op_log_limitintegerMaximum ops kept in the local op-log
seen_ops_limitintegerMaximum op IDs tracked for deduplication
max_message_sizestringMaximum sync message size (e.g. 16MiB, 4KiB)
socket_timeout_secsintegerSocket read/write timeout in seconds
reconnect_initial_delaydurationInitial backoff before reconnecting to a peer
reconnect_max_delaydurationMaximum backoff for reconnect attempts
peer_dead_after_failuresintegerConsecutive failures before a peer is marked dead
anti_entropy_intervaldurationInterval between anti-entropy repair cycles

reconnect_initial_delay and reconnect_max_delay must be provided together. reconnect_initial_delay must be less than or equal to reconnect_max_delay.

[discovery]

[discovery]
mode = "static"
FieldTypeValuesDescription
modestringstatic, bootstrap, mdns, dns-srv, filePeer discovery provider

Provider selectors are seeds for bootstrap, instance_name for mDNS, service_name for DNS-SRV, and path for file discovery. See the configuration reference for all tuning fields and environment variables.


Full two-node example

Terminal window
# Generate config files
nx config init --output node-a.toml --force
nx config init --output node-b.toml --force
# Edit node-a.toml: set listen = "0.0.0.0:9000", peers = ["127.0.0.1:9001"]
# Edit node-b.toml: set listen = "0.0.0.0:9001", peers = ["127.0.0.1:9000"]
# Validate
nx config validate --config node-a.toml
nx config validate --config node-b.toml
# Inspect resolved config
nx config show --config node-a.toml --effective
# Run
nx run my_module.wasm --config node-a.toml --settle-for 5s --print-gcounter counter:visits
nx run my_module.wasm --config node-b.toml --settle-for 5s --print-gcounter counter:visits