Course · Pi · Getting started
Install Pi and see the surfaces it runs on
You’ve got the stash working copy on your machine - the small feed-reader project this module’s opener sets up, with its two failing tests waiting; if you’re starting here, any Git repo works for this lesson - and there’s no agent installed yet. This is the shortest lesson in the module, because the install itself is trivial - the framing matters more than the command.
Getting it onto your machine
Section titled “Getting it onto your machine”The simplest path is the one-line installer:
curl -fsSL https://pi.dev/install.sh | shIf you’d rather go through npm, the canonical package lives under Earendil’s scope (the company that now stewards Pi’s development, alongside its original author):
npm install -g --ignore-scripts @earendil-works/pi-coding-agentThe --ignore-scripts flag is called out deliberately in Pi’s own docs as a supply-chain precaution - Pi doesn’t need install scripts to install correctly, so there’s no reason to run them. Keep the flag even though it’s one more thing to remember. You’ll also see an older package name, @mariozechner/pi-coding-agent, from before the stewardship move. It’s still published and still installs and works, but it’s frozen: the last release, 0.73.1, landed in May 2026 and it has received nothing since. New installs should use the Earendil package.
One number here deserves your own verification rather than this page’s word: the Node floor. The current package requires >=22.19.0, with a legacy-node20 dist-tag pinned to an older release if you’re stuck on an old install (install that branch explicitly with npm install -g --ignore-scripts @earendil-works/pi-coding-agent@legacy-node20). That floor moved a few months before this course’s September 2026 check - it was >=20.6.0 until May 2026 - so it can move again. Run npm view @earendil-works/pi-coding-agent engines before you install and believe the output over any number printed here, including this one. The same habit settles the frozen-package claim above, if you ever need it: npm view @mariozechner/pi-coding-agent version prints the old package’s last release.
Once it’s on your PATH, launch it from inside the project - like most agents, Pi reasons about the directory it starts in:
> cd ~/work/stash> piIf it doesn’t work
Section titled “If it doesn’t work”Two failures cover almost everyone who gets stuck here, and neither is Pi-specific:
pi: command not foundafter a successful install. The installer put the binary somewhere your shell’sPATHdoesn’t check yet - typically~/.local/binfor the curl script, or npm’s own global bin directory for the npm path (npm config get prefix, then look inbin/under that). Add the missing directory to your shell profile (~/.zshrcor~/.bashrc) and open a new terminal; don’t reach forsudoto force it onto a system path, since that’s the more common cause of the next failure.npm install -gfails withEACCES. That means npm’s global directory isn’t writable by your user, usually because an earlier install ran undersudo. Fix the ownership of npm’s prefix directory, or better, install a Node version manager (nvm,fnm) so global installs never need root at all. The curl installer sidesteps this class of problem entirely, which is one real reason to prefer it.
One small core, four front doors
Section titled “One small core, four front doors”Here’s the framing worth setting before you type anything else. What you just installed isn’t really “a CLI with some extra modes bolted on” - it’s a small agent core (the loop, the tools, the model-facing plumbing) that happens to expose itself through several different surfaces, all sharing the exact same behavior underneath:
| Surface | Invocation | Output | When you’ll use it |
|---|---|---|---|
| Interactive | pi |
Rendered TUI, live | This module - every lesson from here on |
pi -p "your prompt" |
Runs one prompt to completion, then exits | Scripts and pipelines: pipe a log in, ask for a summary, done | |
| JSON event-stream | pi --mode json -p "your prompt" |
Every tool call, result, and text chunk as structured JSON lines | Later in the course: subagents and teams both spawn a second Pi process this way and read its stream |
| RPC | pi --mode rpc |
The same events, framed as strict newline-delimited JSON over stdin/stdout | Driving Pi as a subprocess from a host process in any language, with two-way control |
You won’t touch the last two in this module. But it’s worth naming why they’re on the table at all: two later modules in this course - the ones on subagents and on multi-agent teams - are built entirely on spawning a second pi process with --mode json -p and parsing its output. Nothing new gets bolted on to make that work; it’s the exact table above, used from code instead of from your fingers.
Every surface runs the identical agent core - the loop, the tools, the model-facing plumbing behave the same on every surface; what changes is how you talk to it. The habits you build at the interactive prompt this week - how the loop behaves, what it can see, what it’s allowed to do - are the same habits the scripted surfaces run on. There is no second tool to re-learn.
Pi is installed and sitting at a live prompt inside stash - it opens its prompt before any provider is configured, and signing in happens from inside it, on the next page. It doesn’t know who’s paying for the model yet, though - and that choice has a real, easy-to-miss consequence. Next: bring your own key.