Install the package.
npm install @stringsync/vexmlImport the render function.
import { render } from '@stringsync/vexml';Render MusicXML.
const res = await fetch('song.musicxml'); // or .mxl
const musicXML = await res.text(); // or .blob() for mxl
await render(musicXML, element);const score = await render(musicXML, element);
let previous = null;
score.addEventListener('pointermove', (e) => {
const current = e.target?.type === 'note'
? e.target
: null;
if (current !== previous) {
previous?.halo.off();
current?.halo.on('rgba(41, 98, 255, 0.35)');
previous = current;
}
});Note
Font family and url are interpolated into a <style> rule and CSS variables. Don't pass raw untrusted user input.
await render(musicXML, element, {
fonts: {
// noteheads, clefs, rests, accidentals, etc., default is Bravura
notation: { family: 'Petaluma' },
// part/instrument names, lyrics, titles, directions (default is Source Sans 3);
// optionally specify a font url if it's not already available locally
text: { family: 'Inter', url: '/fonts/inter.woff2' },
},
});A layer is a <canvas> that you can draw arbitrary content on without affecting the sheet music. vexml controls its size and position.
const score = await render(musicXML, element);
const background = score.addLayer('content', -1); // draws behind the score
// ctx is a standard CanvasRenderingContext2D
background.ctx.fillStyle = 'rgba(0, 0, 255, 0.3)';
background.ctx.fillRect(50, 50, 100, 80);
const foreground = score.addLayer('content', 1); // draws in front of the score
foreground.ctx.fillStyle = 'rgba(255, 0, 0, 0.3)';
foreground.ctx.fillRect(50, 50, 100, 80);Pass an optional zIndex to order a layer relative to the canvas the score is drawn on, which sits at zIndex 0. A positive value draws in front; a negative value draws behind, showing through the score's transparent pixels. Layers with the same zIndex stack in the order they were created.
When you're done with a layer or the entire rendered score, call .dispose() to clean up resources.
layer.dispose();
score.dispose();Dependencies:
Add the repo's bin/ to your PATH so the vex command works anywhere:
profile=~/.${SHELL##*/}rc # ~/.zshrc, ~/.bashrc, etc.
echo "export PATH=\"$PWD/bin:\$PATH\"" >> "$profile"
source "$profile"Then:
vex dev # run the playground site
vex render -i song.musicxml # render a MusicXML file to a pngDon't want it on your PATH? Run it directly with ./bin/vex <command>.