Getting started
Requirements
- Go 1.26.4 or later
- Make or Task (optional, for convenience targets)
- A writable home directory for
~/.reticulum-go
The repository vendors dependencies. A normal build does not contact module proxies when GOFLAGS=-mod=vendor is set (default in the Makefile and Taskfile).
Build
From the repository root:
make build
This produces bin/reticulum-go as a static stripped binary (CGO_ENABLED=0) with the daemon and all tools as subcommands.
Equivalent manual command:
mkdir -p bin
CGO_ENABLED=0 go build -ldflags="-s -w" -o bin/reticulum-go ./cmd/reticulum-go
Install to PATH
make install
Default prefix is /usr/local. That installs reticulum-go, legacy tool symlinks (rgostatus, rgoid, …), and man pages. Override with make install PREFIX=/opt/reticulum. Staging: make install DESTDIR=/tmp/stage PREFIX=/usr.
Or install into your Go binary directory:
CGO_ENABLED=0 go install -ldflags="-s -w" ./cmd/reticulum-go
Linux packages:
make package-deb
make package-rpm
First run
make run
Or:
go run ./cmd/reticulum-go
On first start the daemon creates ~/.reticulum-go/ with a default config if none exists. Logs go to stderr by default. Set verbosity with [logging] loglevel (1 through 7). Set [logging] destination = file|both and optional logfile to write to disk (default {config_dir}/logfile/reticulum.log). Daemon text logs, pageserver banner, and CLI tools color on TTY. Respect NO_COLOR and FORCE_COLOR / CLICOLOR_FORCE.
Daemon flags:
reticulum-go --config ~/.reticulum-go/config -debug 5
reticulum-go --config /path/to/config-dir
Custom config path
Pass --config / -config with a config file or directory (directory uses config inside it).
Minimal configuration
A useful starting point enables transport and one UDP interface to a known peer:
[reticulum]
enable_transport = yes
share_instance = yes
[logging]
loglevel = 4
[[UDP Peer]]
type = UDPInterface
enabled = yes
interface_enabled = yes
target_address = 192.0.2.10
target_port = 4242
port = 4242
UDP requires an explicit target_address or target_host. Open binds do not learn peers from the first inbound packet (same policy as Python forward_ip).
For local mesh discovery over IPv6 link-local multicast, use AutoInterface. See Interfaces.
Verify the build
make test-short
Full test suite:
make test
Cross-reference tests against Python vectors (requires Python 3 and vector generation):
./tests/crossref/run_crossref.sh all
Cross-platform builds
make build-linux
make build-windows
make build-darwin
make build-all
Legacy Windows 7, 8, and 8.1 builds use go-legacy-win7:
make build-windows-legacy
WebAssembly
Install Task and run:
task build-wasm
task test-wasm
See Embedding and WebAssembly.
librns and Odin bindings
Build the shared library and optional Odin tests:
task build-librns
make -C examples/librns-smoke && ./examples/librns-smoke/librns-smoke
task test-odin
task test-odin needs the Odin compiler on PATH. See librns.
Dart bindings
task build-librns
task test-dart
Needs the Dart SDK on PATH. FFI uses librns on Linux, Android, and Windows. See librns and Control API.
Enable the control API
Add to [reticulum]:
enable_control_api = yes
rpc_key = <64 hex characters>
control_api_host = 127.0.0.1
control_api_port = 37430
Generate a random 32-byte key and encode as hex. Clients send Authorization: Bearer <rpc_key>. See Control API.
CLI utilities (status, identity, probe, path, copy, pageserver)
Tools are subcommands of the single reticulum-go binary (make build). Legacy names (rgostatus, …) install as symlinks via make install.
To query a running Python rnsd from reticulum-go status / path, both stacks need TCP shared-instance RPC. On Linux, Python defaults to a Unix abstract socket unless you set:
[reticulum]
share_instance = yes
shared_instance_type = tcp
shared_instance_port = 37428
instance_control_port = 37429
rpc_key = <64 hex characters>
Restart rnsd, then:
./bin/reticulum-go status -config ~/.reticulum -json
./bin/reticulum-go path -config ~/.reticulum -t -json
Full flag reference, .rsg / .rsm / .rfe usage, file transfer, and troubleshooting are in CLI utilities.
Disable the sandbox
Sandboxing is on by default. To turn it off (not recommended for production):
enable_sandbox = no
See Security for platform behavior.
Troubleshooting
Daemon exits on config error. Check the config path and syntax. Unknown keys are ignored so a damaged file can still boot. Fix typos in type and interface names.
No paths to remote destinations. Confirm interfaces are enabled, peers are reachable, and transport is enabled. Use debug level 5 or higher temporarily. Request paths explicitly from application code or the control API.
IFAC mismatches. Peers must use the same network_name and passphrase. Wrong IFAC frames are dropped silently on ingress.
Shared instance conflicts. Only one process should own interfaces when share_instance = yes. Others should connect as clients. Check shared_instance_port (default 37428).
status connection refused. Point -config at the daemon config dir (~/.reticulum for rnsd). On Linux set shared_instance_type = tcp and restart the daemon. See CLI utilities.
Permission errors on Linux sandbox. Landlock requires kernel 5.13+. The config directory and storage paths must live under whitelisted locations. See Security.
Next steps
| Goal | Document |
|---|---|
| Configure interfaces and rates | Configuration, Interfaces |
| Status / identity / probe / path / copy CLIs | CLI utilities |
| Write a Go app | API reference, Examples, Embedding and WebAssembly |
| Embed from C or Odin | librns, Examples |
| Flutter / Dart | librns Dart FFI, Control API, Examples |
| Talk to a running daemon | Control API |
| Run in Firecracker | Firecracker microvm (make microvm-up) |
| Use Python interop | Compatibility |
| Run examples | Examples |