Local Studio

Setup guide

Get Local Studio running

Local Studio is a local-first workstation for running, managing, and using self-hosted LLM backends. Two modules share one controller API: a Bun/Hono backend and a Next.js + React frontend with an Electron desktop shell.

Prerequisites

  • Bun 1.x — for the controller.
  • Node.js 20+ and npm — for the frontend.
  • Python 3.10+ on PATH — engine installs use uv when present, pip otherwise.
  • Git.
  • NVIDIA driver + CUDA for vLLM/SGLang on Linux. Apple Silicon uses the MLX backend.

Quick start

Run the preflight check first — it verifies toolchain, ports, directories, and network:

npm run doctor

Start the controller (listens on 127.0.0.1:8080; data dir and SQLite are created automatically, model weights live in LOCAL_STUDIO_MODELS_DIR, default /models):

cd controller && bun install && bun src/main.ts

Start the frontend in a second terminal, then open http://localhost:3000/setup:

cd frontend && npm ci && npm run dev

npm ci runs a postinstall patch against @earendil-works/pi-ai. If that step prints a warning, agent streaming may misrender — re-run npm ci to fix it.

Setup wizard

The first-run /setup wizard walks through choosing a models directory, installing an engine, downloading a model, launching it, and benchmarking. Engine installs (vLLM/SGLang/MLX) land in <data dir>/runtime/venvs/<backend>-latest.

Runtime backends

Recipes launch through the controller runtime layer. Wired backend families:

  • vLLMCUDA throughput serving through configured, discovered, system, Docker, or bundled targets.
  • SGLangStructured and multi-turn serving through discovered or configured Python targets.
  • llama.cppGGUF models through the llama-server binary. Great for CPU and modest hardware.
  • MLXApple Silicon serving through mlx_lm.server. The default path on Mac.

Runtime target discovery is surfaced in Settings; selections persist in the controller data directory.

Agent runtime

The agent surface lives at /agent in the frontend. It uses@earendil-works/pi-coding-agent through the frontend runtime rather than shelling out to a separate agent process. Agent skills and extensions are loaded by the frontend runtime and surfaced in the session UI.

Agent file operations are local-only, stored under data/agentfs.

Remote / LAN deployment

The controller binds 127.0.0.1 by default. Binding a non-loopback host (e.g. LOCAL_STUDIO_HOST=0.0.0.0) requires LOCAL_STUDIO_API_KEY — startup throws without it. On a trusted LAN you may instead setLOCAL_STUDIO_ALLOW_UNAUTHENTICATED=true to opt out of authentication.

Point the frontend at a remote controller with BACKEND_URL or NEXT_PUBLIC_API_URL (default http://localhost:8080). Configure .env.local first (see .env.example):

REMOTE_HOST=192.168.x.x REMOTE_USER=username REMOTE_PATH=/home/user/project # Optional: REMOTE_SSH_KEY (defaults to ~/.ssh/id_ed25519)
./scripts/deploy-remote.sh controller # sync + build + restart controller ./scripts/deploy-remote.sh frontend # sync + build + restart frontend ./scripts/deploy-remote.sh status # inspect remote processes

Local daemon helper: ./scripts/daemon.sh {start|stop|status}.

Validation

After setup, confirm the stack is healthy:

  • Settings switches controllers and the runtime state updates.
  • System shows installed engines and the active service topology.
  • A model launches through a recipe and /status reflects it.
  • /v1/chat/completions works locally and through a provider route.
  • /agent completes a turn using the selected model and local tools.
npm run check # contracts + structure + frontend quality + controller typecheck npm run test:integration # controller integration + frontend regression

For the full agent runbook — controllers, providers, runtimes, and Pi sessions — see the agents page.