What if you could write creative code—the kind that makes colors dance and shapes breathe—with Rust's safety and performance?

That's the question that led me to build rust-sketch: a p5.js-compatible creative coding framework powered by wgpu. But this isn't just about another graphics library. It's about what happens when you try to make Rust feel playful.

The Gap Nobody Was Talking About

Python has Processing. JavaScript has p5.js. Processing spawned p5.js, which spawned a generation of creative coders, generative artists, and visual experimenters. The API is simple: setup() for initialization, draw() for the animation loop, and a handful of functions for drawing shapes, colors, and transforms.

Rust didn't have anything like this.

Don't get me wrong—Rust has excellent graphics options. Bevy is a full-blown game engine. Nannou is beautiful and batteries-included. Macroquad offers immediate mode simplicity. But none of them feel like p5.js. None of them invite you to type ellipse(100, 100, 50, 50) and see immediate results.

I wanted that. So I built it.

The Architecture

Here's how rust-sketch works:

rust-sketch/
├── crates/
│   ├── sketch-core/    # Sketch trait, context, color, vectors
│   ├── sketch-api      # p5.js-compatible API layer
│   ├── sketch-wgpu/   # wgpu rendering backend
│   └── sketch-cli/    # CLI runner

sketch-core defines the Sketch trait—the heart of the framework:

pub trait Sketch {
    fn setup(&mut self, ctx: &mut SketchContext) {}
    fn draw(&mut self, ctx: &mut SketchContext) {}
}

Simple. Familiar. But under the hood, SketchContext gives you access to everything: drawing primitives, color management, transforms, math helpers, input (mouse position, keys), and time tracking.

sketch-wgpu handles GPU rendering via wgpu—the same library Firefox and Deno use. This gives us cross-platform graphics with no external dependencies.

sketch-api provides the p5.js-compatible function names. background(), ellipse(), rect(), fill(), stroke()—all the functions creative coders expect.

What's Working

The MVP is functional:

Here's a working sketch:

use sketch_core::{Sketch, SketchContext};
use sketch_wgpu::run;

struct MySketch;

impl Sketch for MySketch {
    fn setup(&mut self, ctx: &mut SketchContext) {
        ctx.fill(ctx.color_rgb(255.0, 100.0, 150.0));
    }
    
    fn draw(&mut self, ctx: &mut SketchContext) {
        ctx.background(ctx.color_rgb(30.0, 30.0, 40.0));
        ctx.ellipse(ctx.mouse_x, ctx.mouse_y, 50.0, 50.0);
    }
}

fn main() {
    run::<MySketch>("My Sketch", 800, 600);
}

Run it with cargo run -p sketch-cli and you get a window where a pink circle follows your mouse against a dark background.

Why This Matters

Three reasons I think rust-sketch (and creative coding in Rust generally) is worth pursuing:

1. WebAssembly is the killer feature.

p5.js runs in browsers, which limits performance. Rust compiles to WASM with near-native speed. Imagine creative coding with thousands of particles, real-time fluid simulation, or audio processing that doesn't choke the main thread.

2. Type safety changes the debugging game.

Creative coding often means tweaking values until something looks right. But when things go wrong—wrong API usage, mismatched types, borrow errors—Rust catches them at compile time. The IDE experience is chef's kiss.

3. The bridge matters.

Many creative coders use p5.js as a gateway to programming. Rust has a steeper learning curve, but rust-sketch lowers the first step. The familiar API means p5 veterans can start creating immediately while gradually learning Rust's concepts.

What's Next

Phase 1 (MVP) is done. Phase 2 targets 90% API parity with p5.js—images, text, more geometry, better color blending. Phase 3 focuses on developer experience: hot reload so edits appear instantly, scaffolding to generate new sketches, better error messages.

Stretch goals include custom shaders (GLSL), audio processing, and 3D rendering.

The Real Lesson

Building rust-sketch taught me something I didn't expect: Rust's learning curve is a feature, not a bug—but only if you give people a reason to climb it.

A p5.js-compatible API gives people a reason. The safety and performance are the reward. Whether this specific project takes off or not, I believe Rust needs more "gateway" projects that welcome newcomers with familiar patterns while showing them what the language can do.

The framework is MIT-licensed, open source, and ready for contributors. If you've ever wanted to make things that move, glow, and dance—with Rust's guarantees—give it a try.


The code lives at github.com/ateeples/rust-sketch. Run cargo build and cargo run -p sketch-cli to see it in action.