npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

scribbletune

v5.5.4

Published

Create music with JavaScript and Node.js!

Readme


Install

npm install scribbletune

Quick start

Option 1: CLI

If you installed Scribbletune globally via npm i -g scribbletune then you can directly use scribbletune as the command. If you installed it locally via npm i scribbletune then please use npx scribbletune as the command.

Run modes:

# Global install
npm install -g scribbletune
scribbletune --help

# Local/project install
npm install scribbletune
npx scribbletune --help

Quick command examples:

Command format

scribbletune --riff <root> <mode> <pattern> <subdiv> [options]
scribbletune --chord <root> <mode> <pattern> <subdiv> <progression|random> [options]
scribbletune --arp <root> <mode> <pattern> <subdiv> <progression|random> [options]

Progression input rules for --chord and --arp:

1645            # degree digits
"I IV vi V"     # roman numerals (space separated)
I,IV,vi,V       # roman numerals (comma separated)
random          # generated progression
CM-FM-Am-GM     # explicit chord names (`root` and `mode` are ignored)

Common options:

--outfile <file.mid>  # default: music.mid
--subdiv <4n|8n|1m...>
--sizzle [sin|cos|rampUp|rampDown] [reps]
--sizzle-reps <number>
--amp <0-127>
--accent <x--x...>
--accent-low <0-127>
--style <letters>     # riff motif/style, e.g. AABC
--fit-pattern         # explicit enable (already enabled by default)
--no-fit-pattern      # disable automatic pattern fitting
--bpm <number>        # your DAW may or may not support it

Note: if your pattern uses [ and ] (for subdivisions), quote it in shell:

scribbletune --arp C3 major 1 'x-x[xx]-x-[xx]' 16n

Pattern helpers:

x.repeat(4)       # -> xxxx
'x-x[xx]'.repeat(2)
2(x-x[xx])        # prefix repeat shorthand
(x-x[xx])2        # suffix repeat shorthand

--riff examples

# Basic riff from scale
scribbletune --riff C3 phrygian x-xRx_RR --outfile riff.mid

# With motif/style and positional subdiv
scribbletune --riff C3 phrygian x-xRx_RR 8n --style AABC --sizzle sin 2 --outfile riff-aabc.mid

# Set riff subdivision via positional arg
scribbletune --riff C3 phrygian x-xRx_RR 8n --style AABC --outfile riff-8n.mid

# Pattern with subdivisions (quote [] in shell)
scribbletune --riff C3 phrygian 'x-x[xx]-x-[xx]' 8n --style AABC --outfile riff-subdiv.mid

Riff + motif note:

  • --style creates riff sections by repeating the full pattern per letter.
  • Example: --style AABC with pattern x-x[xx] creates 4 sections: A, A, B, C.
  • Repeated letters reuse the exact same generated section (same rhythm and same notes, including random R choices).

--chord examples

# Degree digits (resolved against root/mode)
scribbletune --chord C3 major xxxx 1m 1645 --sizzle cos 1 --outfile chords-1645.mid

# Roman numerals (space/comma separated)
scribbletune --chord C3 major xxxx 1m "I IV vi V" --outfile chords-roman.mid

# Random progression
scribbletune --chord C3 major xxxx 1m random --outfile chords-random.mid

# Explicit chord names (root/mode currently ignored for this style)
scribbletune --chord C3 major xxxx 1m CM-FM-Am-GM --outfile chords-explicit.mid

# Subdivisions in pattern
scribbletune --chord C3 major 'x-x[xx]-x-[xx]' 8n I,IV,vi,V --outfile chords-subdiv.mid

--arp examples

# Arp from degree progression
scribbletune --arp C3 major xxxx 1m 1736 --sizzle cos 4 --outfile arp-1736.mid

# Single degree "1" means tonic chord in the chosen key/mode
scribbletune --arp C3 major xxxx 4n 1 --outfile arp-degree-1.mid

# Arp from explicit chords
scribbletune --arp C3 major xxxx 1m CM-FM-Am-GM --count 4 --order 1234 --outfile arp-explicit.mid

# Custom note order inside each arpeggiated chord (one-based)
scribbletune --arp C3 major xxxx 4n 1 --order 2143 --outfile arp-order-2143.mid

# Same custom order using local dist build
node dist/cli.cjs --arp C3 major xxxx 4n 1 --order 2143 --outfile arp-order-local.mid

# Auto-fit is default (single x expands to full generated arp length)
scribbletune --arp C3 major x 4n 1736 --outfile arp-fit-default.mid

# Disable auto-fit if you want a short clip
scribbletune --arp C3 major x 4n 1736 --no-fit-pattern --outfile arp-no-fit.mid

--order behavior:

  • One-based order is supported (1234, 2143) and is recommended.
  • Zero-based order is also accepted for backward compatibility (0123, 1032).

Run scribbletune --help to see the latest CLI usage text.

Option 2: Node.js

import { scale, clip, midi } from 'scribbletune';

const notes = scale('C4 major');
const c = clip({ notes, pattern: 'x'.repeat(8) });

midi(c, 'c-major.mid');

Run it with node and open the .mid file in Ableton Live, GarageBand, Logic, or any DAW.

Option 3: Browser (with Tone.js)

Scribbletune's browser entry point adds Session, Channel, and live clip() support on top of Tone.js.

import { Session } from 'scribbletune/browser';

const session = new Session();
const channel = session.createChannel({
  instrument: 'PolySynth',
  clips: [
    { pattern: 'x-x-', notes: 'C4 E4 G4' },
    { pattern: '[-xx]', notes: 'C4 D#4' },
  ],
});

await Tone.start();
Tone.Transport.start();
channel.startClip(0);

Standalone sample clip (no Session/Channel needed)

import { clip } from 'scribbletune/browser';

await Tone.start();
Tone.Transport.start();

const kick = clip({
  sample: 'https://scribbletune.com/sounds/kick.wav',
  pattern: 'x-x-',
});
kick.start();

Core concepts

Pattern language

Scribbletune uses a simple string notation to describe rhythms:

| Char | Meaning | |------|---------| | x | Note on | | - | Note off (rest) | | _ | Sustain previous note | | R | Random note (from randomNotes pool) | | [] | Subdivide (e.g. [xx] = two notes in one beat) |

'x---x---x-x-x---'   // basic kick pattern
'[xx][xx]x-x-'        // hihat with subdivisions
'x___'                 // one long sustained note

Scales and chords

Powered by harmonics:

import { scale, chord, scales, chords } from 'scribbletune';

scale('C4 major');       // ['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4']
chord('CM');             // ['C4', 'E4', 'G4']
scales();                // list all available scale names
chords();                // list all available chord names

Arpeggios

import { arp } from 'scribbletune';

arp({ chords: 'CM FM', count: 4, order: '0123' });
// ['C4', 'E4', 'G4', 'C5', 'F4', 'A4', 'C5', 'F5']

Chord progressions

import { progression, getChordsByProgression } from 'scribbletune';

progression('M', 4);  // e.g. ['I', 'ii', 'V', 'IV']

getChordsByProgression('C4 major', 'I IV V IV');
// 'CM_4 FM_4 GM_4 FM_4'

Browser API

The browser entry point (scribbletune/browser) provides everything above plus:

Session and Channel

import { Session } from 'scribbletune/browser';

const session = new Session();
const drums = session.createChannel({
  sample: 'https://scribbletune.com/sounds/kick.wav',
  clips: [
    { pattern: 'x---x---' },
    { pattern: 'x-x-x-x-' },
  ],
});

const synth = session.createChannel({
  instrument: 'PolySynth',
  clips: [
    { pattern: 'x-x-', notes: 'C4 E4 G4' },
  ],
});

await Tone.start();
Tone.Transport.start();

// Start clips independently
drums.startClip(0);
synth.startClip(0);

// Switch patterns on the fly
drums.startClip(1);

// Or start a row across all channels
session.startRow(0);

Channel options

Channels accept various sound sources:

// Built-in Tone.js synth (by name)
{ instrument: 'PolySynth' }

// Pre-built Tone.js instrument
{ instrument: new Tone.FMSynth() }

// Audio sample URL
{ sample: 'https://example.com/kick.wav' }

// Multi-sample instrument
{ samples: { C3: 'piano-c3.wav', D3: 'piano-d3.wav' } }

// With effects
{ instrument: 'PolySynth', effects: ['Chorus', 'Reverb'] }

API reference

| Export | Description | |--------|-------------| | clip(params) | Create a clip — returns note objects (Node.js) or a Tone.Sequence (browser) | | midi(clip, filename?) | Export a clip to a MIDI file | | scale(name) | Get notes of a scale, e.g. 'C4 minor' | | chord(name) | Get notes of a chord, e.g. 'CM' | | scales() | List all available scale names | | chords() | List all available chord names | | arp(params) | Generate arpeggiated note sequences | | progression(type, count) | Generate a chord progression ('M' or 'm') | | getChordsByProgression(scale, degrees) | Convert Roman numeral degrees to chord names | | getChordDegrees(mode) | Get Roman numeral degrees for a mode | | Session | (browser only) Manage multiple channels and coordinate playback |

Development

npm install       # install dependencies
npm test          # run tests
npm run build     # build with tsup
npm run lint      # check with biome
npm run dev       # build in watch mode

If developing new features for the CLI, use the following command after running npm run build to test before publishing,

node dist/cli.cjs --help

License

MIT


scribbletune.com | Soundcloud