LJam is a browser-based loop sequencer with a 6-track grid interface. It uses Tone.js for built-in synthesis and supports Web MIDI output so you can drive external instruments and DAWs directly from the browser.
Six tracks are arranged in a 3×2 grid: two drum panels and four melodic synth panels. Each track has 10 slots and 8 chains for building arrangements on the fly.
Each grid panel has its own instrument. Drum panels let you toggle individual hits; melodic panels let you draw notes with variable length.
The interface is a fixed 3×2 layout of grid panels. Each panel is 32 steps long (two bars of 16 sixteenth notes).
| Position | Track | Type | Default Rows | Color |
|---|---|---|---|---|
| Top-left | KICK / SNARE | Drum | 6 instruments | Red |
| Top-center | PERCUSSION | Drum | 7 instruments | Orange |
| Top-right | BASS | Melodic | Scale-dependent | Green |
| Bottom-left | LEAD SYNTH | Melodic | Scale-dependent | Blue |
| Bottom-center | PAD / CHORDS | Melodic | Scale-dependent | Purple |
| Bottom-right | ARP / FX | Melodic | Scale-dependent | Cyan |
If bar 2 (steps 17–32) is empty for a track, the playhead loops at step 16 for that track.
Each track has 10 independent slots labeled A through J. Think of them as pattern variations for a single track.
Chains let you sequence slots into longer patterns. Each track has 8 chains.
When a chain is active, the sequencer automatically advances to the next slot in the chain at each loop boundary, wrapping around at the end.
| Control | Range | Default |
|---|---|---|
| BPM | 60–200 | 120 |
| Swing | 0–100% | 0% |
| Play / Stop | — | Stopped |
BPM and swing update live without stopping playback. Swing delays every second sixteenth note by the set amount, giving a shuffle feel.
The step indicator at the bottom of the transport bar shows the current playback position.
The master key and master scale in the transport bar control all melodic grids by default.
C C# D D# E
F F# G G# A
A# B
| Scale | Intervals (semitones) |
|---|---|
| Major | 0 2 4 5 7 9 11 |
| Minor | 0 2 3 5 7 8 10 |
| Dorian | 0 2 3 5 7 9 10 |
| Mixolydian | 0 2 4 5 7 9 10 |
| Pent Maj | 0 2 4 7 9 |
| Pent Min | 0 3 5 7 10 |
| Blues | 0 3 5 6 7 10 |
| Chromatic | 0 1 2 3 4 5 6 7 8 9 10 11 |
Each melodic panel has its own root and scale dropdowns in the panel header. Setting these overrides the master key/scale for that grid only — useful for polytonality or mixing scale colors.
On melodic grids, click and drag the row labels (the note names on the left edge) up or down to shift the octave range.
| Track | Default Octaves |
|---|---|
| Bass | 2–3 |
| Lead Synth | 4–5 |
| Pad / Chords | 3–4 |
| Arp / FX | 5–6 |
Click a track’s name label to rename it. The label becomes an editable text field.
Custom labels are saved with your project.
On drum grids, click a row label (e.g. KICK, SNARE) to edit that row’s name and MIDI note number inline.
Overridden labels display in the track’s color instead of gray. The override only affects display and MIDI output — saved project files still use the original row names internally, so existing saves load correctly.
Each track panel has a volume slider and a mute
button (M).
M to silence the track. The grid dims to 35% opacity when muted.Volume and mute state are saved per-track and persist across sessions.
LJam can send MIDI to external instruments and DAWs via the Web MIDI API.
Each track has a channel selector (1–16). Default channels:
| Track | Default Channel |
|---|---|
| Kick / Snare | 10 (GM Drums) |
| Percussion | 10 (GM Drums) |
| Bass | 2 |
| Lead Synth | 3 |
| Pad / Chords | 4 |
| Arp / FX | 5 |
MIDI device selections are persisted in localStorage.
Each track has a PC / patch text field in the header. This field serves two purposes: sending MIDI Program Change messages and acting as a free-text label for your own reference.
| Input | What it sends | Example use |
|---|---|---|
42 |
CC#0=0, CC#32=0, PC 42 | GM program 42 (bank reset to 0) |
b:6 p:42 |
CC#0=6, CC#32=0, PC 42 | Bank MSB 6, LSB defaults to 0 |
b:0,3 p:24 |
CC#0=0, CC#32=3, PC 24 | SC-8820: SC-88Pro map, Nylon Guitar |
Slap Bass |
Nothing (label only) | Just a reminder for yourself |
The field border highlights in the track color when the value is a valid program number or bank+program pair. Every valid patch change sends the full CC#0 (MSB) + CC#32 (LSB) + Program Change sequence, so switching from a banked patch back to a plain number always resets to bank 0,0.
GS devices like the Roland SC-8820 use CC#32 to select between sound maps:
| LSB | SC-8820 Sound Map |
|---|---|
| 0 | SC-8820 native |
| 1 | SC-55 |
| 2 | SC-88 |
| 3 | SC-88Pro |
The b:MSB,LSB p:N format lets you address these directly.
The short form b:N p:N defaults LSB to 0, which is the
native map — identical behavior to plain GM devices where LSB is
ignored.
Press ↑ / ↓ while the patch field is focused to increment or decrement a value. The cursor position determines which number is affected — place the cursor on the bank MSB, the LSB, or the program number and arrow keys will adjust that part (clamped to 0–127).
b:0 p:0 for the default bank, b:64 p:0 for
variation sets, or b:0,3 p:0 to access the SC-88Pro sound map.
See the GM / GM2 / GS Reference for the
full program list, drum map, and bank select details.
| Action | Shortcut |
|---|---|
| Play / Stop | Space |
| Undo | Ctrl+Z / ⌘+Z |
| Redo | Ctrl+Shift+Z / ⌘+Shift+Z / Ctrl+Y |
| Action | Shortcut |
|---|---|
| Stamp: Whole (16 steps) | W |
| Stamp: Half (8 steps) | H |
| Stamp: Quarter (4 steps) | Q |
| Stamp: Eighth (2 steps) | E |
| Stamp: Sixteenth (1 step) | S |
| Velocity level (1=soft … 0=full) | 0–9 |
| Shift hovered row left/right | ← / → |
| Move hovered note up/down | ↑ / ↓ |
| Shift entire pattern left/right | Shift+← / → |
| Shift all notes up/down (wraps) | Shift+↑ / ↓ |
| Randomize hovered row | R |
| Exit stamp/velocity mode / clear selection | Escape |
Press a stamp key to enter stamp mode (a colored chip appears in the header). Press the same key again or Escape to exit. On melodic grids, clicking an empty cell places a note of that duration. On drum grids, note length is always 1 step — stamp mode only affects the spacing of drum rolls when dragging. If stamp mode is active when pressing R, notes snap to that duration’s grid.
Velocity levels work the same way: press a number key (1–9, 0=10) to set the velocity for new notes. A “v5”-style chip appears in the header. Press the same key or Escape to clear. Velocity maps to MIDI 25–127 and scales the internal synth volume. Duration and velocity can be active simultaneously. Notes without a velocity level use the track volume as before.
Shortcuts are disabled when a text field, select dropdown, or editable element is focused.
Your project is automatically saved to localStorage after every change (500 ms debounce). It reloads automatically when you reopen the page.
Click SAVE in the transport bar to export your project as
a .json file. On Chrome and Edge this opens a native file
dialog; other browsers download the file directly.
Click LOAD to import a previously saved .json
file. The file format is versioned and older saves are automatically
migrated.
Both the per-track randomize button and the RANDOM ALL button use a press-and-hold mechanic:
An undo snapshot is taken when you press down, so Ctrl+Z / ⌘+Z reverts the entire fill in one step.
Per-track randomize and clear buttons affect only the current editing slot for that track.
When sending MIDI on channel 10, drum tracks use these General MIDI note assignments:
| Instrument | Note | MIDI # |
|---|---|---|
| Kick | C1 | 36 |
| Snare | D1 | 38 |
| Closed Hi-Hat | F#1 | 42 |
| Open Hi-Hat | A#1 | 46 |
| Crash Cymbal | C#3 | 49 |
| Ride Cymbal | D#3 | 51 |
| Instrument | Note | MIDI # |
|---|---|---|
| Hand Clap | D#1 | 39 |
| Side Stick / Rim | C#1 | 37 |
| Low Tom | G1 | 43 |
| High Tom | D2 | 50 |
| Conga High | D#3 | 63 |
| Conga Low | E3 | 64 |
| Cowbell | G#2 | 56 |
The SYNTH ON/OFF button in the transport bar controls whether LJam’s built-in Tone.js synthesizers produce sound.
Use this when driving external gear or a SoundFont player — you hear only the external sound without the internal synths doubling every note.
Per-track mute buttons still work independently of the synth toggle.
When MIDI is enabled and the transport is playing, LJam sends MIDI clock messages to all selected output devices:
| Message | Hex | When Sent |
|---|---|---|
| Start | 0xFA | Transport starts playing |
| Timing Clock | 0xF8 | 24 times per quarter note (continuous) |
| Stop | 0xFC | Transport stops |
External apps and hardware can use these messages as a tempo and beat reference. The clock rate adjusts automatically when you change BPM.
LJam doesn’t load SoundFont files directly, but you can use an external SoundFont player to get high-quality GM instrument sounds driven by LJam’s sequencer via MIDI.
Use the patch field on each track to send Program Change messages. The SoundFont player will switch to the corresponding GM instrument. For example:
0 — Acoustic Grand Piano32 — Acoustic Bass80 — Square Leadb:8 p:0 — Bank 8, Program 0 (bank variations)brew install fluidsynthfluidsynth -a coreaudio -m coremidi /path/to/FluidR3_GM.sf2If things get into a strange state — unexpected drum mappings, stuck settings, or corrupted project data — you can wipe all saved state and start fresh.
This clears: