Blog → Engineering

I Built a Browser-Based Music Notation Editor — Here's What I Learned

April 13, 2026 10 min read ScoreInk Engineering

A year ago I set out to build something that probably shouldn't run in a browser: a full music notation editor with multi-instrument playback, real-time staff rendering, and export to PDF, WAV, and MIDI. No plugins, no desktop install, no backend processing. Just a URL.

The result is ScoreInk — a browser-based music notation editor that now supports 26 instruments, from piano and guitar to trumpet, flute, clarinet, and harp. You click notes onto a staff, hear them played back with real instrument samples, and export your finished score in three formats.

Here's what was actually hard about building it, and what I'd do differently.

The Hard Part Nobody Warns You About: Rendering a Music Staff

Music notation looks simple. Five horizontal lines, some dots with stems. How hard can it be?

Extremely hard, it turns out. A music staff isn't a grid. Notes don't sit at fixed positions — they're spaced proportionally based on their rhythmic duration. A whole note takes more horizontal space than a quarter note. Accidentals (sharps, flats) need room to the left of the notehead without colliding with the previous note. Ledger lines appear dynamically when notes fall above or below the staff. Stems flip direction depending on the note's position relative to the middle line.

And that's before you add multiple staves for different instruments, bar lines, time signatures, key signatures, ties, triplets, dotted notes, and rests — each with its own symbol and spacing rules.

I render everything on an HTML Canvas element. The rendering pipeline works in three passes:

  1. Layout pass — calculates the horizontal position of every note, rest, and bar line based on rhythmic values and the current measure width
  2. Collision pass — adjusts positions to prevent overlapping accidentals, ties, and triplet brackets
  3. Draw pass — renders noteheads, stems, beams, flags, bar lines, clefs, and all annotations to the canvas

Each pass handles hundreds of edge cases. Two notes a second apart? Their accidentals might collide. A tie that spans a bar line? It needs to curve across the break. An eighth-note rest between two beamed eighth notes? The beam group has to split. Every one of these cases required custom logic.

Lesson learned

Don't try to build a general-purpose music layout engine from scratch. Start with the simplest possible rendering (monospaced note spacing, no beaming) and add complexity one feature at a time. I rewrote the layout engine three times before landing on something maintainable.

Web Audio API: Surprisingly Powerful, Surprisingly Tricky

The Web Audio API is the reason ScoreInk can play back 26 instruments in real time without any server involvement. Every sound plays client-side using pre-recorded instrument samples loaded into AudioBuffer nodes.

The basic architecture is straightforward: decode an audio sample into an AudioBuffer, create an AudioBufferSourceNode for each note, connect it to the destination (speakers), and schedule playback at the correct time using AudioContext.currentTime.

The tricky parts:

Export: PDF, WAV, and MIDI From Pure JavaScript

Export is where the "no backend" constraint gets really interesting.

PDF Export

PDF export re-renders the entire score onto a hidden canvas at print resolution (300 DPI vs. the screen's 96 DPI), then converts the canvas to an image and embeds it in a PDF using jsPDF. The main challenge is pagination — figuring out where to break pages so measures don't get split mid-bar. The layout engine calculates break points based on cumulative measure widths, then renders each page to a separate canvas before assembling the final PDF.

WAV Export

WAV export uses an OfflineAudioContext — a Web Audio API feature that renders audio at faster-than-real-time into a buffer. The entire score gets scheduled against the offline context, which processes all the samples and mixing in one pass. The resulting buffer gets encoded to WAV format (PCM, 44.1kHz, 16-bit) and offered as a download. A 3-minute score exports in about 2 seconds on a modern laptop.

MIDI Export

MIDI is the simplest export format conceptually — it's just a list of note-on and note-off events with timestamps. But getting the details right matters: each instrument needs the correct MIDI program number (piano = 0, acoustic guitar = 25, trumpet = 56), note velocities should reflect the dynamics in the score, and tempo changes need to be encoded as MIDI tempo events. I use a minimal MIDI writer that builds the binary file format from scratch — about 200 lines of JavaScript to handle the variable-length encoding that MIDI uses for delta times.

Key insight

The OfflineAudioContext is an underappreciated feature of the Web Audio API. It lets you render hours of audio in seconds, entirely client-side. If you're building any kind of audio export feature in the browser, this is the API you want.

Performance: Making It Feel Instant

A music notation editor has to re-render the staff on every interaction — every note placed, every note moved, every duration changed. If rendering takes more than about 16ms (one frame at 60fps), the editor feels sluggish.

The two biggest performance wins:

The editor now handles scores with 100+ measures across multiple instruments without noticeable lag on a mid-range laptop. Mobile devices are the constraint — phones with less than 4GB of RAM can struggle with large ensemble scores. But for the typical use case (1–4 instruments, 20–60 measures), performance is solid across all devices.

What I'd Do Differently

If I were starting over:


Building a music notation editor in the browser was the hardest project I've worked on. The intersection of music theory, audio engineering, real-time rendering, and file format encoding makes it a uniquely multi-disciplinary challenge. But the result — a tool that lets anyone with a browser write, hear, and export sheet music — is worth the complexity.

If you want to try the finished product: open ScoreInk in your browser. Free 3-day trial, no credit card, no install. Twenty-six instruments, real-time playback, PDF/WAV/MIDI export.

Try ScoreInk Yourself

Write music in your browser. 26 instruments, real-time playback, export to PDF/MIDI/WAV.

Start Free Trial →

No credit card · $20/year or $35 lifetime