This site has already made the case for Nannou as a serious, mature option for creative coders who’ve hit a performance ceiling in Processing or p5.js — but “you should learn this” and “here’s how to start” are different articles. This one is the second: installing the toolchain and writing an actual first sketch, without assuming you already know Rust.
Watch: Creative Coding in Rust with Nannou (YouTube)
Installing the toolchain
Nannou is a Rust library, not a standalone app, so the setup has one extra step compared to p5.js’s “open a browser tab.” First install Rust itself via rustup.rs — a single install script that also gives you cargo, Rust’s package manager and build tool. From there, a new Nannou project is a normal Rust project with nannou added as a dependency in Cargo.toml:
[dependencies]
nannou = "0.19"
Nannou also publishes a cargo generate project template that scaffolds a runnable sketch in one command, which is the fastest path to something on screen if you don’t want to hand-write the boilerplate below first.
The model/update/view pattern
Where p5.js splits a sketch into setup() and draw(), Nannou splits it three ways: model, which holds whatever state your sketch needs (position, color, a list of particles — anything that persists between frames); update, which runs once per frame and mutates that state; and view, which reads the state and draws it, and is not allowed to mutate anything. That separation feels stricter than p5.js at first, but it’s what makes a Nannou sketch predictable under Rust’s ownership rules — the compiler enforces that drawing can’t accidentally corrupt state mid-frame, a category of bug that’s easy to hit by accident in looser languages.
A minimal sketch looks like this:
use nannou::prelude::*;
fn main() {
nannou::app(model).update(update).run();
}
struct Model {
x: f32,
}
fn model(app: &App) -> Model {
app.new_window().size(600, 600).view(view).build().unwrap();
Model { x: 0.0 }
}
fn update(_app: &App, model: &mut Model, _update: Update) {
model.x += 1.0;
}
fn view(app: &App, model: &Model, frame: Frame) {
let draw = app.draw();
draw.background().color(BLACK);
draw.ellipse().x_y(model.x, 0.0).radius(20.0).color(WHITE);
draw.to_frame(app, &frame).unwrap();
}
That’s a circle drifting rightward across the frame — the Nannou equivalent of a first bouncing-ball sketch, and every element in it (the draw builder, chained methods like .x_y() and .color()) will look familiar to anyone coming from p5.js’s own chainable drawing calls.
What trips people up first
The two friction points beginners hit aren’t Nannou-specific, they’re Rust-specific: the borrow checker will reject code that tries to mutate model from inside view (by design — that’s the point of the split), and compile times are real, especially on a first build while cargo pulls in the whole dependency tree. Neither is a Nannou bug; both are the tradeoff for the reliability that makes it worth learning in the first place. Past that first sketch, Nannou’s own repo ships dozens of runnable examples — 2D, 3D, and GPU-shader-driven — that are the fastest way to go from “I got a circle on screen” to “I understand the library.”