A JavaScript library for rendering music notation and guitar tablature.

Related tags


VexFlow 3

A JavaScript library for rendering music notation. Copyright (c) 2010 Mohit Muthanna Cheppudira

Sponsor this Project

If you use VexFlow in your app, startup, institution, and find it useful, please consider sponsoring its development here: https://github.com/sponsors/0xfe.

Need Help? Ask on the Vexflow Google Group.

What is VexFlow?

VexFlow is an open-source web-based music notation rendering API. It is written completely in JavaScript, and runs right in the browser. VexFlow supports HTML5 Canvas and SVG, and runs on all modern browsers.

Go try out The VexFlow Tutorial to learn how to use VexFlow. Also learn to use the simpler EasyScore API in the Using EasyScore guide.

Quick Start

Using NPM

$ npm install vexflow

Using the HTML script Tag

The releases are served via unpkg.com.

Using EasyScore

The EasyScore API is a quick way to create simple music notation in VexFlow. See running example in this jsfiddle.

import Vex from 'vexflow';

const vf = new Vex.Flow.Factory({
  renderer: {elementId: 'boo', width: 500, height: 200}

const score = vf.EasyScore();
const system = vf.System();

  voices: [
    score.voice(score.notes('C#5/q, B4, A4, G#4', {stem: 'up'})),
    score.voice(score.notes('C#4/h, C#4', {stem: 'down'}))


Learn more about EasyScore at: Using EasyScore.

Using the Native API

The example code below renders a VexFlow stave using SVG. See running example in this jsfiddle.

import Vex from 'vexflow';

const VF = Vex.Flow;

// Create an SVG renderer and attach it to the DIV element named "vf".
const div = document.getElementById("vf")
const renderer = new VF.Renderer(div, VF.Renderer.Backends.SVG);

// Configure the rendering context.
renderer.resize(500, 500);
const context = renderer.getContext();
context.setFont("Arial", 10, "").setBackgroundFillStyle("#eed");

// Create a stave of width 400 at position 10, 40 on the canvas.
const stave = new VF.Stave(10, 40, 400);

// Add a clef and time signature.

// Connect it to the rendering context and draw!


To learn and contribute, check out the VexFlow Wiki.

To build VexFlow from scratch, read the Build Instructions.

Sponsor Vexflow: https://github.com/sponsors/0xfe

MIT License

Copyright (c) Mohit Muthanna Cheppudira 2010
0xFE [email protected] http://www.vexflow.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.



  • Add support for all quarter tone accidentals

    Add support for all quarter tone accidentals

    Please consider adding support for quarter tone accidentals.

    These include the Western notation for half-sharp, half-flat, sharp-and-a-half and flat-and-a-half, all of which are explained on https://en.wikipedia.org/wiki/Accidental_%28music%29#Microtonal_notation (and a picture us also available).

    These also include the Iranian notation for half-sharp and half-flat, which are depicted in Persian Wikipedia's pages on sori and koron, respectively.

    Ideally, a different identifier should be used for the western and eastern half-notes, so they can coexist in the same sheet if need be. An example of when this is needed is when sheet music is being written for many instruments (as is used by conductors) some of which are oriental instruments and some western instruments but all can play quarter tones.

    -- UPDATE --

    As shown below, vexflow already supports the Western quarter tone accidentals. There is need for support of Iranian accidentals though.

    feature request 
    opened by Huji 93
  • Use with React / React-native?

    Use with React / React-native?

    Hi there,

    Is it possible to use vexflow with react (react-native) at all? I've used this library before for a phonegap based app but switching to react and would love to keep using this one!

    Cheers david

    question discussion 
    opened by davidfloegel 69
  • Migrate vexflow sources to Typescript

    Migrate vexflow sources to Typescript

    I migrated all the sources to Typescript. Only tests have to be migrated someday as well. I did not migrate the tests, because it would had made the PR even bigger and more complicated to review.

    Tests are all green, but since a huge amount of files were affected would be nice if you could review and find mistakes.

    This is a contribution to the https://github.com/0xfe/vexflow/issues/780 issue.

    • [x] Seamless for existing users. This migration utilises Vex.Flow namespace in index.ts - so it is should be backwards compatible.
    • [x] Use eslint also for ts files
    • [x] Check that there are no existing use cases or workflows that will break by moving to TS.
    • [ ] Review the TS codebase.
    • [x] Check that you can import the typescript classes in javascript without using the minified build.
    opened by wassertim 67
  • JoinVoices / Formatter not aligning voices correctly on 3.0.9

    JoinVoices / Formatter not aligning voices correctly on 3.0.9

    Using native code in 1.2.93 I get a correct alignment between the voices image

    However in 3.0.9 I get it worng image

    The code is available in https://jsfiddle.net/zg95n0du/

    opened by rvilarl 43
  • Vexflow Typescript File by File Migration

    Vexflow Typescript File by File Migration

    After @wassertim and @rvilarl had a discussion we propose to migrate to typescript file by file, providing support for js and ts simultaneously.

    First PR will contain infrastructure for ts and eslint.

    And then we will create many PRs with ts files substituting js files.


    opened by wassertim 43
  • `preCalculateMinTotalWidth` is returning a value that is too low on some cases.

    `preCalculateMinTotalWidth` is returning a value that is too low on some cases.

    Yes, preCalculateMinTotalWidth is still wrong, that should be separate issue...

    Originally posted by @0xfe in https://github.com/0xfe/vexflow/issues/839#issuecomment-792349714

    opened by rvilarl 42
  • Migration/tuning fraction test

    Migration/tuning fraction test

    Tests for Tuning and Fraction migrated

    opened by rvilarl 39
  • support component and browserify with minor refactor

    support component and browserify with minor refactor

    And there are also some other cool features besides:

    • managing all dependencie via a manifest (component.json) with semver
      • jquery
      • qunit
      • raphael
    • no more embedding several files into any HTML page
    • vexflow can be installed and be used as a module with component and npm/browserify
    opened by timaschew 39
  • Added Tuplets

    Added Tuplets

    Sorry it's taken me so long to get this in. It's still more of a preliminary pull request; I'm sending it more to get feedback than in expectation of it getting merged right away.

    What this commit allows you to do:

    • Render tuplets, either with beamed or unbeamed notes
    • Set the number of beats that the tuplet is meant to occupy
    • Optionally display the tuplet as a ratio, e.g. as "3:2" as opposed to just "3" for a standard triplet in 4/4.
    • Optionally display the tuplet notation on the top or bottom of the staff

    Anyways, a few remaining issues:

    I believe that the text for the tuplet is technically meant to be in italics. Unfortunately, I don't think there is an italics Gonville font, so the options are either to forget about the italics or use a font that doesn't match the numbers in the time signature. If anyone has any better ideas, or if I'm wrong, let me know!

    I had to make a couple design decisions here that I'm still not 100% convinced of. The main one has to do with the coupling of beams and tuplets. The way I have it implemented now, the tuplet sort of "owns" the beam. That is, if you create a tuplet, on of the options you can specify is whether or not it is beamed. If it is, then a beam is automatically rendered when the tuplet is rendered. If the beam and the tuplet were separated, then the tuplet class would need to figure out whether or not its constituent notes were beamed in order to now whether or not to render the bracket, but this might be better overall. If anyone has any opinions feel free to offer them.

    Again, this is just for rendering tuplets. They still need to be incorporated with vextab/tabdiv, which will require some extra work and design decisions, such as how one will go about denoting a tuplet in a tabdiv.


    opened by tschmidt23 35
  • Add support for cross stave beams.

    Add support for cross stave beams.

    This would require small changes to the beam and stem drawing code.

    Also, ghost notes will have to be added to partner staves for synchronization.

    feature request 
    opened by 0xfe 33
  • FormatOptions vs FormatterOptions

    FormatOptions vs FormatterOptions


    While cleaning up the Partials, I ran across formatter.ts which has two exported interfaces: FormatOptions and FormatterOptions. It confused me at first sight, and probably would confuse a new VexFlow user as well.

    This is a reminder to myself to discuss w/ Rodrigo and Mohit to see if there's a better name for one of the interfaces. Neither type existed 6 months ago, so it's not a huge risk to rename.

    If we ultimately decide there's no better name for either interface, I'll close this issue.

    opened by ronyeh 1
  • Fix Tests, Remove Partial<...>, Prefer Optional Fields ?

    Fix Tests, Remove Partial<...>, Prefer Optional Fields ?

    This builds directly on top of Rodrigo's https://github.com/0xfe/vexflow/pull/1141

    It includes Rodrigo's 5 commits, so I believe if we merge this one, we can close https://github.com/0xfe/vexflow/pull/1141

    This is part 1 of migrating away from using Partial<...>. The main goal is to prevent Partial types from leaking out into the public API.

    Part 2 will come in a second PR, which will remove the rest of the Partial, and include a couple Required<...>. Part 2 also comes with improvements to how we handle fonts (for text on the score, not for the music engraving).

    There are 2 visual diffs. Both are due to bug fixes.


    BEFORE: Stave Vertical_Bar_Test Bravura_Reference

    AFTER: Stave Vertical_Bar_Test Bravura_Current

    DIFF: Stave Vertical_Bar_Test Bravura

    The test now correctly shows a double vertical bar. This is due to Rodrigo's bug fix. Not sure why we have two methods that were almost identical.... (now they're actually identical!). We can address that in a future PR:

      stave.drawVerticalBar(50, true);
      stave.drawVerticalBar(150, false);
      stave.drawVertical(250, true);


    DIFF: Stave Volta___Modifier_Measure_Test Bravura

    The test now correctly shows the volta number. It was a minor bug fix. The test previously passed in a constant that didn't exist. Thanks to TypeScript, we now realized it doesn't exist, and changed it to the correct constant.

    Ready for review!

    opened by ronyeh 5
  • Semibreve misspelled :-)

    Semibreve misspelled :-)

    "semibrave" shows up 23 times in VexFlow.

    All but one are private names that we can change.

    However, MultimeasureRestRenderOptions contains a field semibrave_rest_glyph_scale that is part of the public API, and has been since version 1.2.88:

    https://www.unpkg.com/browse/[email protected]/src/multimeasurerest.js

    Can we rename it to semibreve_rest_glyph_scale? :-) It would be a breaking change.

    opened by ronyeh 0
  • Clean up Options object interfaces, add documentation.

    Clean up Options object interfaces, add documentation.

    While working on removing Partial, I encountered some fields in export interface StaveOptions { ... } that are not used.

    position_end?: number;
    invert?: boolean;

    These are actually part of CurveOptions. I have removed them from my PR after verifying they are not used anywhere.

    All of these interface declarations were created while we migrated VexFlow to TypeScript 5-6 months ago. There are probably more cases where the interfaces can be tightened up / documented.

    This is just a TODO issue, to remind us to review all the interfaces, document them, remove anything that doesn't belong, etc.

    opened by ronyeh 0
  • Don't stroke rectangles drawn with fillRect

    Don't stroke rectangles drawn with fillRect

    This PR fixes a bug in SVGContext.fillRect.

    Prior to this fix the SVGContext was incorrectly applying the current stroke style to the rectangle; the rectangle should be drawn without a stroke to match the behaviour of the CanvasContext. The most noticeable effect of this bug was that the barlines & stave connectors were drawn incorrectly.

    All visual diffs caused by this change are, rather surprisingly, under the threshold.

    SVG before this PR: svg old

    SVG after this PR: svg new

    Canvas: canvas

    opened by tommadams 9
  • Merge `Tickable` and `Note`?

    Merge `Tickable` and `Note`?

    In the current situation:

    • Note is the only one class extending Tickable
    • Most of the pending ts-nocheck after merging #1141 are related to this topic.

    @0xfe @ronyeh Should we merge both classes in one?

    opened by rvilarl 8
  • Petaluma Font: Remove NOGLYPH glyphs

    Petaluma Font: Remove NOGLYPH glyphs

    238 of the glyphs in petaluma_glyphs.ts have an outline that renders a [NOGLYPH] image.

    Search for

    m 1181 1440 l 268 1440 l 268 -1440 l 1181 -1440 z m 959 -524 l 959 -850 l 481 -850 l 481 -524 z m 864 -619 l 576 -619 l 576 -755 l 864 -755 z m 959 -26 l 959 -351 l 481 -351 l 481 -26 l 576 -26 l 576 -256 l 864 -256 l 864 -121 l 769 -121 l 769 -187 l 671 -187 l 671 -26 z m 959 325 l 959 37 l 481 37 l 481 135 l 864 135 l 864 325 z m 959 498 l 959 403 l 769 403 l 769 202 l 481 202 l 481 297 l 671 297 l 671 403 l 481 403 l 481 498 z m 671 778 l 576 778 l 576 674 l 671 674 z m 769 876 l 769 674 l 959 674 l 959 576 l 481 576 l 481 876 z m 959 1247 l 959 1152 l 769 1152 l 769 1045 l 959 1045 l 959 950 l 481 950 l 481 1045 l 671 1045 l 671 1152 l 484 1152 l 484 1247 z m 959 -916 l 959 -1011 l 867 -1011 l 665 -1146 l 959 -1146 l 959 -1241 l 481 -1241 l 481 -1146 l 683 -1011 l 481 -1011 l 481 -916 z

    We should remove these glyphs, and then update the FONT_STACKS in vexflow_test_helpers to use Bravura as a fallback font for Petaluma. That way, when a glyph is missing in Petaluma, it just pulls the glyph from Bravura (which should include most of the glyphs we care about).

    opened by ronyeh 2
  • Improvements to Glyph Rendering in SVGContext / CanvasContext

    Improvements to Glyph Rendering in SVGContext / CanvasContext

    This thread has evolved into discussing ways to improve Glyph rendering. I'll keep this issue open for now, even though there is no bug to fix. If we prefer to move it to the GitHub discussions tab, I can close off this issue.

    Original title:

    Should OutlineCode enum (in glyph.ts) use ints other than 0, 1, 2, 3?

    This isn't a bug, but I was reading glyph.ts and saw that GlyphOutline.parse() returns a number[] where the position of the number changes its meaning.

    For example, Bach Demo produces an array like: [0,0,60,3,140,180,0,135,62,180,3,425,60,268,180,425,62,3,285,180,425,134,367,180,3,0,60,127,180,0,63]

    The first 0 is actually a "move to" instruction, and the second 0 is an x coordinate with value 0, and then comes a y coordinate with value 60. The 3 after that starts a bezier curve....

    Then, Glyph.renderOutline() and Glyph.getOutlineBoundingBox() loop over these outline arrays to draw the glyphs to the context.

        while (!go.done()) {
          switch (go.next()) {
            case OutlineCode.MOVE: // => 0
              ctx.moveTo(go.nextX(), go.nextY());
            case OutlineCode.LINE: // => 1
              ctx.lineTo(go.nextX(), go.nextY());

    So the switch statement is looking for numbers 0, 1, 2, 3.

    Anyways, like I said, this isn't a bug because the three methods all follow the same convention (a number 0 implies an x, y and a number 3 is followed by 6 ints specifying the points of a cubic bezier curve).

    I know it was part of @tommadams massive improvements on glyph performance & correctness in https://github.com/0xfe/vexflow/pull/1103 and https://github.com/0xfe/vexflow/pull/1077.

    Obviously we don't want to go back to the old / slow way.

    But do we have any ideas on if / how we could improve this, or make it potentially less brittle / future proof?

    I can't think of anything off the top of my head at the moment, other than starting the enum at a really big number (that is still well under Number.MAX_SAFE_INTEGER), like:

    export const enum OutlineCode {
      MOVE = 0xfffffffffff0,
      LINE = 0xfffffffffff1,
      QUADRATIC = 0xfffffffffff2,
      BEZIER = 0xfffffffffff3,

    Anyways, can we improve this in any way? If not, I'll close as "not a bug."

    opened by ronyeh 17
  • SVGContext's scale(x, y) works differently from CanvasContext's scale(x,y)

    SVGContext's scale(x, y) works differently from CanvasContext's scale(x,y)

    While migrating tests, I encountered a weird bit of code in NoteHeadTests:


    The setupContext() scales the context to 0.9, 0.9. The basic() test case applies another scale of 2.0, 2.0. (It also ignores the stave created by setupContext and creates its own stave, but that's another story.)

    The scaling transformation should be multiplied against the existing scale: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/scale

    So 0.9 * 2.0 => 1.8 final scale.

    flow.html shows that the Canvas renderer works as expected, but the SVG renderer sets the final scale to 2.0, 2.0.

    The fix might be straightforward. In SVGContext's scale method, we have: this.state.scale = { x, y };

    We probably just need to multiply it into the existing scale.

    This bug has existed for a while, as it repros on vexflow.com: https://www.vexflow.com/tests/?module=NoteHead

    You can verify the bug by doing something like this:

      ctx.scale(2.0, 2.0);
      ctx.scale(0.5, 0.5);
      ctx.scale(2.0, 2.0);
      ctx.scale(0.5, 0.5);

    The final output will look like:

    S 2021-09-01 at 10 25 22
    opened by ronyeh 1
  • Tuning constructor defaults to 8 strings?

    Tuning constructor defaults to 8 strings?


    The default tuningString is E/5,B/4,G/4,D/4,A/3,E/3,B/2,E/2 which looks like the shape of a standard tuning of a 6-string guitar but with two extra bass strings at B/2 and E/2. Is this a bug? The comment suggests it should default to standard tuning.

    Additionally, the guitar tunings seem to be one octave higher than I expect.


    Shouldn't standard tuning go from E/2 to E/4?

    C/4 is on string 2, fret 1 of a 6-string guitar with standard tuning.

    I'm in the middle of cleaning up the migration/tests PR and I found what I thought was an incorrect test case comment:


    When I change the 9 to a 7 to match the comment, the test case fails.... since the standard tuning in VexFlow actually has 8 strings!

    Additionally, the .getValueForString() method doesn't do what I initially expected:


    The values are set by:


    It looks like C/5 is mapped to value 60, so my assumption is that this is using the MIDI convention of # 60 == Middle C.

    It is also assuming that C/5 == Middle C, so that would make the octave numbers of the "standard tuning" make more sense.

    However, in other parts of VexFlow, C/4 is middle C, which corresponds with scientific pitch notation.

    In summary, Tuning probably has a small bug in the constructor, and it either needs extra comments to explain that middle C == C/5 == note value 60, or it needs to somehow be reworked such that middle C is C/4, like in StaveNote.

    opened by ronyeh 0
Mohit Cheppudira
i am jack's wasted life
Mohit Cheppudira
A Music programming language. Translates source code into MIDI. Includes a player. Supports MIDI-Karaoke. Includes a MIDI analyzer.

Get Started | Features | Screenshots | Programming | CLI | Contribute | License Midica is an interpreter for a Music Programming Language. It translat

Jan Trukenmüller 47 Sep 17, 2021
A JavaScript library for rendering music notation and guitar tablature.

VexFlow 3 A JavaScript library for rendering music notation. Copyright (c) 2010 Mohit Muthanna Cheppudira Sponsor this Project If you use VexFlow in y

Mohit Cheppudira 3.1k Sep 14, 2021
OpenSheetMusicDisplay renders sheet music in MusicXML format in your web browser based on VexFlow. OSMD is brought to you by PhonicScore.com.

OpenSheetMusicDisplay (OSMD) A MusicXML renderer for the Browser opensheetmusicdisplay.org About OSMD • Demo • Key Features • Limitations • How to Use

Open Sheet Music Display 800 Sep 15, 2021
Music typeset with the Lilypond system

Intro (from long ago) This repo contains sheet music typeset with the Lilypond typesetter. The music chosen is in favour of cello music (mostly chambe

Enthusiastic about  the Cello 95 Sep 15, 2021
A beautiful cross platform Desktop Player for Google Play Music

Google Play Music™ Desktop Player Windows: MacOS / Linux: Run "Google Play Music" as a standalone desktop app. Never again will you have to hunt throu

Samuel Attard 8.5k Sep 12, 2021
🎵 Music notation engraving library for MEI with MusicXML and Humdrum support and various toolkits (JavaScript, Python)

Verovio is a fast, portable and lightweight library for engraving Music Encoding Initiative (MEI) digital scores into SVG images. Verovio also contain

RISM Digital Center 426 Sep 22, 2021

ieaseMusic Elegant NeteaseMusic desktop app, Rock with NeteaseMusic ?? Built by Electron, React, MobX, JSS API 由 Binaryify/NeteaseCloudMusicApi 提供。 Pr

null 8.6k Sep 22, 2021
MuseScore is an open source and free music notation software. For support, contribution, bug reports, visit MuseScore.org. Fork and make pull requests!

Music notation and composition software MuseScore is an open source and free music notation software. For support, contribution, and bug reports visit

MuseScore 6.3k Sep 24, 2021
C++ library and Python bindings for the Music Encoding Initiative format

LibMEI LibMEI is a C++ library for reading and writing MEI files It is developed by the Distributed Digital Music Archives and Libraries Lab at the Sc

Distributed Digital Music Archives and Libraries Lab 49 Aug 30, 2021
A music programming language for musicians. :notes:

Installation | Docs | Changelog | Contributing composers chatting Alda is a text-based programming language for music composition. It allows you to co

Alda 4.7k Sep 25, 2021
Music player for deepin desktop environment.

deepin-music Deepin music is a local music player with beautiful design and simple functions developed by Deepin Technology. Dependencies Build depend

Wuhan Deepin Technology Co.,Ltd. 155 Sep 16, 2021
music library manager and MusicBrainz tagger

beets Beets is the media library management system for obsessive music geeks. The purpose of beets is to get your music collection right once and for

beetbox 10.4k Sep 15, 2021
Mopidy is an extensible music server written in Python

Mopidy Mopidy is an extensible music server written in Python. Mopidy plays music from local disk, Spotify, SoundCloud, Google Play Music, and more. Y

Mopidy 7.2k Sep 17, 2021
Frescobaldi LilyPond Editor

README for Frescobaldi Homepage: http://www.frescobaldi.org/ Main author: Wilbert Berendsen Frescobaldi is a LilyPond sheet music text editor. It aims

Frescobaldi 501 Sep 21, 2021
Lilypond music preprocessor

Ripple - DRY for Lilypond Ripple is a small program that helps you generate scores and parts without repeating yourself, performing complex includes o

Sharon Rosner 21 Mar 24, 2020
web based music sheet viewer (go, pdfjs) as a single binary

Digital Music Stand A simple cross-platform browser-based pdfjs-based viewer to display and search music sheets. A single binary including all assets.

Patrick Wieschollek 21 Aug 27, 2021
Compose music and write score easily in your browser!

inknote Compose music easily in your browser! http://www.michalpaszkiewicz.co.uk/inknote/ Store multiple files, tag them with colours. Made using Type

Michal Paszkiewicz 145 Aug 18, 2021
Streaming music player that finds free music for you

Desktop music player focused on streaming from free sources Links Official website Mastodon Twitter Support channel (Matrix): #nuclear:matrix.org Disc

null 6.8k Sep 17, 2021
The git repository of the advanced drum machine

Hydrogen drum machine Hydrogen is an advanced drum machine for GNU/Linux, Mac and Windows. It's main goal is to bring professional yet simple and intu

Hydrogen 702 Sep 15, 2021