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

riffscore

v1.0.0-alpha.9

Published

An intuitive, embeddable sheet music editor for React

Downloads

25

Readme

RiffScore

npm version license

RiffScore is a self-hostable, embeddable sheet music editor for React.

Unlike commercial platforms that require users to leave your site or pay subscription fees, RiffScore allows you to embed interactive, editable scores directly into your application.

RiffScore Editor

Installation

npm install riffscore

Quick Start

import { RiffScore } from 'riffscore';

function App() {
  return <RiffScore id="my-editor" />;
}

That's it! RiffScore renders a fully interactive grand staff editor with sensible defaults.

Note: Styles and fonts are bundled automatically — no separate CSS import or font setup required.

With Configuration

<RiffScore id="my-editor" config={{
  score: { 
    staff: 'treble',      // 'grand' | 'treble' | 'bass' | 'alto' | 'tenor'
    measureCount: 4,
    keySignature: 'G'
  }
}} />

See Configuration for all options.

Read-Only Mode

<RiffScore config={{
  ui: { showToolbar: false },
  interaction: { isEnabled: false }
}} />

See Interaction Configuration for more display modes.

Programmatic Control

const api = window.riffScore.get('my-editor');

api.select(1)                      // Select measure 1
   .addNote('C4', 'quarter')       // Add a quarter note
   .addNote('E4')                  // Add with current duration
   .play();                        // Play from selection

See the Cookbook for more recipes.


Features

Core Editing

  • Self-Hostable: No external dependencies or platform lock-in.
  • Embeddable: Drop it into any React application.
  • Configurable: Full control over UI, interactions, and score content.
  • SMuFL Compliance: Beautiful engraving using the Bravura font.
  • Export Options: JSON, MusicXML, and ABC notation export.
  • Theming: Built-in dark, light, cool, and warm themes.

Chord Symbols

  • Click-to-Edit: Click above any beat to add or edit chord symbols.
  • Flexible Input: Letter names (Cmaj7), solfège (Do), Roman numerals (IV7).
  • Multiple Notations: Display in letter, Roman numeral, Nashville number, or solfège.
  • Playback: Chord voicings play back alongside the score.
  • Full API: CRUD, selection, and navigation via addChord(), selectChord(), etc.

Machine-Addressable API

  • Imperative Control: Programmatically control the score via window.riffScore (API Reference)
  • Fluent Chaining: api.select(1).addNote('C4').play() — chainable methods for concise scripting.
  • Event Subscriptions: React to state changes with api.on('score', callback) and api.on('batch', callback).
  • Transaction Batching: Atomic operations with beginTransaction/commitTransaction for single undo steps.
  • Structured Feedback: Unified result objects and sticky error states for robust scripting.
  • Playback API: play(), pause(), stop(), rewind(), setInstrument() for programmatic audio control.

Engines

  • Music Theory: Powered by Tonal.js for scales, chords, and transposition.
  • Audio Playback: Tone.js sampler with multiple instrument support.
  • MIDI Input: Connect a MIDI keyboard for note entry (experimental).

Keyboard Shortcuts

| Mac | Windows | Action | |-----|---------|--------| | Entry & Editing ||| | 1-7 | 1-7 | Set duration (64th to whole) | | . | . | Toggle dotted | | R | R | Toggle note/rest mode | | T | T | Toggle tie | | Enter | Enter | Insert note/rest at cursor | | / | / | Transpose selection | | Navigation & Selection ||| | / | / | Previous / Next event | | Shift+←/→ | Shift+←/→ | Extend selection horizontally | | Cmd+↑/↓ | Ctrl+↑/↓ | Navigate within chord | | Cmd+Shift+↑/↓ | Ctrl+Shift+↑/↓ | Extend selection vertically | | Cmd+A | Ctrl+A | Select all (progressive) | | Esc | Esc | Clear selection / Cancel | | Playback ||| | Space | Space | Play / Pause | | History ||| | Cmd+Z | Ctrl+Z | Undo | | Cmd+Shift+Z | Ctrl+Y | Redo |

See the Interaction Guide for the complete keyboard reference.


Documentation

📚 View Full Documentation Index
Browse all guides, architectural records, and migration history.

Getting Started

| Guide | Description | |-------|-------------| | 📖 Configuration | All config options for <RiffScore /> | | 🎹 API Reference | Imperative API for script control | | 📗 Cookbook | Task-oriented recipes and examples |

Deep Dives

| Guide | Description | |-------|-------------| | 🎨 Interaction Design | UX philosophy and editor states | | ⌨️ Keyboard Navigation | Navigation state machine details | | 🎯 Selection Model | Multi-selection and vertical extension |

Architecture

| Guide | Description | |-------|-------------| | 📘 Architecture | Technical overview and design principles | | 🧩 Coding Patterns | Common patterns and architectural standards | | 🧱 Data Model | Score schema and quant system | | 🔧 Commands | Command pattern reference | | 🎼 Layout Engine | Engraving and positioning | | 📜 ADRs | Architecture Decision Records |

Contributing

| Guide | Description | |-------|-------------| | 🤝 Contributing | Dev setup and guidelines | | 🧪 Testing | Test patterns and fixtures | | 📋 Changelog | Release history |


Imperative API

Control the editor programmatically from external scripts:

const api = window.riffScore.get('my-editor');

// Build a chord
api.select(1)              // Measure 1
   .addNote('C4', 'quarter')
   .addNote('E4')
   .addNote('G4')
   .addTone('C5');          // Stack into chord

// Batch operations (single undo step)
api.beginTransaction();
for (let i = 0; i < 16; i++) {
  api.addNote(`C${(i % 3) + 4}`, 'sixteenth');
}
api.commitTransaction('Scale run');

// Subscribe to changes
api.on('batch', (e) => console.log(`Committed: ${e.label}`));

See the API Reference and Cookbook for all available methods.


Repository Structure

riffscore/
├── src/        ← Library source
├── demo/       ← Next.js demo app
├── docs/       ← Documentation
├── dist/       ← Built library (ESM/CJS/DTS)
└── tsup.config.ts

Development

# Install dependencies
npm install
cd demo && npm install

# Build library
npm run build

# Run demo
npm run demo:dev

Coming Soon

  • Import: ABC and MusicXML import
  • Clipboard API: Copy, cut, and paste operations
  • Move Operations: Drag-and-drop and keyboard-based event moving