Skip to content

Builds & downloads

Nouride ships as a tarball per platform. Each one holds the executable and everything it needs beside it:

nouride the executable — the runtime, the engine, and every migration inside it
dashboard/ the built SPA, which the binary serves from beside itself
skills/ the skills that ship with the daemon
wa-bridge/wa-bridge the WhatsApp bridge, itself a compiled executable
config.example.toml every setting, annotated. A reference; the daemon boots without it

The dashboard is a directory of hash-named assets, which cannot be named as imports and so cannot be compiled in. The daemon looks for it next to the executable, which is why the two travel together and why the binary is installed into its working directory rather than dropped into /usr/local/bin on its own.

Downloads

Served from get.nouride.com.

PlatformArchitectureLibcDownload
Linuxx86_64glibcnouride-linux-x64.tar.gz
Linuxaarch64glibcnouride-linux-arm64.tar.gz
Linux (Alpine)x86_64muslnouride-linux-x64-musl.tar.gz
Linux (Alpine)aarch64muslnouride-linux-arm64-musl.tar.gz
macOSApple SiliconMach-Onouride-darwin-arm64.tar.gz
macOSIntelMach-Onouride-darwin-x64.tar.gz

Replace latest with a tag to pin a version: https://get.nouride.com/v0.1.0/nouride-linux-x64.tar.gz.

The installer picks the right one for you from uname -m and your C library:

Terminal window
curl -fsSL https://get.nouride.com/install.sh | sudo sh

There is no 32-bit ARM build. On armv7l the installer stops with unsupported architecture rather than downloading something that will not run.

The container image

ghcr.io/nouverse-tech/nouride:latest

Published as one manifest covering linux/amd64 and linux/arm64, so a server pulls its own architecture without being told which. The same release attaches the native binaries, from the same commit and the same test run.

While the package is private, pulling needs a login:

Terminal window
echo "$GHCR_TOKEN" | docker login ghcr.io -u <github-username> --password-stdin

A classic PAT, or a fine-grained token with read:packages and nothing more. The image contains no credentials — config holds secret names and data/ is a volume — so making the package public is a real option rather than a compromise, and it is the difference between one docker login and a token to rotate on every machine that pulls.

Docker & Compose →

Building it yourself

Terminal window
bun run build:binary # this machine
bun run build:binary --target linux-arm64 # one target
bun run build:binary --target linux-x64,linux-arm64 # several
bun run build:release # every Linux target

--target all and build:release mean the four Linux targets. Nobody deploys a daemon to a macOS server, and the host build already covers a laptop.

Before shipping:

Terminal window
git submodule update --init plugins/wa-bridge # default and --bundle-wa-bridge need it
git submodule update --init plugins/nougate # --bundle-nougate needs it
bun run lint:check && bun run test

A build that claims a bundle asserts its own artefact and fails if the plugin did not resolve. A dynamic import of a missing package fails at runtime, not at build time — without that check an bundle build could ship having bundled nothing.

The four builds

There are four, and nothing else. Pick the row, add --target, done.

CommandnougateWhatsAppLicenceTarball
build:binaryabsentits own process72.3 MB
build:binary --bundle-nougatein this processits own process72.4 MB
build:binary --bundle-wa-bridgeabsentin this processGPL-3.041.2 MB
build:binary --bundle-nougate --bundle-wa-bridgein this processin this processGPL-3.041.3 MB

WhatsApp is always included — only its topology changes. There is no build without it.

nougate is bundled in or absent, and absent is the normal answer: a nougate this daemon does not carry is one it reaches over the network, which is a provider base_url rather than a build. Bundling it is for a device that has to answer with no network — which makes the last row the device build.

The flags

FlagWhat it does
--target <t>Cross-compile. Omit for this machine
--bundle-wa-bridgeBridge compiled into the binary instead of spawned beside it. No stdio fallback. Makes the binary GPL-3.0
--bundle-nougateLLM gateway compiled in, served on 127.0.0.1:18256. Needs [nougate] in_process = true to actually start
--no-smolBuild without the low-memory profile. For a host with memory to spare

--bundle-* are the only flags that change the licence or the crash domain. Everything else is packaging.

What each variant costs

Measured on one linux-x64 box, four isolated daemons, the same config, nothing configured — so the rows are comparable to each other.

BuildBinaryTarballRSS idleLicence
(default)80.3 MB74.7 MB51.8 MB
--bundle-wa-bridge95.0 MB +14.743.5 MB −31.258.0 MB +6.2GPL-3.0
--bundle-nougate80.7 MB +0.474.8 MB53.0 MB +1.2
both bundles95.3 MB +15.043.6 MB59.7 MB +7.9GPL-3.0

RSS idle is the daemon carrying the code with the feature switched off — what it costs to have the option, not to use it.

Bundling the bridge makes the tarball smaller, because a 65.7 MB executable stops being staged.

The full measurement set, and why →

Why bundling saves what it saves

A separate process cannot share the Bun runtime. Measured by running one binary twice: ~36 MB of runtime and bundle pages are shared between processes of the same executable, and ~14.5 MB of heap is private to each. So a second process pays the 36 MB again, and a second listener or a bundled module pays none of it.

Both separate artefacts are almost entirely runtime. A bare compiled hello-world for linux-x64 is 78.7 MB, so nougate’s own code is 0.3 MB of its 79.0 MB binary.

A bundle you do not switch on is not free. The dynamic import means the code is never evaluated, but a bundled module graph is registered either way — which is why the non-bundle builds externalise it rather than relying on the import alone.

What bundling does not change

Nothing about how either component is reached. The WhatsApp bridge speaks the same newline-JSON protocol whether it is a process or not, and a gateway hosted here is addressed by a provider profile’s base_url exactly like a remote one. Only the transport shortens, so bridge_transport = "stdio" and [nougate] in_process = false put either back with no code change.

Licence

Nouride is proprietary — Nouverse Technologies.

The WhatsApp bridge is a separate artifact under GPL-3.0, because Baileys depends on libsignal, which is GPL-3.0. Process isolation is where that boundary sits, which is why the default build ships the bridge as its own executable and is not GPL.

--bundle-wa-bridge moves that code inside the binary and the binary is then GPL-3.0. Every build prints which it is, ending with THIS BINARY IS GPL-3.0 (libsignal) when it applies.

These were once a single flag, and that was a trap: the default staged the executable and bundled Baileys, so the ordinary build was GPL-3.0 with nothing saying so. Now the default is the safe one and the other is deliberate.

--bundle-nougate does not affect the licence — nougate depends only on drizzle-orm.