creative-lab: Shipping a Visual Demo Every Two Days
creative-lab: Shipping a Visual Demo Every Two Days
GitHub: bkmashiro/creative-lab · Live: cl.yuzhes.com
The Premise
Creative coding as a daily (well, every-two-days) practice. Ship something visual. Keep it self-contained. Don’t think about it too hard.
That’s the rule. Each demo in creative-lab is a single HTML file: no npm, no bundler, no build step. Open it in a browser and it runs. The gallery index is a dark-themed grid that loads every demo inline.
There are 12 demos so far. Number 13 is probably being written right now.
The Demos
| # | Name | Technique |
|---|---|---|
| 001 | Particle Physics | Canvas 2D, Verlet integration |
| 002 | Fractal Tree | Recursive canvas drawing |
| 003 | Wave Interference | Superposition, 2D field |
| 004 | Mandelbrot Explorer | WASM / pure JS, zoom, coloring |
| 005 | Cellular Automaton | Conway’s GOL variant, canvas |
| 006 | Audio Visualizer | Web Audio API, FFT, canvas |
| 007 | Gravity Simulator | N-body, Barnes-Hut approximation |
| 008 | Cloth Physics | Spring-mass system, canvas |
| 009 | Ray Marching | SDF, WebGL fragment shader |
| 010 | L-System Trees | Lindenmayer grammar, SVG |
| 011 | Reaction Diffusion | Gray-Scott model, canvas |
| 012 | Fluid Simulation | SPH particles, WebGL |
Each file is between 100 and 300 lines. Some are pure math, some are GPU-bound. All of them run without a server.
Single-File Philosophy
The constraint is intentional. A single HTML file is:
- Portable — copy it anywhere, it works
- Auditable — you can read the whole thing in one scroll
- Low-friction — no setup, no
npm install
The demos inline everything: CSS in <style>, JS in <script>, assets as base64 if needed. For WebGL demos, the shaders are template literals inside the JS. It’s not elegant in the traditional sense, but it’s self-contained in a way that a webpack bundle never quite is.
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; background: #0a0a0f; }
canvas { display: block; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
// entire demo in here, ~150 lines
const canvas = document.getElementById('c');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// ...
</script>
</body>
</html>
That’s the template. Start there. End somewhere interesting.
The Cron Pipeline
The interesting part isn’t the demos themselves — it’s how they get generated.
Every two days, a cron job fires a Claude agent with the following context:
- The
todo.mdfile from the repo root (a numbered list of demo ideas) - The most recently generated demo (as a style/structure reference)
- Instructions to write the next demo in the list, following the single-file constraint
The agent writes the HTML file, updates the gallery index, and commits directly to the repo. Cloudflare Pages picks up the commit and deploys within a minute.
The todo list looks roughly like this:
# Demo Ideas
- [x] 001 Particle Physics
- [x] 002 Fractal Tree
...
- [x] 012 Fluid Simulation
- [ ] 013 Voronoi Diagram
- [ ] 014 Strange Attractors
- [ ] 015 Metaballs
- [ ] 016 Fourier Drawing
...
When the agent picks up the next unchecked item, it checks it off, generates the demo, and commits. The pipeline is entirely automated — I set it up once and it runs.
What the Agent Gets Right (and Wrong)
Most demos come out working on the first try. Simple particle systems, fractal trees, cellular automata — these are well-covered in training data and the agent generates clean, correct code.
The harder ones — fluid simulation, ray marching — sometimes need a nudge. The agent occasionally produces physically plausible but visually uninteresting results (e.g., an SPH fluid that technically conserves momentum but runs at 3fps and looks like a gray blob). When that happens, I regenerate with a more specific prompt (“make the particles smaller, increase the interaction radius, use a warm color gradient based on velocity”).
One thing the agent does consistently well: the visual style. Dark background, bright particles or lines, smooth animation. It’s picked up the aesthetic from the reference demos and applies it reliably.
One thing it does less well: performance. An agent-generated WebGL shader is rarely optimized. If the demo stutters, I usually drop into the file and fix the hot path manually — but the structure and math are almost always correct.
The Gallery Index
The gallery is a hand-written HTML file that loads each demo in an <iframe> for the thumbnail preview. It auto-discovers demos by reading a manifest.json generated at commit time:
[
{ "id": "001", "name": "Particle Physics", "file": "demos/001.html" },
{ "id": "002", "name": "Fractal Tree", "file": "demos/002.html" },
...
]
The manifest is updated by the agent as part of the commit. Clicking a thumbnail opens the demo full-screen. The layout is CSS Grid, 3-4 columns depending on viewport width.
Why This Works
The two-day cadence is deliberate. One day is too fast — there’s no time to think about what to make. One week is too slow — it becomes a “project” with expectations. Two days is enough to pick something interesting from the list, trust the agent to implement it, and move on.
The zero-dependency rule removes an entire class of decisions. No framework debates, no bundler configuration, no dependency updates. Each demo stands alone.
The goal isn’t perfect demos. The goal is the habit of shipping.
Twelve demos in. The list has another forty items on it.
Running It Locally
git clone https://github.com/bkmashiro/creative-lab
cd creative-lab
# just open any demo directly
open demos/001.html
# or serve the gallery
python3 -m http.server 8080
No build step. No setup. It’s just files.