{/* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */}
This guide is for developers and users who prefer to compile Personal AI Router (PAIR). To use a prebuilt Windows installer, Debian package, or binary archive from the GitHub releases page, refer to Getting started.
Run commands from the indicated project directory.
Install these first:
- Git.
- Node.js 25.5.0 or newer, which includes npm.
- Go 1.25 or newer.
- jq on your
PATH. Install it withsudo apt install jq,sudo dnf install jq,brew install jq, orwinget install jqlang.jq.
Clone the repository, install dependencies, and start the application:
git clone https://github.com/NVIDIA/Personal-AI-Router.git
cd Personal-AI-Router/desktop
npm install
npm startThe start script generates desktop assets, compiles required Go executables
from sibling ../services into desktop/cli-bin/, and starts Electron through
electron-vite. The service source is part of the same checkout, so there is no
submodule and no separate services build step.
The initial build can take longer than later ones. When the desktop application opens, follow Getting started to install or select an engine, pair systems, prepare a model, and run a first inference test.
The Makefile at the repository root wraps the commands in this guide for
developers on Linux and macOS. Run these targets from there:
make # list every target
make dev # check toolchain versions, fetch Go modules, install npm packages
make build # build the service binaries and the desktop bundles
make run # start the desktop application in development mode
make check # desktop gates: build scripts, lint, typecheck, contracts, tests
make test # desktop unit tests plus go test in every services module
make clean # remove build output; leaves installed dependencies alonemake run and make build install npm packages first whenever
desktop/package-lock.json is newer than desktop/node_modules, so a fresh
clone needs only make run.
make test includes the Go component and cross-process suites, which start
real subprocesses and bind local ports.
make build-services stages the standalone bundle described in
Build the Services Alone. Run make for the
remaining single-step targets.
make clean removes generated build output and nothing else. It leaves
desktop/node_modules in place, along with the per-user data a run creates:
settings, logs, cluster identity, and any engine PAIR installed. To reset that
data as well, refer to
Cleaning Up a Build from Source, which is the
quickest way back to a first-run state after testing pairing or engine installs.
Windows has no equivalent wrapper. Use the npm scripts and build.bat
described below.
Install dependencies and build the application bundles without starting them:
cd desktop
npm install
npm run buildBuild only the service binaries bundled by the desktop:
npm run build:modular-binariesThe service source must remain available at ../services. Target-specific
service-build scripts cover win32, linux, and darwin on x64 and arm64.
Refer to desktop/package.json for their names. The Go services use no cgo, so
you can build any of those targets from any host.
A local build produces an application you run on the machine that built it. Use the releases page for installable builds. This guide does not cover producing distributable artifacts.
The service scripts read services/versions.json, stamp each version, build 13
executables, and stage them together in services/build/bin/.
Linux and macOS:
cd services
./build.shWindows Command Prompt:
cd services
build.batAvoid building one component and then running an old staged bundle. Rebuild the
complete bundle so services/build/bin/ is consistent.
After you stage build/bin/, you have a complete, runnable PAIR node without
the desktop application. How you drive it is up to you. You can start the
terminal interface, which is the quickest route, run the broker directly, or
write your own client against its API.
This is the recommended way to use a services-only build, and the interface
intended for headless systems. nvpair-tui launches and supervises its own
broker, so nothing else needs to be running and there is no wiring to do:
Linux and macOS:
cd services
./build/bin/nvpair-tuiWindows Command Prompt:
cd services
build\bin\nvpair-tui.exePass --broker-path if the broker is not beside the nvpair-tui executable. Do
not run the terminal interface and the desktop application at the same time. They
compete for the same services, engines, and ports.
Using the PAIR terminal interface covers what to do after it opens: pairing, engines, models, routing, and settings. It also lists the operations that remain desktop-only.
Run nvpair-ui-broker directly when you want to drive the services
programmatically rather than through the desktop or terminal interface:
Linux and macOS:
cd services
./build/bin/nvpair-ui-brokerWindows Command Prompt:
cd services
build\bin\nvpair-ui-broker.exeThe broker speaks newline-delimited JSON-RPC on stdout and logs to stderr, and it expects the worker binaries beside it. A programmatic client normally spawns it with piped stdio. A quick check that it came up, on Linux or macOS:
cd services/build/bin
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"ping"}' | ./nvpair-ui-brokerPowerShell:
Set-Location services\build\bin
'{"jsonrpc":"2.0","id":1,"method":"ping"}' | .\nvpair-ui-broker.exeYou may see an app:ready notification alongside the response, and discovery may
be empty while LAN browsing starts. Set NVPAIR_LOG_LEVEL=debug or pass
--log-level debug for launch diagnostics. The accepted levels are debug,
info, warn, and error.
For the methods, notifications, and worker ownership, refer to the broker reference. That document, not this one, is the source of truth for API usage.
The broker's JSON-RPC API is the same contract the desktop application and the terminal interface use, and neither is privileged. If you want a different interface, you can build one against that API rather than modifying PAIR. Drive discovery, pairing, engines, models, and routing yourself, and let the broker supervise the workers.
Start with the broker reference for the protocol and lifecycle, and use the generated method surface for the full list of requests and notifications across the services.
If you are changing PAIR rather than only running it, the checks to run before opening a pull request are in CONTRIBUTING.md.
A source build has nothing to uninstall — deleting the checkout removes the application. What it leaves behind is the same per-user data any install creates, so reset that the same way. Alongside the in-app Settings > Service > Reset app data, a script does the same job without the application running:
./scripts/wipe-app-data.sh --dry-run # list what would be deleted
./scripts/wipe-app-data.sh --confirm # delete itOn Windows use scripts\wipe-app-data.cmd with the same flags. Neither script
needs Node, and both exclude engine model libraries such as ~/.ollama and
~/.lmstudio by design, so a reset does not cost you re-downloading models.
Start with --dry-run; it prints the exact paths and deletes nothing.
If the machine belongs to a cluster, leave the cluster as well, or the other nodes keep listing it as a member. Refer to Uninstalling.