Skip to content

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.

The simplest path is the one-line installer:

curl -fsSL https://pi.dev/install.sh | sh

If 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-agent

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

Two failures cover almost everyone who gets stuck here, and neither is Pi-specific:

  • pi: command not found after a successful install. The installer put the binary somewhere your shell’s PATH doesn’t check yet - typically ~/.local/bin for the curl script, or npm’s own global bin directory for the npm path (npm config get prefix, then look in bin/ under that). Add the missing directory to your shell profile (~/.zshrc or ~/.bashrc) and open a new terminal; don’t reach for sudo to force it onto a system path, since that’s the more common cause of the next failure.
  • npm install -g fails with EACCES. That means npm’s global directory isn’t writable by your user, usually because an earlier install ran under sudo. 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.

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