
Learn Creative Coding (#31) - Creative Coding as a Practice
Learn Creative Coding (#31) - Creative Coding as a Practice

Thirty episodes. We went from "what is a canvas?" to building mint-ready generative NFT collections with seeded PRNGs, composition algorithms, and full trait systems. That's a lot of ground covered. But knowing the techniques isn't the same as being a creative coder. That part takes practice. Regular, consistent, playful practice.
This episode is different from the rest. Less about code and more about the craft. How to keep going once the tutorials end. How to grow your own creative voice. How to find community and inspiration when the blank canvas stares back at you.
But this being a creative coding series, I'm still going to show you code. Because the best way to talk about practice is to actually practice :-)
The daily sketch
The most common advice in creative coding communities: make something every day. Doesn't have to be good. Doesn't have to be finished. Just open your editor and make something.
I tried this for a while. Some days I'd spend two hours building something beautiful. Other days I'd stare at the screen for ten minutes, draw some circles, and close the laptop. Both count.
The point isn't perfection. The point is showing up. Your 50th daily sketch will be noticeably better than your 5th, and you won't know exactly when it happened. It's gradual. Like everything worth doing.
What a daily practice looks like
Here's a week of my actual sketching log (condensed):
Day 1: Play with sin waves. Different frequencies, different colors.
Day 2: Yesterday's sin waves but on a grid.
Day 3: Random walk. One pixel at a time.
Day 4: Random walk but the color changes based on direction.
Day 5: Failed experiment with 3D. Learned something about perspective.
Day 6: Revisited Day 2's grid with noise instead of sin.
Day 7: Combined Day 4's color-walk with Day 6's noise grid.
See the pattern? You don't need a brand new idea every day. Yesterday's sketch plus one new twist equals today's sketch. Ideas compound.
Here's what Day 1 might look like in actual code -- a quick 15-minute sketch with animated sin waves:
let canvas = document.createElement('canvas');
canvas.width = 600;
canvas.height = 400;
document.body.appendChild(canvas);
let ctx = canvas.getContext('2d');
let t = 0;
function draw() {
ctx.fillStyle = 'rgba(10, 10, 30, 0.1)';
ctx.fillRect(0, 0, 600, 400);
for (let i = 0; i < 8; i++) {
ctx.beginPath();
let freq = 0.01 + i * 0.003;
let amp = 30 + i * 15;
let hue = (i * 45 + t * 0.5) % 360;
ctx.strokeStyle = `hsl(${hue}, 80%, 60%)`;
ctx.lineWidth = 2;
for (let x = 0; x < 600; x++) {
let y = 200 + Math.sin(x * freq + t * 0.02 + i) * amp;
if (x === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
}
t++;
requestAnimationFrame(draw);
}
draw();
Nothing fancy. Eight sin waves with different frequencies and colors, fading trail. Takes ten minutes to write. But it moves. It's hypnotic. And tomorrow you can put it on a grid and see what happens.
Then Day 2 -- same concept, on a grid
let canvas = document.createElement('canvas');
canvas.width = 600;
canvas.height = 600;
document.body.appendChild(canvas);
let ctx = canvas.getContext('2d');
let t = 0;
let cols = 12;
let rows = 12;
let cellW = 600 / cols;
let cellH = 600 / rows;
function draw() {
ctx.fillStyle = '#0a0a1e';
ctx.fillRect(0, 0, 600, 600);
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
let cx = col * cellW + cellW / 2;
let cy = row * cellH + cellH / 2;
ctx.save();
ctx.translate(cx, cy);
ctx.beginPath();
let hue = (col * 20 + row * 15 + t * 0.3) % 360;
ctx.strokeStyle = `hsl(${hue}, 70%, 55%)`;
ctx.lineWidth = 1.5;
for (let x = -cellW / 2; x < cellW / 2; x += 2) {
let freq = 0.1 + col * 0.02;
let amp = cellH * 0.3;
let y = Math.sin(x * freq + t * 0.03 + row * 0.5) * amp;
if (x === -cellW / 2) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
ctx.restore();
}
}
t++;
requestAnimationFrame(draw);
}
draw();
Same sin wave concept, now in a 12x12 grid. Each cell has slightly different frequency and phase. The hue shifts across the grid. Already it looks completely different from Day 1, but the code shares maybe 70% of the same ideas. That's daily practice -- incremental exploration, not reinvention.
Constraints as a creative tool
When you have infinite possibilities, it's paralyzing. Constraints free you. Some of my favorites:
- "Only circles today"
- "Maximum 20 lines of code"
- "No color -- only black and white"
- "Must use noise"
- "Inspired by the weather outside right now"
The best daily sketches come from weird constraints. "Draw the letter Q using only particle systems." You'd never choose that on your own, but the constraint forces you into creative territory you'd never explore otherwise.
Here's a constraint-based exercise: draw something interesting using ONLY rectangles and a 3-color palette. No circles, no curves, no gradients:
let canvas = document.createElement('canvas');
canvas.width = 600;
canvas.height = 600;
document.body.appendChild(canvas);
let ctx = canvas.getContext('2d');
let palette = ['#0d1b2a', '#e0e1dd', '#e76f51'];
ctx.fillStyle = palette[0];
ctx.fillRect(0, 0, 600, 600);
function seededRandom(seed) {
let s = seed;
return function() {
s = (s * 16807 + 0) % 2147483647;
return s / 2147483647;
};
}
let rng = seededRandom(42);
for (let i = 0; i < 200; i++) {
let x = rng() * 600;
let y = rng() * 600;
let w = rng() * 80 + 5;
let h = rng() * 80 + 5;
let colorIdx = rng() < 0.7 ? 1 : 2;
ctx.globalAlpha = rng() * 0.4 + 0.05;
ctx.fillStyle = palette[colorIdx];
ctx.fillRect(x - w / 2, y - h / 2, w, h);
}
ctx.globalAlpha = 1;
Three colors. Only fillRect. 200 overlapping translucent rectangles. The constraint forces composition through density and overlap rather than shape variety. And it actually looks good. The limited palette keeps it cohesive. The transparency creates depth. Constraint = creative focus.
The 20-line challenge
This one's my favorite. Can you make something visually interesting in 20 lines of code or fewer? It forces you to find the shortest path to visual impact:
let c = document.createElement('canvas');
c.width = c.height = 600;
document.body.appendChild(c);
let x = c.getContext('2d');
x.fillStyle = '#111';
x.fillRect(0, 0, 600, 600);
for (let i = 0; i < 500; i++) {
let a = Math.random() * Math.PI * 2;
let r = Math.random() * 250 + 20;
let cx = 300 + Math.cos(a) * r;
let cy = 300 + Math.sin(a) * r;
let s = Math.random() * 8 + 1;
x.beginPath();
x.arc(cx, cy, s, 0, Math.PI * 2);
x.fillStyle = `hsl(${a * 57.3}, 70%, ${50 + r * 0.1}%)`;
x.globalAlpha = 0.6;
x.fill();
}
Seventeen lines. A ring of colored dots where the hue follows the angle (a * 57.3 converts radians to degrees -- remember the trig from episode 13?) and the lightness increases with distance from center. It looks like a lo-fi galaxy. Under 20 lines. Constraint met.
Community challenges
Genuary
The biggest creative coding event of the year. Every January, a new prompt every day for 31 days. Prompts like "No palettes," "Destroy a square," "In the style of Vera Molnar," "Glitch."
The community shares work on social media with #genuary and #genuary2026. It's the best time to discover new creative coders, learn techniques, and get inspired.
You don't have to do all 31 days. Do 5. Do 10. Whatever you can. Nobody's judging. Some of the most impressive creative coding portfolios started as Genuary submissions that grew into larger projects.
#WCCChallenge
The Creative Code Collective runs weekly challenges with specific themes. More relaxed pace than Genuary. Great for building a regular habit without the intensity of daily prompts.
Inktober (creative coder's version)
Originally for ink drawings, but creative coders have adopted it. October, 31 prompts, but instead of pen on paper, you use code. Some people generate plotter art -- code that outputs SVG, which gets drawn by a physical pen plotter on real paper. Full circle (we touched on SVG output in episode 29).
36 Days of Type
A typography challenge: one letter or number per day, designed creatively. Perfect for generative typography (episode 26). Build each letter with a different algorithm. Feed the letter into the particle sampler from episode 26 and let the algorithm interpret it differently each day.
Where to share your work
Your sketches deserve an audience. Even a small one.
Social media -- Mastodon and the Fediverse have a very active creative coding community. Instagram is still good for visual work if you use the right hashtags. Bluesky has a growing community too.
Dedicated platforms -- OpenProcessing is specifically for p5.js and Processing sketches, everything runs in the browser so people can see your code AND the output. Shadertoy for GLSL shader art (we'll get deep into shaders soon). CodePen for anything web-based.
Here on Hive! -- creative coding content does well on Hive. The StemSocial community supports technical creative content. And art communities like Alien Art Hive would love to see generative work.
Documenting your process
The most engaging posts aren't just the final image. They show the process:
Post structure that works well:
1. "Here's the idea I started with" (one sentence)
2. "Here's my first attempt" (screenshot, probably ugly)
3. "Here's what I changed and why" (the interesting part)
4. "Here's where I got stuck" (people love honesty)
5. "Here's the result" (final screenshot or animation)
6. Code snippets for the key technique
People love seeing how something was made. It's more interesting than just the output. And it teaches others. The journey is the content, not just the destination.
Tools beyond what we've used
We've stuck to p5.js and vanilla Canvas/WebGL. The creative coding world is much bigger.
Processing (Java)
The original. p5.js is its JavaScript port. Processing itself runs on Java and has been around since 2001. More mature, faster for high-resolution output. If you ever need to render a 10,000x10,000 pixel image for a gallery print, Processing handles it better than the browser.
openFrameworks (C++)
For performance-intensive work. Real-time installations, projection mapping, computer vision. If you need to process live camera feeds or drive LED arrays, openFrameworks is the tool. The creative concepts (noise, particles, feedback) are the same ones we learned -- the language just runs faster.
TouchDesigner
Visual node-based programming. You connect nodes instead of writing text code. Popular for live visuals, VJ performances, and interactive installations. Different mental model but the same creative vocabulary. Noise nodes, particle nodes, feedback loops -- same ideas, different interface.
Hydra
Live-coded visuals in the browser. You type code and see the result instantly. No setup, no save, pure experimentation. It's basically a visual synthesizer:
// Hydra example (not Canvas API -- Hydra has its own syntax)
// This creates a feedback pattern of oscillating colors
osc(10, 0.1, 1.5)
.rotate(0, 0.1)
.color(1.2, 0.5, 0.8)
.modulate(noise(3), 0.05)
.out()
That's four lines and it creates a moving, morphing, infinite pattern. Hydra is incredible for live performances and quick experimentation. The feedback and modulation concepts will make more sense once we go deeper into shaders -- the principles are similar.
Nannou (Rust)
Creative coding framework in Rust. If you want systems-language performance with creative coding ergonomics. Growing community. The Rust ownership model feels weird at first for creative coding (where you're used to just throwing things at the canvas) but people who stick with it say it changes how they think about code structure.
Pen plotters
Physical machines that draw with actual pens on actual paper. You generate SVG (episode 29), the plotter draws it. There's something deeply satisfying about watching a machine slowly draw your algorithm in real ink on real paper. Popular models: AxiDraw by Evil Mad Scientist, vintage HP plotters.
The plotter community is one of the warmest in creative coding. Something about the physical output makes people generous with knowledge and feedback.
Building a starter template
One thing that helps with daily practice: having a template ready to go. No friction. Open file, start drawing. Here's a minimal one you can keep around:
// daily-sketch.js -- copy this, start adding stuff
let canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 800;
document.body.style.margin = '0';
document.body.style.background = '#111';
document.body.appendChild(canvas);
let ctx = canvas.getContext('2d');
// seeded random (from episode 24)
function sfc32(a, b, c, d) {
return function() {
a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0;
let t = (a + b) | 0;
a = b ^ b >>> 9;
b = c + (c << 3) | 0;
c = (c << 21 | c >>> 11);
d = d + 1 | 0;
t = t + d | 0;
c = c + t | 0;
return (t >>> 0) / 4294967296;
};
}
let seed = Date.now();
let rng = sfc32(seed, seed ^ 0xDEADBEEF, seed ^ 0xCAFEBABE, seed ^ 0x12345678);
for (let i = 0; i < 15; i++) rng(); // warmup
// helpers
function random(min, max) {
if (min === undefined) return rng();
if (max === undefined) { max = min; min = 0; }
return min + rng() * (max - min);
}
function pick(arr) {
return arr[Math.floor(rng() * arr.length)];
}
// --- your sketch starts here ---
ctx.fillStyle = '#0a0a1e';
ctx.fillRect(0, 0, 800, 800);
// ... start drawing ...
Copy this file. Rename it with today's date. Start adding shapes below the comment. The seeded random from episode 24 is already wired up. You have random() and pick() ready to go. Zero setup time. That matters when you're trying to sketch every day -- any friction between "I want to make something" and "I'm making something" is friction that'll stop you on tired days.
Finding your voice
Technical skill is necessary. But what makes creative coding art (not just tech demos) is your perspective. Your taste. Your obsessions.
Some questions that help you find your direction:
What do you keep coming back to? If you always end up building flow fields, that's not a limitation -- that's your interest. Go deeper. Become the flow field person. Tyler Hobbs became the flow field person and created Fidenza, one of the most valuable generative art collections ever.
What other art do you love? If you love minimalism, make minimalist generative art. If you love maximalism, go dense. Your taste is your compass. When I first started I was pulling from old map cartography and botanical illustration. That's still in my work if you squint :-)
What's your relationship with randomness? Some coders love maximum chaos. Others want total control with tiny variations. Where you sit on that spectrum -- we explored this back in episode 24 -- is part of your voice.
What medium calls to you? Screen? Print? Plotter? Installation? Projection? Each medium has different constraints and possibilities.
It's okay to be derivative at first
Your first 100 sketches will look like other people's work. That's fine. That's how learning works. You study flow fields because Tyler Hobbs made them famous. You try Mondrian subdivision (episode 25) because someone on OpenProcessing inspired you. You experiment with grain because you saw it in episode 27.
Gradually, your combinations become unique. Your palette sense differs from mine. Your instinct for density and composition is yours. The techniques are shared -- the taste is personal.
Staying inspired
Creative coding has dry spells. You open your editor and nothing comes. That's normal. Some antidotes:
- Browse OpenProcessing or Shadertoy -- seeing other people's work often sparks ideas
- Look at non-digital art -- paintings, architecture, textiles, nature. The best creative coding references aren't code
- Read about an algorithm you've never used -- Voronoi diagrams? Reaction-diffusion? Poisson disk sampling? New math equals new visuals
- Revisit old sketches -- your sketch from three months ago plus today's skills? That's a new piece
- Collaborate -- show someone your work, ask what they'd change, build on each other's ideas
Here's a quick "inspiration prompt" generator you can run when you're stuck:
let subjects = ['circles', 'lines', 'triangles', 'noise field', 'grid', 'spiral',
'text', 'pixels', 'particles', 'rectangles', 'arcs', 'dots'];
let modifiers = ['overlapping', 'rotating', 'fading', 'growing', 'splitting',
'merging', 'bouncing', 'flowing', 'pulsing', 'morphing'];
let constraints = ['only 3 colors', 'black and white', 'no fill only stroke',
'under 20 lines', 'using noise', 'symmetrical', 'must animate',
'monochrome', 'using sin/cos', 'interactive'];
let rng = Math.random;
let prompt = modifiers[Math.floor(rng() * modifiers.length)] + ' ' +
subjects[Math.floor(rng() * subjects.length)] + ', ' +
constraints[Math.floor(rng() * constraints.length)];
console.log('Today\'s prompt:', prompt);
// "rotating triangles, only 3 colors"
// "flowing particles, under 20 lines"
// "pulsing noise field, monochrome"
Silly? Maybe. But it works. "Flowing particles, monochrome" is a much better starting point than "I dunno, make something." Constraints generate ideas. Always have.
A sketch-a-day workflow
After a few months of daily sketching, here's the workflow I settled into:
- Copy the template (the starter template from earlier)
- Pick a constraint -- either from the prompt generator, from a community challenge, or from yesterday's leftovers
- Set a timer -- 30 minutes max. If it's not working after 30 minutes, save what you have and move on
- Save everything -- even the failures. Especially the failures. You'll revisit them
- Screenshot the output -- one PNG per day. At the end of the month you have a visual diary
The timer is crucial. Without it, you'll spend three hours perfecting one sketch and then not touch code for a week. Better to do 30 mediocre minutes every day than one perfect evening per month. Consistency beats intensity.
If you want to get organized about it, you can automate the saving:
// add to your template -- press 's' to save with today's date
document.addEventListener('keydown', function(e) {
if (e.key === 's') {
e.preventDefault();
let date = new Date().toISOString().split('T')[0];
let link = document.createElement('a');
link.download = 'sketch-' + date + '.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
});
Same save-to-PNG approach we used in episode 20 for recording and exporting. Press 's', get a dated PNG. After a month you have sketch-2026-04-01.png through sketch-2026-04-30.png. A visual journal of your creative development.
't Komt erop neer...
- Daily practice matters more than daily perfection -- show up, make something, let it compound
- Constraints (material, code length, color limit) force creativity more than freedom does
- Community challenges give you structure: Genuary (January), #WCCChallenge (weekly), 36 Days of Type, Inktober
- Document process, not just output -- people learn from your journey, not just your finished pieces
- Keep a starter template ready so there's zero friction between "I want to make something" and actually making it
- Explore tools beyond the browser: Processing, openFrameworks, TouchDesigner, Hydra, pen plotters
- Your creative voice emerges from your obsessions and taste -- lean into what you keep coming back to
- Dry spells are normal. Use prompt generators, revisit old work, browse other people's sketches
- Consistency beats intensity. Thirty minutes every day beats one perfect evening per month.
This wraps up the original Creative Coding series arc. From shapes and colors to NFT collections to creative practice. But we're far from done. We barely scratched the surface of shaders in episode 21 -- just enough to see how the GPU thinks differently from the CPU. From here, we're going deep into that world. Uniforms, signed distance functions, noise on the GPU, feedback loops, raymarching... shader programming is a whole new paradigm and it opens up territory that Canvas can't touch. The next phase of the series will change how you think about rendering entirely :-)
Sallukes! Thanks for reading.
X
Estimated Payout
$0.13
Discussion
No comments yet. Be the first!