The Klipper stack explained: Klipper, Moonraker, Mainsail
By Tess · thought-leadership-writer · 17 June 2026 · 7 min read
People say "I installed Klipper" the way they'd say "I installed an app". But a modern print server is not one program — it is a small stack of four, each doing one job and talking to the next over a defined interface. Once you can see the layers, the whole thing stops being mysterious: setup quirks land in the right box, and the reason this architecture is quietly perfect for AI becomes obvious. Here is the stack, top to bottom, from the build we actually run.
The one idea: split the brain
Traditional printer firmware — Marlin and its kin — does everything on the printer's own microcontroller: read the G-code, plan the motion, drive the steppers, draw the LCD. That chip is an 8- or 32-bit microcontroller with kilobytes of RAM. It copes, but it is doing expensive maths on a calculator.
Klipper's founding decision was to take the hard thinking off that chip and move it onto a real computer — usually a Raspberry Pi. The Pi runs the motion planner; the printer's microcontroller is demoted to a tiny program that does nothing but execute precisely timed step commands the host sends it. The host does the trigonometry; the MCU does the timing. That single split — planner here, stepper there — is the seed everything else grows from. And because the host is now a full Linux box on your network, it has room for the three layers that stack on top.
Layer 1 — the MCU firmware (on the printer)
At the bottom is the part most people trip over: a small Klipper firmware compiled for your specific mainboard's chip and flashed onto it. This is not optional and not generic. You run make menuconfig, pick your microcontroller, build a klipper.bin, and get it onto the board — over USB, or on cheaper boards like the Ender 3 V2's, by copying it onto an SD card the bootloader reads at power-on.
It is also where a first build most often stalls. We wrote a whole war story about how this layer ate two evenings on a stock Ender 3 V2 — the wrong class of SD card, then the wrong flash offset, both masquerading as a dead board. The lesson that matters here is structural: this layer lives on the printer and is the one part of the stack you genuinely have to get right by hand. Everything above it is software on the Pi.
Layer 2 — the Klipper host (the motion planner)
On the Pi sits the Klipper host process. This is the brain: it parses G-code, runs look-ahead and acceleration shaping, applies input shaping to cancel ringing and pressure advance to sharpen corners, and streams the resulting step timings down to the MCU. The entire machine — kinematics, pins, limits, macros — is described in one human-readable printer.cfg. Your printer's behaviour is configuration-as-code: diffable, version-controllable, shareable.
Here is the detail that explains the next two layers: the Klipper host has no network interface and no UI of its own. It talks to the outside world through a single Unix domain socket on the Pi. That is a deliberate, almost austere choice — Klipper does motion, and only motion. So on its own it is a perfect planner that nothing can reach. To drive it from a browser, something has to wrap that socket.
Layer 3 — Moonraker (the API)
That something is Moonraker: a Python web server whose whole job is to sit in front of Klipper's socket and expose it as a proper API — JSON-RPC over a WebSocket, plus a REST-style HTTP interface. Every "send G-code", "stream the temperatures", "upload this file", "what's the print progress" request goes through Moonraker.
It also absorbs the unglamorous jobs Klipper deliberately refuses: update management (pulling new Klipper, Moonraker and UI versions), file and print-history management, webcam configuration, and notifications to services like ntfy or Discord. You configure it once in moonraker.conf — the [authorization] block, with its trusted clients and CORS rules, is the part that bites when you put the printer behind a reverse proxy — and then you mostly forget it exists. That invisibility is the point. Moonraker is infrastructure, not an interface. This is the most important layer in the whole stack, and the one nobody photographs, because it is the seam that makes everything above it interchangeable.
Layer 4 — the web UI (Mainsail or Fluidd)
At the top is the face: Mainsail or its near-twin Fluidd. These are single-page web apps — Mainsail is built in Vue — that talk to nothing but Moonraker. Temperature graphs, the live console, the G-code file list and viewer, manual movement, webcam feeds, print history, the update button: all of it is the UI rendering data it pulled from the Moonraker API and posting commands back the same way.
Because the UI only knows the API, the two front-ends are genuinely swappable — point either at the same Moonraker and the printer cannot tell the difference. The choice between Mainsail and Fluidd is taste, not capability. (A web server such as nginx usually serves the static UI files and proxies the API calls through to Moonraker, but that is plumbing, not a fifth brain.)
The glue you'll meet too
Two more names show up the moment you add a camera or do a real install, and they fit the same pattern. Crowsnest is the webcam service — a wrapper around ustreamer (light, MJPEG, a little latency) or camera-streamer (hardware-accelerated, low latency for H.264) — that Moonraker and the UI then read from. And KIAUH, the Klipper Installation And Update Helper, is the menu-driven script most people use to install Klipper, Moonraker, a UI and Crowsnest in one sitting rather than wiring four repositories by hand. Neither is a new layer; they install and feed the four you already understand.
Why the split is the whole point
It is tempting to read four programs as four times the hassle, and the honest cost is real: more moving parts, and version coupling — Klipper, Moonraker and the UI move together, so an out-of-step component can break the update manager until you reconcile them. You are also now maintaining a small Linux server that happens to print.
But the separation buys something a monolith cannot. Each layer evolves on its own: a new dashboard never touches your motion code; a Klipper update never re-flashes your firmware by surprise; you can run two different UIs against one printer at once. The boundary that makes setup feel like four things is the same boundary that makes the system modular, debuggable and — the part we care about most — open at every level.
The AI angle: a printer you can program
This is where the architecture stops being a curiosity and starts being a platform. The reason a Klipper machine is the natural home for AI is not the motion maths — it is Layer 3. Moonraker exposes the printer's entire state (temperatures, position, job progress, history) over a stable WebSocket and accepts G-code back. That is exactly the surface an agent needs: subscribe to live telemetry, react to events, issue commands — all without touching firmware.
So first-layer vision, automatic pause-on-spaghetti, fleet queue orchestration, or an LLM that watches a print and narrates what's happening all plug into the same API the browser UI uses. The webcam frames are already there via Crowsnest; the control channel is already there via Moonraker; and the machine's configuration is plain text an agent can read and edit — printer.cfg is just a file. A walled-garden printer gives you an app. This stack gives you an interface, which is a far more useful thing to hand a model.
We dogfood exactly this. ender-pi (github.com/2nth-ai/ender-pi) is our real Raspberry Pi 4 Klipper server for a Creality Ender 3 V2 — MCU firmware flashed onto the stock 4.2.2 board, Klipper and Moonraker on the Pi, Mainsail as the UI. Every layer in this post is a layer we run.
Start here
- Klipper — Layer 2, the motion planner, and why the flash is worth it.
- Moonraker — Layer 3, the API that makes the printer programmable.
- Mainsail — Layer 4, the browser face (Fluidd is the alternative).
- Building & flashing Klipper firmware — Layer 1, the hands-on step, written from our build.
- Install the lot in one go with KIAUH, or flash MainsailOS for the prebuilt path.
The trick to understanding a Klipper machine is to stop seeing one program and start seeing four boxes with arrows between them: MCU firmware ← Klipper host ← Moonraker ← UI, each blind to all but its neighbour. Hold that picture and the setup quirks sort themselves into the right box, the upgrade path makes sense, and the reason this is the printing world's most AI-ready architecture stops being a slogan and becomes something you can point at.