You can just make music
The browser you're reading this in contains a full drum machine. Not "could download an app" — it's one line of code away, and by the end of this post you'll have pressed play on four of them without installing anything.
This is a tutorial about Strudel, a wonderful live-coding music engine — you type little patterns, it makes beats. Every example below is a real app running live in this page. Press play. Then remix one and make it yours.
The one line that does all the work
Normally, using a music engine in your app means a project setup: package
managers, import statements, build tools, and a folder of other people's
code that becomes part of your app. If you've never done that, good news —
you're not going to start today.
Here's the entire trick, and the only "advanced" code in this post:
jsconst web = await import("https://esm.sh/@strudel/[email protected]");
Read it like a sentence: when someone presses play, go fetch the Strudel engine from that address and hand it to me. The engine lives on a public shelf on the internet (a CDN), and the visitor's browser picks it up at that moment — exactly the way it picks up a webpage. It is not copied into your app. Your app is just your fifty lines; the instrument is borrowed at showtime, not photocopied into your sheet music.
That distinction is more than tidy — it's respectful. Strudel is licensed under the AGPL, a strong share-alike license: build Strudel's code into your program, and your program is expected to adopt the same license. That's a great deal for a music tool, but it's a decision you shouldn't have to make to play a kick drum. Loading the engine at runtime keeps the two programs separate: Strudel stays whole, credited, and under its own license at its own address, and your fifty lines stay yours. (Usual caveat: we're enthusiasts, not lawyers — and either way, credit the Strudel project visibly. They made the magic.)
On Vibes you don't even have to remember the line — every example below is a public vibe you can open and remix, loader included. Let's play.
Step 1 — press play
One button. When you press it, the engine arrives (first press takes a few seconds — it's fetching real drum sounds), and then this plays:
jss("bd*4, ~ cp ~ cp, hh*8")
That string is a whole song, or at least a whole groove: bd*4 is four bass
drums per bar, ~ cp ~ cp is a clap on the off-beats, hh*8 is eight
hi-hats, and the commas mean play all of these at once.
Get posts like this in your inbox
One email field. Real updates. No algorithm required.
Step 2 — the pattern language
Those little strings are called mini-notation, and they're the whole game. Words are drum sounds. Spaces divide the bar. A few symbols do the rest:
| write | meaning |
|---|---|
bd sd | kick, then snare |
~ | silence |
bd*2 | twice as many |
[sd sd] | squeeze two into one slot |
<sd cp> | snare this bar, clap the next |
bd sd, hh*8 | both lines at once |
Type anything into this one — it's a text box wired straight to the engine. The chips load examples of each symbol:
Step 3 — you don't have to show anyone the code
Here's the part that turns a toy into an app: your interface can write the pattern for you. This is a classic step sequencer — three rows of buttons, and every toggle rebuilds the mini-notation string and hands it to the engine, live, while it plays:
The translation from buttons to music is one honest function — a lit button
becomes its drum sound, an unlit one becomes ~:
jsfunction toCode(grid) {
const lines = ROWS.map(([sound]) =>
` s("${grid[sound].map((on) => (on ? sound : "~")).join(" ")}")`
);
return `stack(\n${lines.join(",\n")}\n).cpm(110/8)`;
}
stack(...) is "play these together," and cpm() sets the tempo — one
small gotcha worth knowing: it counts whole loops per minute, not beats,
so you divide your BPM by how many beats one loop holds (our eight steps
span two bars, hence the 8). When in doubt, divide until it grooves.
Step 4 — knobs
Patterns take effects by chaining them on the end: .lpf(1200) is a filter
that muffles the highs, .room(0.3) adds space, .cpm() sets how fast the loop spins.
Which means sliders are just numbers dropped into the same string:
Drag while it plays. There's a bassline hiding under that filter.
Where this goes
Each demo above is a public vibe: open it, hit remix, and the loader line comes with it — you start at "making music" instead of "configuring a project." That's the actual point of the runtime-import trick. It's not a license workaround, it's a division of labor: the Strudel folks maintain a brilliant instrument at a public address, and you write the fifty lines that are actually yours — the interface, the idea, the song.
If you want to see how far the same trick stretches, jchris/strudel is the full live-coding version: an editor, saved patterns, and an AI prompt box that rewrites your groove when you ask it to "make it darker."
Make a noise machine of your own
Remix any demo in this post, or describe the instrument you wish existed.
Start building →