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 itdashboard/ the built SPA, which the binary serves from beside itselfskills/ the skills that ship with the daemonwa-bridge/wa-bridge the WhatsApp bridge, itself a compiled executableconfig.example.toml every setting, annotated. A reference; the daemon boots without itThe 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.
| Platform | Architecture | Libc | Download |
|---|---|---|---|
| Linux | x86_64 | glibc | nouride-linux-x64.tar.gz |
| Linux | aarch64 | glibc | nouride-linux-arm64.tar.gz |
| Linux (Alpine) | x86_64 | musl | nouride-linux-x64-musl.tar.gz |
| Linux (Alpine) | aarch64 | musl | nouride-linux-arm64-musl.tar.gz |
| macOS | Apple Silicon | Mach-O | nouride-darwin-arm64.tar.gz |
| macOS | Intel | Mach-O | nouride-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:
curl -fsSL https://get.nouride.com/install.sh | sudo shThere 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:latestPublished 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:
echo "$GHCR_TOKEN" | docker login ghcr.io -u <github-username> --password-stdinA 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.
Building it yourself
bun run build:binary # this machinebun run build:binary --target linux-arm64 # one targetbun run build:binary --target linux-x64,linux-arm64 # severalbun 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:
git submodule update --init plugins/wa-bridge # default and --bundle-wa-bridge need itgit submodule update --init plugins/nougate # --bundle-nougate needs itbun run lint:check && bun run testA 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.
| Command | nougate | Licence | Tarball | |
|---|---|---|---|---|
build:binary | absent | its own process | — | 72.3 MB |
build:binary --bundle-nougate | in this process | its own process | — | 72.4 MB |
build:binary --bundle-wa-bridge | absent | in this process | GPL-3.0 | 41.2 MB |
build:binary --bundle-nougate --bundle-wa-bridge | in this process | in this process | GPL-3.0 | 41.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
| Flag | What it does |
|---|---|
--target <t> | Cross-compile. Omit for this machine |
--bundle-wa-bridge | Bridge compiled into the binary instead of spawned beside it. No stdio fallback. Makes the binary GPL-3.0 |
--bundle-nougate | LLM gateway compiled in, served on 127.0.0.1:18256. Needs [nougate] in_process = true to actually start |
--no-smol | Build 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.
| Build | Binary | Tarball | RSS idle | Licence |
|---|---|---|---|---|
| (default) | 80.3 MB | 74.7 MB | 51.8 MB | — |
--bundle-wa-bridge | 95.0 MB +14.7 | 43.5 MB −31.2 | 58.0 MB +6.2 | GPL-3.0 |
--bundle-nougate | 80.7 MB +0.4 | 74.8 MB | 53.0 MB +1.2 | — |
| both bundles | 95.3 MB +15.0 | 43.6 MB | 59.7 MB +7.9 | GPL-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.