Free, open source drum/beat sequencer that runs in your browser. No ads, no account required, nothing to install. Written in pure JavaScript with no frameworks and no backend. It works on desktop, tablets and mobile phones.
Try it out: https://maximecb.github.io/groovie/
The same project either way. On a narrow screen the controls stack, the grid scrolls sideways and the mix controls move behind a button, so a pattern is edited the same way on a phone as on a desktop.
Sketch a beat in the step sequencer, then arrange your patterns into a song on the timeline below it. When it sounds right, hit "Copy link": the whole project is encoded into the hash portion of the URL, so anyone you send the link to can play it and remix it. Nothing is uploaded anywhere, and there is nothing to sign up for.
I hope this can be a valuable tool for teaching people about rhythm and music production, and a fun one for enthusiasts to sketch ideas with. If you think this project is cool and you want to support my open source work, you can sponsor me on GitHub.
Each of these links is the whole piece. There is nothing behind them: open one and you can play it, take it apart and remix it.
- The amen break — the most sampled break there is, laid onto a grid, and about as much as one pattern holds.
- A drum and bass roller — two-step at 174, with rimshots standing in for ghost notes and the hats opening into sixteenths for the last half bar.
- A house groove, panned wide — 32 bars with the kit spread across the stereo field, and a light shuffle on the sixteenths that leaves the four to the floor where it is.
- A two step arrangement — garage at 136 with the sixteenths swung hard, where the two bar kit steps aside for a busier one over the middle eight and the shakers run three bars to its two.
- A dub techno arrangement — built around the delay, a dotted eighth fed by a rimshot and a metallic stab played sparsely enough to leave the repeats room.
- A berlin techno arrangement — 96 hypnotic bars at 133 that layer rather than tile, where the kick and the offbeat open hat hold under everything until the breakdown drops them and leaves the dotted eighth delay holding the room.
- A psytrance arrangement — the rolling sixteenth bass answering the kick that the whole genre is built on, with every row at a level of its own and a twelve step percussion layer that only comes back into line with the bar every three of them.
- A rave with vocal one shots — 60 bars at 138 over a doubled kick, where half the twelve patterns are single vocal and alarm hits dropped onto the timeline where they land.
- A drill and bass arrangement — 64 bars across eight patterns at 165, the longest and busiest of these, and the one that pushes the encoding hardest at 354 characters.
- A rap arrangement — a three minute song laid out the way a rap single is, four bars of intro then sixteen bar verses that hand off to the hook on a fill, with a shaker three bars long drifting against the two bar kit underneath all of it.
- A rock arrangement — 112 bars at 132 played straight, where the feel comes from the humanize control rather than from swing: every hit lands a little late and a little down, drawn afresh each time, with the kick held closer to the grid than the rest of the kit. Verses and choruses closed off by tom fills, and a one bar crash dropped on each section downbeat.
- A tech house arrangement — 96 bars at 127 out of a plain kit, where everything sits on the four and the movement comes from the pattern lengths instead: a four bar engine whose last bar pushes into the next section, a shaker layer a bar and a half long that lands on the downbeat one pass and the offbeat the next, and a cowbell fed to the delay almost wet.
Free-running polymeters. Steps have a fixed duration rather than a fixed number per pattern, so a 15-step pattern and a 16-step one drift against each other and only line up again much later. Odd pattern lengths give you grooves that keep evolving instead of resetting every bar.
- Patterns of 1 to 64 steps and up to 16 rows, up to 64 patterns per project
- Over 150 public domain (CC0) samples: kicks, snares, hats, toms, percussion and cymbals, plus vocals, game sounds and assorted noise
- Per-row sample, stereo panning, level in dB and delay send
- A tempo-synced delay set in fractions of a step, from slapback up to a full bar
- A filter across the whole mix on one knob, low-pass below the centre and high-pass above it, the way a DJ mixer does it, with its own resonance control
- Tempo from 40 to 280 BPM, plus swing and humanize controls: swing shifts the off-beats, humanize scatters every hit a little in time and level so a pattern stops repeating itself exactly
- Patterns can be switched while the music plays: the one you pick is queued and launches when the playing one comes around, the way a groovebox does it
- MIDI clock output, to run a drum machine or synth in time with the page: start, stop and clock broadcast to every connected device, at rates from the standard 24 PPQ down to 2 PPQ for gear that wants a slower one. Chrome and other Chromium browsers only, since Safari has no Web MIDI and Firefox will only hand it over once you have installed an add-on
- Works on desktop, tablets and phones
Space |
Play or stop the song, or the current pattern when the timeline is empty |
P |
Play or stop the pattern being edited |
T |
Play or stop the timeline |
← → |
Move to the previous or next pattern |
| Shift+click a timeline lane | Open that lane's pattern for editing, without placing or removing anything |
Shift-clicking a lane does what its numbered label at the left does, except that anywhere on the lane works. On a long song the label can be a long way from the part of the arrangement you are looking at, and shift saves the trip back to it.
Clone the repo and start a local HTTP server as follows:
git clone https://github.com/maximecb/groovie.git
cd groovie
./tools/dev_server.pyThen open http://localhost:8001. Nothing to install or build, but the page does
have to be served over HTTP: it loads as an ES module and fetches its samples,
which browsers block on file://. The server needs Python 3 and sends no-cache
headers, so a reload always picks up your last edit.
The repo ships a Claude Code skill in .claude/skills/make-a-beat. Run Claude Code
from a clone and ask it for a beat ("make me a psytrance loop", "swing it harder",
"make it longer") and it writes the song out, encodes it with tools/make_song.js
and hands back a link you can open in your browser, play and remix like any other.
The skill covers the sample library, the tempo and mixing ranges, and how the
corpus songs are built into arrangements. Nothing is uploaded: the link is the
song, same as always.
The code is distributed under an MIT license, while the samples are under a CC0 license.
We could use more high quality samples. These should be in 44.1KHz 16-bit mono PCM wav format,
and they have to be available under the CC0 license (public domain). We cannot include
copyrighted samples.
You can run tools/convert_samples.sh to convert new samples to the expected format,
which the CI will check.
Plain ES modules, no build step and no dependencies. index.html loads main.js,
which pulls in the rest.
model.js |
The project itself: patterns, rows, the timeline, and the URL encoding a link is made of. Knows nothing about the DOM or about audio. |
audio.js |
The sample library and the Web Audio graph, including the scheduler that decides what plays when. |
midi.js |
The MIDI clock sent to outboard gear. The scheduler hands it the same position line it queues samples on, so the two can't drift apart. |
view.js |
Renders the pattern grid and the timeline. The views are a function of the model: rendering reads project state and never writes it. |
main.js |
The wiring. Controls, buttons, keyboard, and keeping the link in the address bar in step with the project. |
sample_list.js |
Generated map of sample paths to indices. Rebuilt by tools/update_samples.py, not edited by hand. |
A sample index is permanent once it has been used in a shared link, which is why that map is generated rather than sorted on the fly.
tests/corpus.js holds the songs the encoding is exercised and measured on, and is
kept apart from the tests because two things use it: the tests round-trip the songs,
and tools/link_sizes.js reports what each one costs as a link. A change to the
encoding is judged on what it does to that table. design.md covers the decisions
behind the model and the URL scheme.
There is nothing to install. The tests run on the test runner built into Node, and need Node 22 or later:
./tools/run_tests.shThe tests cover the project model and the URL encoding in model.js, and the
sample library in audio.js. Playback and the DOM are not covered, since they
need a browser.
Note that the model states its preconditions with console.assert, which only
prints a message in the browser rather than stopping anything. tests/setup.js
makes those count as test failures, and tools/run_tests.sh loads it ahead of
every test file, so run the tests through that script rather than calling
node --test directly.
tests/encoding.test.js holds a few golden links, and tests/golden_links.js
holds the link every song in the corpus encodes to. A shared link has to keep
opening as the project it was made from, so a failure there means that
already-shared links now decode differently. The corpus links are regenerated
by node tools/update_golden.js, which is only for when the corpus itself
changes: a failure that the corpus didn't cause is the encoding breaking links,
and re-running the script would only hide it.
The CI also runs two checks you can run yourself:
./tools/check_js.sh # every .js file parses as an ES module
python3 tools/check_samples.py # sample format, and sample_list.js against the samples
