Building and Running NVIDIA Personal AI Router

View as Markdown

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.

Prerequisites

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 with sudo apt install jq, sudo dnf install jq, brew install jq, or winget install jqlang.jq.

Quick Start from Source

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 start

The 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.

Make Targets

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 alone

make 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.

Build the Desktop Application Alone

Install dependencies and build the application bundles without starting them:

$cd desktop
$npm install
$npm run build

Build only the service binaries bundled by the desktop:

$npm run build:modular-binaries

The 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.

Build the Services Alone

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.sh

Windows Command Prompt:

1cd services
2build.bat

Avoid building one component and then running an old staged bundle. Rebuild the complete bundle so services/build/bin/ is consistent.

Run Without the Desktop Application

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.

Start with the Terminal Interface

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-tui

Windows Command Prompt:

1cd services
2build\bin\nvpair-tui.exe

Pass --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 the Broker Yourself

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-broker

Windows Command Prompt:

1cd services
2build\bin\nvpair-ui-broker.exe

The 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-broker

PowerShell:

1Set-Location services\build\bin
2'{"jsonrpc":"2.0","id":1,"method":"ping"}' | .\nvpair-ui-broker.exe

You 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.

Write Your Own Client

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.

Cleaning Up a Build from Source

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 it

On 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.