strudel
Skill1 starsChanged 7 months agoMITView on GitHub
Use when live coding music with Strudel — pattern-based algorithmic music in the browser using mini-notation, synths, samples, effects, scales, MIDI/OSC, and Euclidean rhythms.
3 other projects use a version of this.
Adopted by
Most recently taken up by
- eXodes/skills-workspacetheir own version, first seen Jun 2, 2026
- aleiby/claude-skillstheir own version, first seen Mar 26, 2026
- renatoworks/strudel-claudetheir own version, first seen Feb 3, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- renatoworks/strudel-claude★ 61same name
- eXodes/skills-workspace★ 3same name
- aleiby/claude-skills★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository12 other files it gives its agents.
- advanced-swift-patternsSkill
- apotheneum-patternSkill
- githubSkill
- idea-framingSkill
- metal-graphicsSkill
- realitykit-visionosSkill
- sonic-piSkill
- swift-concurrencySkill
- swiftui-architectureSkill
- te-patternSkill
- te-shaderSkill
- te-showSkill
The file
Files
Strudel Live Coding Reference
Comprehensive reference for Strudel (v1.2), a browser-based live coding environment for algorithmic music. JavaScript port of TidalCycles, runs entirely in the browser at strudel.cc with no installation required.
Core Concepts
- Patterns, not sequences — code generates repeating time patterns, not linear note lists.
- Cycles, not bars — default 0.5 CPS (1 cycle = 2 seconds). Use
setcps()orsetcpm()to change tempo. - Mini-notation — rhythm/timing syntax inside quoted strings:
"bd sd hh oh". - Method chaining — functions chain left to right:
note("c3 e3").sound("piano").lpf(800). - Orbits — patterns on the same orbit share delay/reverb. Default orbit is 1.
- Hot-reload — edit code while it plays; changes take effect on the next cycle.
Mini-Notation
The pattern language used inside quoted strings.
Basics
| Syntax | Meaning | Example |
| Space | Sequence events in one cycle | "bd sd hh oh" |
~ or - | Rest (silence) | "bd ~ sd ~" |
*N | Speed up / repeat N times | "hh*8" = 8 hi-hats per cycle |
/N | Slow down over N cycles | "bd/2" = kick every 2 cycles |
<a b c> | One per cycle, rotate | "<bd sd cp>" |
[a b] | Subdivide time | "[bd bd] sd" = 2 kicks + 1 snare |
, | Play simultaneously (stack) | "bd, hh*8" |
@N | Elongate (weight) | "bd@3 sd" = kick takes 3/4 of cycle |
!N | Replicate without speeding | "bd!3 sd" = 3 kicks + snare, evenly spaced |
:N | Sample variant | "bd:3" = 4th variant of bass drum |
? or ?0.N | Random skip | "hh*8?0.3" = 30% chance each hh is silent |
(p,s) | Euclidean rhythm | "bd(3,8)" = 3 hits spread over 8 steps |
(p,s,o) | Euclidean with offset | "bd(3,8,2)" |
Nesting
Brackets nest arbitrarily deep for complex subdivisions:
"[bd [sd sd]] hh [oh [hh hh hh]]"Chords in Mini-Notation
"[c3,e3,g3] [d3,f3,a3]" // two chords per cyclePattern Constructors
| Function | Purpose | Example |
cat(a, b, c) | Sequence, 1 cycle each | cat("bd sd", "hh hh hh") |
seq(a, b, c) | Sequence, all in 1 cycle | seq("bd sd", "hh hh hh") |
stack(a, b) | Play simultaneously | stack(s("bd*4"), s("hh*8")) |
silence | Empty pattern | — |
run(N) | Numbers 0 to N-1 | run(8) = 0 1 2 3 4 5 6 7 |
arrange(...) | Cycle-range sections | arrange([4, "bd sd"], [2, "hh*8"]) |
Sound Sources
Triggering Samples
s("bd sd hh oh") // short form
sound("bd sd hh oh") // long formBuilt-in Drum Abbreviations
| Name | Sound |
bd | Bass drum (kick) |
sd | Snare drum |
hh | Closed hi-hat |
oh | Open hi-hat |
cp | Clap |
cr | Crash cymbal |
sh | Shaker |
cb | Cowbell |
tb | Tambourine |
rim | Rim click |
Variants via :N — "bd:0 bd:1 bd:2 bd:3" cycles through different kicks.
Drum Machine Banks
s("bd sd hh oh").bank("RolandTR808")
s("bd sd hh oh").bank("RolandTR909")Synth Oscillators
note("c3 e3 g3").sound("sine")
note("c3 e3 g3").sound("sawtooth")
note("c3 e3 g3").sound("square")
note("c3 e3 g3").sound("triangle")Noise types: white, pink, brown
Sample Manipulation
| Opt | Effect |
begin(0-1) / end(0-1) | Trim playback region |
speed(N) | Playback rate (negative = reverse) |
loopAt(N) | Fit sample to N cycles |
chop(N) | Granular: cut into N pieces |
slice(N) | Divide into N segments |
cut(group) | Stop previous sample in same cut group |
Loading Custom Samples
samples('github:user/repo') // from GitHub
samples({ name: 'https://url/to/file.wav' }) // direct URLSynths and Synthesis
FM Synthesis
note("c3 e3 g3")
.sound("sine")
.fmh(2) // harmonicity ratio (integer = tonal, decimal = metallic)
.fmenv(4) // modulation envelope
.fmdecay(0.2) // modulation decayWavetable Synthesis
Over 1000 waveforms from the AKWF library via wt_ prefix:
note("c3 e3 g3").sound("wt_piano")Additive Synthesis
note("c3").sound("sine")
.partials("0.5 0.3 0.1") // harmonic magnitudesVibrato
note("c4").sound("sine").vib(4).vibmod(0.5)Notes, Scales, and Chords
Note Formats
note("c3 e3 g3 c4") // letter notation (sharps: c#3, flats: eb3)
note("48 52 55 60") // MIDI numbers (decimals for microtonal)
freq("261 329 392 523") // frequency in HzScales
Numbers become scale degrees (zero-indexed). Any number "should sound good":
note("0 2 4 6 3 1 5 7").scale("C:major")
note("0 1 2 3 4 5 6 7").scale("A:minor:pentatonic")Common scales: major, minor, dorian, mixolydian, lydian, phrygian, locrian, major:pentatonic, minor:pentatonic, blues, chromatic, whole:tone, harmonic:minor, melodic:minor
Transposition
note("0 2 4").scale("C:major").add("<0 1 2 3>") // transpose by scale degrees
note("c3 e3").transpose(7) // transpose by semitones
note("0 2 4").scale("C:major").scaleTranspose(2) // move within scaleChords and Voicings
chord("Am C F G") // chord symbols
chord("Am C F G").voicing() // smart voice leading
note("<Am C F G>").voicing().sound("piano") // idiomatic usageVoicing modes: below (default), above, duck, root
Extract bass notes: .rootNotes(2) (octave 2)
Tempo
setcps(0.5) // cycles per second (default)
setcpm(30) // cycles per minute (default)Converting from BPM
// BPM / beats per cycle = CPM
setcpm(120 / 4) // 120 BPM with 4 beats per cycle = 30 CPMTime Modifiers
| Function | Effect | Example |
fast(N) | Speed up by N | .fast(2) = double speed |
slow(N) | Slow down by N | .slow(2) = half speed |
early(N) | Shift earlier | .early(0.25) |
late(N) | Shift later | .late(0.25) |
rev() | Reverse pattern | .rev() |
palindrome() | Alternate forward/backward | .palindrome() |
iter(N) | Rotate subdivisions each cycle | .iter(4) |
ply(N) | Repeat each event N times | .ply(2) |
swingBy(amt, div) | Add swing | .swingBy(1/6, 4) |
Euclidean Rhythms
s("bd").euclid(3, 8) // 3 hits over 8 steps (Cuban tresillo)
s("hh").euclid(5, 8) // 5 over 8 (rumba)
s("cp").euclid(7, 16) // 7 over 16Also available in mini-notation: "bd(3,8)", "hh(5,8,2)" (with offset).
Effects
Filters
| Function | Purpose | Example |
lpf(freq) / lowpass(freq) | Low pass filter | .lpf(800) |
hpf(freq) / highpass(freq) | High pass filter | .hpf(200) |
bandpass(freq) | Band pass filter | .bandpass(1000) |
lpenv(a, d, s, r) | Filter envelope (LP) | .lpf(2000).lpenv(0.01, 0.2, 0, 0) |
hpenv(a, d, s, r) | Filter envelope (HP) | .hpf(200).hpenv(...) |
Resonance: .lpf(800).lpq(10) (or .resonance(10))
Distortion
| Function | Purpose |
distort(amount) | Harmonic distortion |
crush(bits) | Bit-crush |
shape(amount) | Waveshaper |
Spatial
| Function | Purpose | Example |
pan(0-1) | Stereo position (0=L, 0.5=center, 1=R) | .pan(sine) |
jux(fn) | Apply fn to right channel only | .jux(rev) |
delay(time, feedback, wet) | Echo | .delay(0.5, 0.6, 0.3) |
room(size) | Reverb room size | .room(0.8) |
dry(amount) | Dry/wet mix | .dry(0.5) |
Modulation
| Function | Purpose |
tremolo(rate, depth) | Amplitude modulation |
phaser(rate, depth) | Phaser effect |
vibrato(rate, depth) | Pitch modulation |
Amplitude
| Function | Purpose |
gain(0-1) | Volume control |
velocity(0-1) | Multiplied with gain |
env(adsrPattern) | ADSR amplitude envelope |
attack, decay, sustain, release | Individual ADSR components |
Ducking / Sidechain
s("bd*4").orbit(0)
note("c2 c2 c2 c2").sound("sawtooth").orbit(1).duckorbit(0)Pattern Transformation
Layering and Offset
// Copy pattern, shift in time, and transform
note("0 [4 3]").scale("C:minor")
.off(1/8, x => x.add(4)) // offset + transpose copy
.off(1/4, x => x.add(7)) // another layerConditional Modifiers
| Function | Probability | Example |
sometimes(fn) | 50% | .sometimes(rev) |
often(fn) | 75% | .often(x => x.add(12)) |
rarely(fn) | 25% | .rarely(x => x.crush(4)) |
almostAlways(fn) | 90% | — |
almostNever(fn) | 10% | — |
sometimesBy(p, fn) | custom | .sometimesBy(0.3, rev) |
someCyclesBy(p, fn) | per-cycle | .someCyclesBy(0.5, fast(2)) |
Degradation
s("hh*16").degradeBy(0.5) // randomly remove 50% of events
s("hh*16").degrade() // shortcut for 50%Structure
s("hh").struct("1 0 1 1 0 1 0 1") // apply binary rhythm
s("bd sd").mask("1 1 0 1") // silence where mask = 0Arithmetic
| Function | Purpose | Example |
add(N) | Add / transpose | .add("<0 3 5 7>") |
sub(N) | Subtract | .sub(2) |
mul(N) | Multiply | .mul(2) |
div(N) | Divide | .div(2) |
Selection
pick(["bd sd", "hh oh", "cp cr"], "0 1 2 1") // select by indexMIDI
Sending MIDI Out
note("c3 e3 g3 c4").midi() // send to default MIDI output
note("c3 e3 g3").midi().channel(2) // specific channel (1-16)Receiving MIDI In
// MIDI keyboard input
midikeys().sound("piano")
// MIDI CC input
midin(1).range(200, 2000) // CC 1 mapped to rangeMIDI Mapping
Custom CC mappings: midimaps({ cutoff: 74, resonance: 71 })
OSC
note("c3 e3 g3").osc() // send as OSC to SuperCollider/SuperDirtRequires SuperCollider + SuperDirt running locally.
Visualization
Built-in inline visualizations:
note("0 2 4 6").scale("C:major").pianoroll()
s("bd sd hh oh").punchcard()
note("c3").scope()Idioms and Patterns
Minimal Techno
stack(
s("bd*4"),
s("~ cp").delay(0.5, 0.4, 0.3),
s("hh*8").gain(0.6).sometimes(x => x.speed(2)),
note("c2 ~ c2 ~").sound("sawtooth").lpf("<800 400 1200 600>").decay(0.1).sustain(0)
).setcpm(132/4)Ambient
stack(
note("<Am C F G>").voicing().sound("sine")
.release(4).room(0.9).delay(0.5, 0.7, 0.4),
note("0 2 4 7").scale("A:minor").slow(2).sound("triangle")
.gain(0.3).room(0.9)
).setcpm(60/4)Drum & Bass
stack(
s("[bd ~ bd ~] [~ sd ~ sd]").fast(2),
s("hh*16").gain("0.8 0.4").sometimes(x => x.speed(1.5)),
note("[c2 ~ c2 c2] [~ c2 ~ ~]").sound("sawtooth").lpf(600).fast(2)
).setcpm(170/4)Euclidean Polyrhythm
stack(
s("bd").euclid(3, 8),
s("sd").euclid(5, 8).gain(0.7),
s("hh").euclid(7, 16).gain(0.5),
s("cp").euclid(2, 8).delay(0.25, 0.5, 0.3)
)Generative Melody
note("0 1 2 3 4 5 6 7")
.scale("C:minor:pentatonic")
.sound("sine")
.sometimesBy(0.3, x => x.add(7))
.sometimesBy(0.2, x => x.rev())
.off(1/8, x => x.add(12).gain(0.4))
.room(0.5)
.delay(0.25, 0.4, 0.3)Strudel vs Sonic Pi
| Aspect | Strudel | Sonic Pi |
| Language | JavaScript | Ruby |
| Runs in | Browser (no install) | Desktop app |
| Time model | Cycles (CPS) | Beats (BPM) |
| Core abstraction | Pattern transformation | live_loop + sleep |
| Rhythm notation | Mini-notation strings | Rings + tick/look |
| Audio engine | Web Audio API | SuperCollider (scsynth) |
| Euclidean rhythms | euclid(3,8) or "bd(3,8)" | spread(3,8) ring |
| FX | Method chain | with_fx blocks |
| MIDI | .midi() | midi_note_on / midi |
| Randomness | sometimes, degrade, choose | one_in, choose, seeds |
| Collaboration | Multi-user via Flok | Single-user |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

